github.com/coreos/mantle@v0.13.0/platform/api/azure/image.go (about)

     1  // Copyright 2016 CoreOS, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package azure
    16  
    17  import (
    18  	"bufio"
    19  	"encoding/xml"
    20  	"fmt"
    21  	"net/http"
    22  	"strings"
    23  
    24  	"github.com/Azure/azure-sdk-for-go/arm/compute"
    25  	"github.com/Azure/azure-sdk-for-go/management"
    26  )
    27  
    28  // OSImage struct for https://msdn.microsoft.com/en-us/library/azure/jj157192.aspx call.
    29  //
    30  // XXX: the field ordering is important!
    31  type OSImage struct {
    32  	XMLName           xml.Name `xml:"http://schemas.microsoft.com/windowsazure OSImage"`
    33  	Category          string   `xml:",omitempty"` // Public || Private || MSDN
    34  	Label             string   `xml:",omitempty"` // Specifies an identifier for the image.
    35  	MediaLink         string   `xml:",omitempty"` // Specifies the location of the vhd file for the image. The storage account where the vhd is located must be associated with the specified subscription.
    36  	Name              string   // Specifies the name of the operating system image. This is the name that is used when creating one or more virtual machines using the image.
    37  	OS                string   // Linux || Windows
    38  	Eula              string   `xml:",omitempty"` // Specifies the End User License Agreement that is associated with the image. The value for this element is a string, but it is recommended that the value be a URL that points to a EULA.
    39  	Description       string   `xml:",omitempty"` // Specifies the description of the image.
    40  	ImageFamily       string   `xml:",omitempty"` // Specifies a value that can be used to group images.
    41  	PublishedDate     string   `xml:",omitempty"` // Specifies the date when the image was added to the image repository.
    42  	ShowInGui         bool     // Specifies whether the image should appear in the image gallery.
    43  	PrivacyURI        string   `xml:"PrivacyUri,omitempty"`   // Specifies the URI that points to a document that contains the privacy policy related to the image.
    44  	IconURI           string   `xml:"IconUri,omitempty"`      // Specifies the Uri to the icon that is displayed for the image in the Management Portal.
    45  	RecommendedVMSize string   `xml:",omitempty"`             // Specifies the size to use for the virtual machine that is created from the image.
    46  	SmallIconURI      string   `xml:"SmallIconUri,omitempty"` // Specifies the URI to the small icon that is displayed when the image is presented in the Microsoft Azure Management Portal.
    47  	Language          string   `xml:",omitempty"`             // Specifies the language of the image.
    48  
    49  	LogicalSizeInGB   float64 `xml:",omitempty"` //Specifies the size, in GB, of the image.
    50  	Location          string  `xml:",omitempty"` // The geo-location in which this media is located. The Location value is derived from storage account that contains the blob in which the media is located. If the storage account belongs to an affinity group the value is NULL.
    51  	AffinityGroup     string  `xml:",omitempty"` // Specifies the affinity in which the media is located. The AffinityGroup value is derived from storage account that contains the blob in which the media is located. If the storage account does not belong to an affinity group the value is NULL and the element is not displayed in the response. This value is NULL for platform images.
    52  	IsPremium         string  `xml:",omitempty"` // Indicates whether the image contains software or associated services that will incur charges above the core price for the virtual machine. For additional details, see the PricingDetailLink element.
    53  	PublisherName     string  `xml:",omitempty"` // The name of the publisher of the image. All user images have a publisher name of User.
    54  	PricingDetailLink string  `xml:",omitempty"` // Specifies a URL for an image with IsPremium set to true, which contains the pricing details for a virtual machine that is created from the image.
    55  }
    56  
    57  var azureImageShareURL = "services/images/%s/share?permission=%s"
    58  
    59  func (a *API) ShareImage(image, permission string) error {
    60  	url := fmt.Sprintf(azureImageShareURL, image, permission)
    61  	op, err := a.client.SendAzurePutRequest(url, "", nil)
    62  	if err != nil {
    63  		return err
    64  	}
    65  
    66  	return a.client.WaitForOperation(op, nil)
    67  }
    68  
    69  func IsConflictError(err error) bool {
    70  	azerr, ok := err.(management.AzureError)
    71  	return ok && azerr.Code == "ConflictError"
    72  }
    73  
    74  func (a *API) CreateImage(name, resourceGroup, blobURI string) (compute.Image, error) {
    75  	_, err := a.imgClient.CreateOrUpdate(resourceGroup, name, compute.Image{
    76  		Name:     &name,
    77  		Location: &a.opts.Location,
    78  		ImageProperties: &compute.ImageProperties{
    79  			StorageProfile: &compute.ImageStorageProfile{
    80  				OsDisk: &compute.ImageOSDisk{
    81  					OsType:  compute.Linux,
    82  					OsState: compute.Generalized,
    83  					BlobURI: &blobURI,
    84  				},
    85  			},
    86  		},
    87  	}, nil)
    88  	if err != nil {
    89  		return compute.Image{}, err
    90  	}
    91  
    92  	return a.imgClient.Get(resourceGroup, name, "")
    93  }
    94  
    95  // resolveImage is used to ensure that either a Version or DiskURI
    96  // are provided present for a run. If neither is given via arguments
    97  // it attempts to parse the Version from the version.txt in the Sku's
    98  // release bucket.
    99  func (a *API) resolveImage() error {
   100  	// immediately return if the version has been set or if the channel
   101  	// is not set via the Sku (this happens in ore)
   102  	if a.opts.DiskURI != "" || a.opts.Version != "" || a.opts.Sku == "" {
   103  		return nil
   104  	}
   105  
   106  	resp, err := http.DefaultClient.Get(fmt.Sprintf("https://%s.release.core-os.net/amd64-usr/current/version.txt", a.opts.Sku))
   107  	if err != nil {
   108  		return fmt.Errorf("unable to fetch release bucket %v version: %v", a.opts.Sku, err)
   109  	}
   110  
   111  	scanner := bufio.NewScanner(resp.Body)
   112  	for scanner.Scan() {
   113  		line := strings.SplitN(scanner.Text(), "=", 2)
   114  		if len(line) != 2 {
   115  			continue
   116  		}
   117  		if line[0] == "COREOS_VERSION" {
   118  			a.opts.Version = line[1]
   119  			return nil
   120  		}
   121  	}
   122  
   123  	return fmt.Errorf("couldn't find COREOS_VERSION in version.txt")
   124  }