Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1336)

Delta Between Two Patch Sets: environs/tools.go

Issue 6145043: cmd/juju: add --upload-tools flag to bootstrap command
Left Patch Set: Created 12 years, 11 months ago
Right Patch Set: cmd/juju: add --upload-tools flag to bootstrap command Created 12 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « environs/open_test.go ('k') | environs/tools_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 package environs 1 package environs
2 2
3 import ( 3 import (
4 "archive/tar" 4 "archive/tar"
5 "compress/gzip" 5 "compress/gzip"
6 "fmt" 6 "fmt"
7 "io" 7 "io"
8 "io/ioutil" 8 "io/ioutil"
9 "launchpad.net/juju/go/version" 9 "launchpad.net/juju/go/version"
10 "os" 10 "os"
11 "os/exec" 11 "os/exec"
12 "path/filepath" 12 "path/filepath"
13 "runtime" 13 "runtime"
14 "strings"
14 ) 15 )
16
17 // toolsPath is the storage path for the juju tools with the
18 // same version, OS, and arch as the currently running client.
19 var toolsPath = fmt.Sprintf("tools/juju-%v-%s-%s.tgz", version.Current, runtime. GOOS, runtime.GOARCH)
15 20
16 // tarHeader returns a tar file header given the file's stat 21 // tarHeader returns a tar file header given the file's stat
17 // information. 22 // information.
18 func tarHeader(i os.FileInfo) *tar.Header { 23 func tarHeader(i os.FileInfo) *tar.Header {
19 return &tar.Header{ 24 return &tar.Header{
20 Typeflag: tar.TypeReg, 25 Typeflag: tar.TypeReg,
21 Name: i.Name(), 26 Name: i.Name(),
22 Size: i.Size(), 27 Size: i.Size(),
23 Mode: int64(i.Mode() & 0777), 28 Mode: int64(i.Mode() & 0777),
24 ModTime: i.ModTime(), 29 ModTime: i.ModTime(),
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 "GOBIN=" + dir, 107 "GOBIN=" + dir,
103 "PATH=" + os.Getenv("PATH"), 108 "PATH=" + os.Getenv("PATH"),
104 } 109 }
105 out, err := cmd.CombinedOutput() 110 out, err := cmd.CombinedOutput()
106 if err != nil { 111 if err != nil {
107 return fmt.Errorf("build failed: %v; %s", err, out) 112 return fmt.Errorf("build failed: %v; %s", err, out)
108 } 113 }
109 return archive(w, dir) 114 return archive(w, dir)
110 } 115 }
111 116
112 // UploadTools uploads the current version of the juju tools 117 // PutTools uploads the current version of the juju tools
113 // executables to the given environment. 118 // executables to the given storage.
114 // TODO find binaries from $PATH when go dev environment not available. 119 // TODO find binaries from $PATH when go dev environment not available.
115 func UploadTools(env Environ) error { 120 func PutTools(storage StorageWriter) error {
116 // We create the entire archive before asking the environment to 121 // We create the entire archive before asking the environment to
117 // start uploading so that we can be sure we have archived 122 // start uploading so that we can be sure we have archived
118 // correctly. 123 // correctly.
119 f, err := ioutil.TempFile("", "juju-tgz") 124 f, err := ioutil.TempFile("", "juju-tgz")
120 if err != nil { 125 if err != nil {
121 return err 126 return err
122 } 127 }
123 defer f.Close() 128 defer f.Close()
124 defer os.Remove(f.Name()) 129 defer os.Remove(f.Name())
125 err = bundleTools(f) 130 err = bundleTools(f)
126 if err != nil { 131 if err != nil {
127 return err 132 return err
128 } 133 }
129 _, err = f.Seek(0, 0) 134 _, err = f.Seek(0, 0)
130 if err != nil { 135 if err != nil {
131 return err 136 return err
132 } 137 }
133 fi, err := f.Stat() 138 fi, err := f.Stat()
134 if err != nil { 139 if err != nil {
135 return err 140 return err
136 } 141 }
137 » name := fmt.Sprintf("tools/juju-%v-%s-%s.tgz", version.Current, runtime. GOOS, runtime.GOARCH) 142 » return storage.Put(toolsPath, f, fi.Size())
138 » return env.PutFile(name, f, fi.Size()) 143 }
139 } 144
145 // GetTools finds the latest compatible version of the juju tools
146 // and downloads and extracts them into the given directory.
147 func GetTools(storage StorageReader, dir string) error {
148 » // TODO search the storage for the right tools version.
149 » r, err := storage.Get(toolsPath)
150 » if err != nil {
151 » » return err
152 » }
153 » defer r.Close()
154
155 » r, err = gzip.NewReader(r)
156 » if err != nil {
157 » » return err
158 » }
159 » defer r.Close()
160
161 » tr := tar.NewReader(r)
162 » for {
163 » » hdr, err := tr.Next()
164 » » if err != nil {
165 » » » if err == io.EOF {
166 » » » » err = nil
167 » » » }
168 » » » return err
169 » » }
170 » » if strings.Contains(hdr.Name, "/\\") {
171 » » » return fmt.Errorf("bad name %q in tools archive", hdr.Na me)
172 » » }
173
174 » » name := filepath.Join(dir, hdr.Name)
175 » » if err := writeFile(name, os.FileMode(hdr.Mode&0777), tr); err ! = nil {
176 » » » return fmt.Errorf("tar extract %q failed: %v", name, err )
177 » » }
178 » }
179 » panic("not reached")
180 }
181
182 func writeFile(name string, mode os.FileMode, r io.Reader) error {
183 » f, err := os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode)
184 » if err != nil {
185 » » return err
186 » }
187 » defer f.Close()
188 » _, err = io.Copy(f, r)
189 » return err
190 }
191
192 // EmptyStorage holds a StorageReader object
193 // that contains nothing.
194 var EmptyStorage StorageReader = emptyStorage{}
195
196 type emptyStorage struct{}
197
198 func (s emptyStorage) Get(name string) (io.ReadCloser, error) {
199 » return nil, &NotFoundError{fmt.Errorf("file %q not found in empty storag e", name)}
200 }
201
202 func (s emptyStorage) List(prefix string) ([]string, error) {
203 » return nil, nil
204 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b