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  }