github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/container/image.go (about) 1 // Copyright 2014 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package container 5 6 import ( 7 "fmt" 8 "os/exec" 9 "path" 10 "strings" 11 12 "github.com/juju/errors" 13 14 "github.com/juju/juju/instance" 15 ) 16 17 // ImageURLGetter implementations provide a getter which returns a URL which 18 // can be used to fetch an image blob. 19 type ImageURLGetter interface { 20 // ImageURL returns a URL which can be used to fetch an image of the 21 // specified kind, series, and arch. 22 ImageURL(kind instance.ContainerType, series, arch string) (string, error) 23 24 // CACert returns the ca certificate used to validate the state server 25 // certificate when using wget. 26 CACert() []byte 27 } 28 29 type imageURLGetter struct { 30 serverRoot string 31 envuuid string 32 caCert []byte 33 } 34 35 // NewImageURLGetter returns an ImageURLGetter for the specified state 36 // server address and environment UUID. 37 func NewImageURLGetter(serverRoot, envuuid string, caCert []byte) ImageURLGetter { 38 return &imageURLGetter{ 39 serverRoot, 40 envuuid, 41 caCert, 42 } 43 } 44 45 // ImageURL is specified on the NewImageURLGetter interface. 46 func (ug *imageURLGetter) ImageURL(kind instance.ContainerType, series, arch string) (string, error) { 47 imageURL, err := ImageDownloadURL(kind, series, arch) 48 if err != nil { 49 return "", errors.Annotatef(err, "cannot determine LXC image URL: %v", err) 50 } 51 imageFilename := path.Base(imageURL) 52 53 imageUrl := fmt.Sprintf( 54 "https://%s/environment/%s/images/%v/%s/%s/%s", ug.serverRoot, ug.envuuid, kind, series, arch, imageFilename, 55 ) 56 return imageUrl, nil 57 } 58 59 // CACert is specified on the NewImageURLGetter interface. 60 func (ug *imageURLGetter) CACert() []byte { 61 return ug.caCert 62 } 63 64 // ImageDownloadURL determines the public URL which can be used to obtain an 65 // image blob with the specified parameters. 66 func ImageDownloadURL(kind instance.ContainerType, series, arch string) (string, error) { 67 // TODO - we currently only need to support LXC images - kind is ignored. 68 if kind != instance.LXC { 69 return "", errors.Errorf("unsupported container type: %v", kind) 70 } 71 72 // Use the ubuntu-cloudimg-query command to get the url from which to fetch the image. 73 // This will be somewhere on http://cloud-images.ubuntu.com. 74 cmd := exec.Command("ubuntu-cloudimg-query", series, "released", arch, "--format", "%{url}") 75 urlBytes, err := cmd.CombinedOutput() 76 if err != nil { 77 stderr := string(urlBytes) 78 return "", errors.Annotatef(err, "cannot determine LXC image URL: %v", stderr) 79 } 80 imageURL := strings.Replace(string(urlBytes), ".tar.gz", "-root.tar.gz", -1) 81 return imageURL, nil 82 }