mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-23 11:00:25 +00:00
Split build and push, and remove push code from run
This currently only changes the `gcp` target, but is the new model - the `build` command will only do things locally, then you need to `push` to an image store such as GCP or other ones in order to `run` for platforms that cannot boot directly from a local image. Fix #1618 Signed-off-by: Justin Cormack <justin.cormack@docker.com>
This commit is contained in:
parent
b556f51b47
commit
4e1317d213
@ -35,13 +35,7 @@ type Moby struct {
|
||||
Contents string
|
||||
}
|
||||
Outputs []struct {
|
||||
Format string
|
||||
Project string
|
||||
Bucket string
|
||||
Family string
|
||||
Keys string
|
||||
Public bool
|
||||
Replace bool
|
||||
Format string
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,8 @@ func main() {
|
||||
fmt.Printf("USAGE: %s [options] COMMAND\n\n", filepath.Base(os.Args[0]))
|
||||
fmt.Printf("Commands:\n")
|
||||
fmt.Printf(" build Build a Moby image from a YAML file\n")
|
||||
fmt.Printf(" run Run a Moby image on a local hypervisor or remote cloud\n")
|
||||
fmt.Printf(" push Push a VM image to a cloud or image store\n")
|
||||
fmt.Printf(" run Run a VM image on a local hypervisor or remote cloud\n")
|
||||
fmt.Printf(" version Print version information\n")
|
||||
fmt.Printf(" help Print this message\n")
|
||||
fmt.Printf("\n")
|
||||
@ -81,6 +82,8 @@ func main() {
|
||||
switch args[0] {
|
||||
case "build":
|
||||
build(args[1:])
|
||||
case "push":
|
||||
push(args[1:])
|
||||
case "run":
|
||||
run(args[1:])
|
||||
case "version":
|
||||
|
@ -43,42 +43,6 @@ func outputs(m *Moby, base string, bzimage []byte, initrd []byte) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error writing %s output: %v", o.Format, err)
|
||||
}
|
||||
case "gcp-storage":
|
||||
err := outputImg(gcp, base+".img.tar.gz", bzimage, initrd, m.Kernel.Cmdline)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error writing %s output: %v", o.Format, err)
|
||||
}
|
||||
if o.Bucket == "" {
|
||||
return fmt.Errorf("No bucket specified for GCP output")
|
||||
}
|
||||
gClient, err := NewGCPClient(o.Keys, o.Project)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to connect to GCP")
|
||||
}
|
||||
err = gClient.UploadFile(base+".img.tar.gz", base+".img.tar.gz", o.Bucket, o.Public)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error copying to Google Storage: %v", err)
|
||||
}
|
||||
case "gcp":
|
||||
err := outputImg(gcp, base+".img.tar.gz", bzimage, initrd, m.Kernel.Cmdline)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error writing %s output: %v", o.Format, err)
|
||||
}
|
||||
if o.Bucket == "" {
|
||||
return fmt.Errorf("No bucket specified for GCP output")
|
||||
}
|
||||
gClient, err := NewGCPClient(o.Keys, o.Project)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to connect to GCP")
|
||||
}
|
||||
err = gClient.UploadFile(base+".img.tar.gz", base+".img.tar.gz", o.Bucket, o.Public)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error copying to Google Storage: %v", err)
|
||||
}
|
||||
err = gClient.CreateImage(base, "https://storage.googleapis.com/"+o.Bucket+"/"+base+".img.tar.gz", o.Family, o.Replace)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating Google Compute Image: %v", err)
|
||||
}
|
||||
case "qcow", "qcow2":
|
||||
err := outputImg(qcow, base+".qcow2", bzimage, initrd, m.Kernel.Cmdline)
|
||||
if err != nil {
|
||||
|
37
src/cmd/moby/push.go
Normal file
37
src/cmd/moby/push.go
Normal file
@ -0,0 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
func pushUsage() {
|
||||
fmt.Printf("USAGE: %s push [backend] [options] [prefix]\n\n", os.Args[0])
|
||||
|
||||
fmt.Printf("'backend' specifies the push backend.\n")
|
||||
fmt.Printf("Supported backends are\n")
|
||||
fmt.Printf(" gcp\n")
|
||||
fmt.Printf("\n")
|
||||
fmt.Printf("'options' are the backend specific options.\n")
|
||||
fmt.Printf("See 'moby push [backend] --help' for details.\n\n")
|
||||
fmt.Printf("'prefix' specifies the path to the VM image.\n")
|
||||
}
|
||||
|
||||
func push(args []string) {
|
||||
if len(args) < 1 {
|
||||
runUsage()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
switch args[0] {
|
||||
case "help", "-h", "-help", "--help":
|
||||
pushUsage()
|
||||
os.Exit(0)
|
||||
case "gcp":
|
||||
pushGcp(args[1:])
|
||||
default:
|
||||
log.Errorf("No 'push' backend specified.")
|
||||
}
|
||||
}
|
73
src/cmd/moby/push_gcp.go
Normal file
73
src/cmd/moby/push_gcp.go
Normal file
@ -0,0 +1,73 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Process the run arguments and execute run
|
||||
func pushGcp(args []string) {
|
||||
gcpCmd := flag.NewFlagSet("gcp", flag.ExitOnError)
|
||||
gcpCmd.Usage = func() {
|
||||
fmt.Printf("USAGE: %s push gcp [options] [name]\n\n", os.Args[0])
|
||||
fmt.Printf("'name' specifies the full path of an image file which will be uploaded\n")
|
||||
fmt.Printf("Options:\n\n")
|
||||
gcpCmd.PrintDefaults()
|
||||
}
|
||||
keysFlag := gcpCmd.String("keys", "", "Path to Service Account JSON key file")
|
||||
projectFlag := gcpCmd.String("project", "", "GCP Project Name")
|
||||
bucketFlag := gcpCmd.String("bucket", "", "GS Bucket to upload to. *Required*")
|
||||
publicFlag := gcpCmd.Bool("public", false, "Select if file on GS should be public. *Optional*")
|
||||
familyFlag := gcpCmd.String("family", "", "GCP Image Family. A group of images where the family name points to the most recent image. *Optional*")
|
||||
nameFlag := gcpCmd.String("img-name", "", "Overrides the Name used to identify the file in Google Storage and Image. Defaults to [name]")
|
||||
|
||||
if err := gcpCmd.Parse(args); err != nil {
|
||||
log.Fatal("Unable to parse args")
|
||||
}
|
||||
|
||||
remArgs := gcpCmd.Args()
|
||||
if len(remArgs) == 0 {
|
||||
fmt.Printf("Please specify the prefix to the image to push\n")
|
||||
gcpCmd.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
prefix := remArgs[0]
|
||||
|
||||
keys := getStringValue(keysVar, *keysFlag, "")
|
||||
project := getStringValue(projectVar, *projectFlag, "")
|
||||
bucket := getStringValue(bucketVar, *bucketFlag, "")
|
||||
public := getBoolValue(publicVar, *publicFlag)
|
||||
family := getStringValue(familyVar, *familyFlag, "")
|
||||
name := getStringValue(nameVar, *nameFlag, "")
|
||||
|
||||
client, err := NewGCPClient(keys, project)
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to connect to GCP")
|
||||
}
|
||||
|
||||
suffix := ".img.tar.gz"
|
||||
src := prefix
|
||||
if strings.HasSuffix(prefix, suffix) {
|
||||
prefix = prefix[:len(prefix)-len(suffix)]
|
||||
} else {
|
||||
src = prefix + suffix
|
||||
}
|
||||
if name != "" {
|
||||
prefix = name
|
||||
}
|
||||
if bucket == "" {
|
||||
log.Fatalf("No bucket specified. Please provide one using the -bucket flag")
|
||||
}
|
||||
err = client.UploadFile(src, prefix+suffix, bucket, public)
|
||||
if err != nil {
|
||||
log.Fatalf("Error copying to Google Storage: %v", err)
|
||||
}
|
||||
err = client.CreateImage(prefix, "https://storage.googleapis.com/"+bucket+"/"+prefix+".img.tar.gz", family, true)
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating Google Compute Image: %v", err)
|
||||
}
|
||||
}
|
@ -4,7 +4,6 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
)
|
||||
@ -40,10 +39,6 @@ func runGcp(args []string) {
|
||||
machineFlag := gcpCmd.String("machine", defaultMachine, "GCP Machine Type")
|
||||
keysFlag := gcpCmd.String("keys", "", "Path to Service Account JSON key file")
|
||||
projectFlag := gcpCmd.String("project", "", "GCP Project Name")
|
||||
bucketFlag := gcpCmd.String("bucket", "", "GS Bucket to upload to. *Required* when 'prefix' is a filename")
|
||||
publicFlag := gcpCmd.Bool("public", false, "Select if file on GS should be public. *Optional* when 'prefix' is a filename")
|
||||
familyFlag := gcpCmd.String("family", "", "GCP Image Family. A group of images where the family name points to the most recent image. *Optional* when 'prefix' is a filename")
|
||||
nameFlag := gcpCmd.String("img-name", "", "Overrides the Name used to identify the file in Google Storage, Image and Instance. Defaults to [name]")
|
||||
diskSizeFlag := gcpCmd.Int("disk-size", 0, "Size of system disk in GB")
|
||||
skipCleanup := gcpCmd.Bool("skip-cleanup", false, "Don't remove images or VMs")
|
||||
|
||||
@ -53,20 +48,16 @@ func runGcp(args []string) {
|
||||
|
||||
remArgs := gcpCmd.Args()
|
||||
if len(remArgs) == 0 {
|
||||
fmt.Printf("Please specify the prefix to the image to boot\n")
|
||||
fmt.Printf("Please specify the name of the image to boot\n")
|
||||
gcpCmd.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
prefix := remArgs[0]
|
||||
name := remArgs[0]
|
||||
|
||||
zone := getStringValue(zoneVar, *zoneFlag, defaultZone)
|
||||
machine := getStringValue(machineVar, *machineFlag, defaultMachine)
|
||||
keys := getStringValue(keysVar, *keysFlag, "")
|
||||
project := getStringValue(projectVar, *projectFlag, "")
|
||||
bucket := getStringValue(bucketVar, *bucketFlag, "")
|
||||
public := getBoolValue(publicVar, *publicFlag)
|
||||
family := getStringValue(familyVar, *familyFlag, "")
|
||||
name := getStringValue(nameVar, *nameFlag, "")
|
||||
diskSize := getIntValue(diskSizeVar, *diskSizeFlag, defaultDiskSize)
|
||||
|
||||
client, err := NewGCPClient(keys, project)
|
||||
@ -74,33 +65,7 @@ func runGcp(args []string) {
|
||||
log.Fatalf("Unable to connect to GCP")
|
||||
}
|
||||
|
||||
suffix := ".img.tar.gz"
|
||||
if strings.HasSuffix(prefix, suffix) {
|
||||
src := prefix
|
||||
if name != "" {
|
||||
prefix = name
|
||||
} else {
|
||||
prefix = prefix[:len(prefix)-len(suffix)]
|
||||
}
|
||||
if bucket == "" {
|
||||
log.Fatalf("No bucket specified. Please provide one using the -bucket flag")
|
||||
}
|
||||
err = client.UploadFile(src, prefix+suffix, bucket, public)
|
||||
if err != nil {
|
||||
log.Fatalf("Error copying to Google Storage: %v", err)
|
||||
}
|
||||
err = client.CreateImage(prefix, "https://storage.googleapis.com/"+bucket+"/"+prefix+".img.tar.gz", family, true)
|
||||
if err != nil {
|
||||
log.Fatalf("Error creating Google Compute Image: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// If no name was supplied, use the prefix
|
||||
if name == "" {
|
||||
name = prefix
|
||||
}
|
||||
|
||||
if err = client.CreateInstance(name, prefix, zone, machine, diskSize, true); err != nil {
|
||||
if err = client.CreateInstance(name, name, zone, machine, diskSize, true); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
|
@ -31,13 +31,7 @@ var schema = string(`
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"format": {"type": "string"},
|
||||
"project": {"type": "string"},
|
||||
"bucket": {"type": "string"},
|
||||
"family": {"type": "string"},
|
||||
"keys": {"type": "string"},
|
||||
"public": {"type": "boolean"},
|
||||
"replace": {"type": "boolean"}
|
||||
"format": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"outputs": {
|
||||
|
Loading…
Reference in New Issue
Block a user