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 }