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

Delta Between Two Patch Sets: environs/tools.go

Issue 6501106: environs: remove VarDir global
Left Patch Set: environs: remove VarDir global Created 12 years, 7 months ago
Right Patch Set: environs: remove VarDir global Created 12 years, 7 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:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « environs/ec2/ec2.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
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-core/log" 9 "launchpad.net/juju-core/log"
10 "launchpad.net/juju-core/state" 10 "launchpad.net/juju-core/state"
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 if bestTools == nil || bestTools.Number.Less(t.Number) { 228 if bestTools == nil || bestTools.Number.Less(t.Number) {
229 bestTools = t 229 bestTools = t
230 } 230 }
231 } 231 }
232 return bestTools 232 return bestTools
233 } 233 }
234 234
235 const urlFile = "downloaded-url.txt" 235 const urlFile = "downloaded-url.txt"
236 236
237 // toolsParentDir returns the tools parent directory. 237 // toolsParentDir returns the tools parent directory.
238 func toolsParentDir(varDir string) string { 238 func toolsParentDir(dataDir string) string {
239 » return path.Join(varDir, "tools") 239 » return path.Join(dataDir, "tools")
240 } 240 }
241 241
242 // UnpackTools reads a set of juju tools in gzipped tar-archive 242 // UnpackTools reads a set of juju tools in gzipped tar-archive
243 // format and unpacks them into the appropriate tools directory 243 // format and unpacks them into the appropriate tools directory
244 // within varDir. If a valid tools directory already exists, 244 // within dataDir. If a valid tools directory already exists,
245 // UnpackTools returns without error. 245 // UnpackTools returns without error.
246 func UnpackTools(varDir string, tools *state.Tools, r io.Reader) (err error) { 246 func UnpackTools(dataDir string, tools *state.Tools, r io.Reader) (err error) {
247 zr, err := gzip.NewReader(r) 247 zr, err := gzip.NewReader(r)
248 if err != nil { 248 if err != nil {
249 return err 249 return err
250 } 250 }
251 defer zr.Close() 251 defer zr.Close()
252 252
253 // Make a temporary directory in the tools directory, 253 // Make a temporary directory in the tools directory,
254 // first ensuring that the tools directory exists. 254 // first ensuring that the tools directory exists.
255 » err = os.MkdirAll(toolsParentDir(varDir), 0755) 255 » err = os.MkdirAll(toolsParentDir(dataDir), 0755)
256 » if err != nil { 256 » if err != nil {
257 » » return err 257 » » return err
258 » } 258 » }
259 » dir, err := ioutil.TempDir(toolsParentDir(varDir), "unpacking-") 259 » dir, err := ioutil.TempDir(toolsParentDir(dataDir), "unpacking-")
260 if err != nil { 260 if err != nil {
261 return err 261 return err
262 } 262 }
263 defer removeAll(dir) 263 defer removeAll(dir)
264 264
265 tr := tar.NewReader(zr) 265 tr := tar.NewReader(zr)
266 for { 266 for {
267 hdr, err := tr.Next() 267 hdr, err := tr.Next()
268 if err == io.EOF { 268 if err == io.EOF {
269 break 269 break
(...skipping 10 matching lines...) Expand all
280 name := filepath.Join(dir, hdr.Name) 280 name := filepath.Join(dir, hdr.Name)
281 if err := writeFile(name, os.FileMode(hdr.Mode&0777), tr); err ! = nil { 281 if err := writeFile(name, os.FileMode(hdr.Mode&0777), tr); err ! = nil {
282 return fmt.Errorf("tar extract %q failed: %v", name, err ) 282 return fmt.Errorf("tar extract %q failed: %v", name, err )
283 } 283 }
284 } 284 }
285 err = ioutil.WriteFile(filepath.Join(dir, urlFile), []byte(tools.URL), 0 644) 285 err = ioutil.WriteFile(filepath.Join(dir, urlFile), []byte(tools.URL), 0 644)
286 if err != nil { 286 if err != nil {
287 return err 287 return err
288 } 288 }
289 289
290 » err = os.Rename(dir, ToolsDir(varDir, tools.Binary)) 290 » err = os.Rename(dir, ToolsDir(dataDir, tools.Binary))
291 // If we've failed to rename the directory, it may be because 291 // If we've failed to rename the directory, it may be because
292 // the directory already exists - if ReadTools succeeds, we 292 // the directory already exists - if ReadTools succeeds, we
293 // assume all's ok. 293 // assume all's ok.
294 if err != nil { 294 if err != nil {
295 » » _, err := ReadTools(varDir, tools.Binary) 295 » » _, err := ReadTools(dataDir, tools.Binary)
296 if err == nil { 296 if err == nil {
297 return nil 297 return nil
298 } 298 }
299 } 299 }
300 return nil 300 return nil
301 } 301 }
302 302
303 func removeAll(dir string) { 303 func removeAll(dir string) {
304 err := os.RemoveAll(dir) 304 err := os.RemoveAll(dir)
305 if err == nil || os.IsNotExist(err) { 305 if err == nil || os.IsNotExist(err) {
306 return 306 return
307 } 307 }
308 log.Printf("environs: cannot remove %q: %v", dir, err) 308 log.Printf("environs: cannot remove %q: %v", dir, err)
309 } 309 }
310 310
311 func writeFile(name string, mode os.FileMode, r io.Reader) error { 311 func writeFile(name string, mode os.FileMode, r io.Reader) error {
312 f, err := os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode) 312 f, err := os.OpenFile(name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, mode)
313 if err != nil { 313 if err != nil {
314 return err 314 return err
315 } 315 }
316 defer f.Close() 316 defer f.Close()
317 _, err = io.Copy(f, r) 317 _, err = io.Copy(f, r)
318 return err 318 return err
319 } 319 }
320 320
321 // ReadTools checks that the tools for the given version exist 321 // ReadTools checks that the tools for the given version exist
322 // in the varDir directory, and returns a Tools instance describing them. 322 // in the dataDir directory, and returns a Tools instance describing them.
323 func ReadTools(varDir string, vers version.Binary) (*state.Tools, error) { 323 func ReadTools(dataDir string, vers version.Binary) (*state.Tools, error) {
324 » dir := ToolsDir(varDir, vers) 324 » dir := ToolsDir(dataDir, vers)
325 urlData, err := ioutil.ReadFile(filepath.Join(dir, urlFile)) 325 urlData, err := ioutil.ReadFile(filepath.Join(dir, urlFile))
326 if err != nil { 326 if err != nil {
327 return nil, fmt.Errorf("cannot read URL in tools directory: %v", err) 327 return nil, fmt.Errorf("cannot read URL in tools directory: %v", err)
328 } 328 }
329 url := strings.TrimSpace(string(urlData)) 329 url := strings.TrimSpace(string(urlData))
330 if len(url) == 0 { 330 if len(url) == 0 {
331 return nil, fmt.Errorf("empty URL in tools directory %q", dir) 331 return nil, fmt.Errorf("empty URL in tools directory %q", dir)
332 } 332 }
333 // TODO(rog): do more verification here too, such as checking 333 // TODO(rog): do more verification here too, such as checking
334 // for the existence of certain files. 334 // for the existence of certain files.
335 return &state.Tools{ 335 return &state.Tools{
336 URL: url, 336 URL: url,
337 Binary: vers, 337 Binary: vers,
338 }, nil 338 }, nil
339 } 339 }
340 340
341 // ChangeAgentTools atomically replaces the agent-specific symlink 341 // ChangeAgentTools atomically replaces the agent-specific symlink
342 // under varDir so it points to the previously unpacked 342 // under dataDir so it points to the previously unpacked
343 // version vers. It returns the new tools read. 343 // version vers. It returns the new tools read.
344 func ChangeAgentTools(varDir string, agentName string, vers version.Binary) (*st ate.Tools, error) { 344 func ChangeAgentTools(dataDir string, agentName string, vers version.Binary) (*s tate.Tools, error) {
345 » tools, err := ReadTools(varDir, vers) 345 » tools, err := ReadTools(dataDir, vers)
346 » if err != nil { 346 » if err != nil {
347 » » return nil, err 347 » » return nil, err
348 » } 348 » }
349 » tmpName := AgentToolsDir(varDir, "tmplink-"+agentName) 349 » tmpName := AgentToolsDir(dataDir, "tmplink-"+agentName)
350 err = os.Symlink(tools.Binary.String(), tmpName) 350 err = os.Symlink(tools.Binary.String(), tmpName)
351 if err != nil { 351 if err != nil {
352 return nil, fmt.Errorf("cannot create tools symlink: %v", err) 352 return nil, fmt.Errorf("cannot create tools symlink: %v", err)
353 } 353 }
354 » err = os.Rename(tmpName, AgentToolsDir(varDir, agentName)) 354 » err = os.Rename(tmpName, AgentToolsDir(dataDir, agentName))
355 if err != nil { 355 if err != nil {
356 return nil, fmt.Errorf("cannot update tools symlink: %v", err) 356 return nil, fmt.Errorf("cannot update tools symlink: %v", err)
357 } 357 }
358 return tools, nil 358 return tools, nil
359 } 359 }
360 360
361 // ToolsStoragePath returns the slash-separated path that is used to store and 361 // ToolsStoragePath returns the slash-separated path that is used to store and
362 // retrieve the given version of the juju tools in a Storage. 362 // retrieve the given version of the juju tools in a Storage.
363 func ToolsStoragePath(vers version.Binary) string { 363 func ToolsStoragePath(vers version.Binary) string {
364 return toolPrefix + vers.String() + ".tgz" 364 return toolPrefix + vers.String() + ".tgz"
365 } 365 }
366 366
367 // ToolsDir returns the slash-separated directory name that is used to 367 // ToolsDir returns the slash-separated directory name that is used to
368 // store binaries for the given version of the juju tools 368 // store binaries for the given version of the juju tools
369 // within the varDir directory. 369 // within the dataDir directory.
370 func ToolsDir(varDir string, vers version.Binary) string { 370 func ToolsDir(dataDir string, vers version.Binary) string {
371 » return path.Join(varDir, "tools", vers.String()) 371 » return path.Join(dataDir, "tools", vers.String())
372 } 372 }
373 373
374 // AgentToolsDir returns the slash-separated directory name that is used 374 // AgentToolsDir returns the slash-separated directory name that is used
375 // to store binaries for the tools used by the given agent 375 // to store binaries for the tools used by the given agent
376 // within the given varDir directory. 376 // within the given dataDir directory.
377 // Conventionally it is a symbolic link to the actual tools directory. 377 // Conventionally it is a symbolic link to the actual tools directory.
378 func AgentToolsDir(varDir, agentName string) string { 378 func AgentToolsDir(dataDir, agentName string) string {
379 » return path.Join(varDir, "tools", agentName) 379 » return path.Join(dataDir, "tools", agentName)
380 } 380 }
381 381
382 // ToolsSearchFlags gives options when searching 382 // ToolsSearchFlags gives options when searching
383 // for tools. 383 // for tools.
384 type ToolsSearchFlags int 384 type ToolsSearchFlags int
385 385
386 const ( 386 const (
387 // HighestVersion indicates that versions above the version being 387 // HighestVersion indicates that versions above the version being
388 // searched for may be included in the search. The default behavior 388 // searched for may be included in the search. The default behavior
389 // is to search for versions <= the one provided. 389 // is to search for versions <= the one provided.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 return nil, &NotFoundError{fmt.Errorf("file %q not found in empty storag e", name)} 474 return nil, &NotFoundError{fmt.Errorf("file %q not found in empty storag e", name)}
475 } 475 }
476 476
477 func (s emptyStorage) URL(string) (string, error) { 477 func (s emptyStorage) URL(string) (string, error) {
478 return "", fmt.Errorf("empty storage has no URLs") 478 return "", fmt.Errorf("empty storage has no URLs")
479 } 479 }
480 480
481 func (s emptyStorage) List(prefix string) ([]string, error) { 481 func (s emptyStorage) List(prefix string) ([]string, error) {
482 return nil, nil 482 return nil, nil
483 } 483 }
LEFTRIGHT

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