github.com/coreos/mantle@v0.13.0/cmd/ore/gcloud/create-image.go (about)

     1  // Copyright 2015 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 gcloud
    16  
    17  import (
    18  	"fmt"
    19  	"net/url"
    20  	"os"
    21  	"path"
    22  	"strings"
    23  
    24  	"github.com/spf13/cobra"
    25  	"google.golang.org/api/storage/v1"
    26  
    27  	"github.com/coreos/mantle/platform/api/gcloud"
    28  )
    29  
    30  var (
    31  	cmdCreateImage = &cobra.Command{
    32  		Use:   "create-image",
    33  		Short: "Create GCE image",
    34  		Long:  "Create GCE image from an existing file in Google Storage",
    35  		Run:   runCreateImage,
    36  	}
    37  
    38  	createImageFamily  string
    39  	createImageBoard   string
    40  	createImageVersion string
    41  	createImageRoot    string
    42  	createImageName    string
    43  	createImageForce   bool
    44  )
    45  
    46  func init() {
    47  	user := os.Getenv("USER")
    48  	cmdCreateImage.Flags().StringVar(&createImageFamily, "family",
    49  		user, "GCE image group and name prefix")
    50  	cmdCreateImage.Flags().StringVar(&createImageBoard, "board",
    51  		"amd64-usr", "OS board name")
    52  	cmdCreateImage.Flags().StringVar(&createImageVersion, "version",
    53  		"", "OS build version")
    54  	cmdCreateImage.Flags().StringVar(&createImageRoot, "source-root",
    55  		"gs://users.developer.core-os.net/"+user+"/boards",
    56  		"Storage URL prefix")
    57  	cmdCreateImage.Flags().StringVar(&createImageName, "source-name",
    58  		"coreos_production_gce.tar.gz",
    59  		"Storage image name")
    60  	cmdCreateImage.Flags().BoolVar(&createImageForce, "force",
    61  		false, "overwrite existing GCE images without prompt")
    62  	GCloud.AddCommand(cmdCreateImage)
    63  }
    64  
    65  func runCreateImage(cmd *cobra.Command, args []string) {
    66  	if len(args) != 0 {
    67  		fmt.Fprintf(os.Stderr, "Unrecognized args: %v\n", args)
    68  		os.Exit(2)
    69  	}
    70  
    71  	if createImageVersion == "" {
    72  		fmt.Fprintln(os.Stderr, "--version is required")
    73  		os.Exit(2)
    74  	}
    75  
    76  	gsURL, err := url.Parse(createImageRoot)
    77  	if err != nil {
    78  		fmt.Fprintf(os.Stderr, "%v\n", err)
    79  		os.Exit(1)
    80  	}
    81  	if gsURL.Scheme != "gs" {
    82  		fmt.Fprintf(os.Stderr, "URL missing gs:// scheme: %v\n", createImageRoot)
    83  		os.Exit(1)
    84  	}
    85  	if gsURL.Host == "" {
    86  		fmt.Fprintf(os.Stderr, "URL missing bucket name %v\n", createImageRoot)
    87  		os.Exit(1)
    88  	}
    89  
    90  	bucket := gsURL.Host
    91  	imageNameGS := strings.TrimPrefix(path.Join(gsURL.Path,
    92  		createImageBoard, createImageVersion, createImageName), "/")
    93  	imageNameGCE := gceSanitize(createImageFamily + "-" + createImageVersion)
    94  
    95  	storageAPI, err := storage.New(api.Client())
    96  	if err != nil {
    97  		fmt.Fprintf(os.Stderr, "Storage client failed: %v\n", err)
    98  		os.Exit(1)
    99  	}
   100  
   101  	// check if this file actually exists
   102  	if ok, err := fileQuery(storageAPI, bucket, imageNameGS); err != nil {
   103  		fmt.Fprintf(os.Stderr,
   104  			"Checking source image %s failed: %v\n", gsURL, err)
   105  		os.Exit(1)
   106  	} else if !ok {
   107  		fmt.Fprintf(os.Stderr,
   108  			"Source image %s does not exist\n", gsURL)
   109  		os.Exit(1)
   110  	}
   111  
   112  	fmt.Printf("Creating image in GCE: %v...\n", imageNameGCE)
   113  
   114  	// create image on gce
   115  	storageSrc := fmt.Sprintf("https://storage.googleapis.com/%v/%v", bucket, imageNameGS)
   116  	_, pending, err := api.CreateImage(&gcloud.ImageSpec{
   117  		Name:        imageNameGCE,
   118  		SourceImage: storageSrc,
   119  	}, createImageForce)
   120  	if err == nil {
   121  		err = pending.Wait()
   122  	}
   123  	if err != nil {
   124  		fmt.Fprintf(os.Stderr, "Creating GCE image failed: %v\n", err)
   125  		os.Exit(1)
   126  	}
   127  }