func installImage(cmd *cobra.Command, args []string) { if err := environment.ExtractVariablesFrom(&args, true); err != nil { gcmd.Fail(1, err.Error()) } if len(args) < 2 { gcmd.Fail(1, "Valid arguments: <image_name> <id> ...") } t := defaultTransport.Get() imageId := args[0] if imageId == "" { gcmd.Fail(1, "Argument 1 must be a Docker image to base the service on") } ids, err := gcmd.NewContainerLocators(t, args[1:]...) if err != nil { gcmd.Fail(1, "You must pass one or more valid service names: %s", err.Error()) } for _, locator := range ids { if imageId == string(gcmd.AsIdentifier(locator)) { gcmd.Fail(1, "Image name and container id must not be the same: %s", imageId) } } gcmd.Executor{ On: ids, Serial: func(on gcmd.Locator) gcmd.JobRequest { r := cjobs.InstallContainerRequest{ RequestIdentifier: jobs.NewRequestIdentifier(), Id: gcmd.AsIdentifier(on), Image: imageId, Started: start, Isolate: isolate, SocketActivation: sockAct, Ports: *portPairs.Get().(*port.PortPairs), Environment: &environment.Description, NetworkLinks: networkLinks.NetworkLinks, } return &r }, Output: os.Stdout, Transport: t, }.StreamAndExit() }
func restartContainer(cmd *cobra.Command, args []string) { t := defaultTransport.Get() if err := gcmd.ExtractContainerLocatorsFromDeployment(t, deploymentPath, &args); err != nil { gcmd.Fail(1, err.Error()) } if len(args) < 1 { gcmd.Fail(1, "Valid arguments: <id> ...") } ids, err := gcmd.NewContainerLocators(t, args...) if err != nil { gcmd.Fail(1, "You must pass one or more valid service names: %s", err.Error()) } gcmd.Executor{ On: ids, Serial: func(on gcmd.Locator) gcmd.JobRequest { return &cjobs.RestartContainerRequest{ Id: gcmd.AsIdentifier(on), } }, Output: os.Stdout, Transport: t, }.StreamAndExit() }
func linkContainers(cmd *cobra.Command, args []string) { if len(args) < 1 { gcmd.Fail(1, "Valid arguments: <id> ...") } t := defaultTransport.Get() ids, err := gcmd.NewContainerLocators(t, args...) if err != nil { gcmd.Fail(1, "You must pass one or more valid service names: %s", err.Error()) } if networkLinks.NetworkLinks == nil { networkLinks.NetworkLinks = &containers.NetworkLinks{} } gcmd.Executor{ On: ids, Group: func(on ...gcmd.Locator) gcmd.JobRequest { links := &containers.ContainerLinks{make([]containers.ContainerLink, 0, len(on))} for i := range on { links.Links = append(links.Links, containers.ContainerLink{gcmd.AsIdentifier(on[i]), *networkLinks.NetworkLinks}) } return &cjobs.LinkContainersRequest{links} }, Output: os.Stdout, OnSuccess: func(r *gcmd.CliJobResponse, w io.Writer, job gcmd.JobRequest) { fmt.Fprintf(w, "Links set on %s\n", job.(*cjobs.LinkContainersRequest).ContainerLinks.String()) }, Transport: t, }.StreamAndExit() }
func deleteContainer(cmd *cobra.Command, args []string) { t := defaultTransport.Get() if err := gcmd.ExtractContainerLocatorsFromDeployment(t, deploymentPath, &args); err != nil { gcmd.Fail(1, err.Error()) } if len(args) < 1 { gcmd.Fail(1, "Valid arguments: <id> ...") } ids, err := gcmd.NewContainerLocators(t, args...) if err != nil { gcmd.Fail(1, "You must pass one or more valid service names: %s", err.Error()) } gcmd.Executor{ On: ids, Serial: func(on gcmd.Locator) gcmd.JobRequest { return &cjobs.DeleteContainerRequest{ Id: gcmd.AsIdentifier(on), } }, Output: os.Stdout, OnSuccess: func(r *gcmd.CliJobResponse, w io.Writer, job gcmd.JobRequest) { fmt.Fprintf(w, "Deleted %s", string(job.(*cjobs.DeleteContainerRequest).Id)) }, Transport: t, }.StreamAndExit() }
func setEnvironment(cmd *cobra.Command, args []string) { if err := environment.ExtractVariablesFrom(&args, false); err != nil { gcmd.Fail(1, err.Error()) } if len(args) < 1 { gcmd.Fail(1, "Valid arguments: <name>... <key>=<value>...") } t := defaultTransport.Get() ids, err := gcmd.NewContainerLocators(t, args...) if err != nil { gcmd.Fail(1, "You must pass one or more valid service names: %s", err.Error()) } gcmd.Executor{ On: ids, Serial: func(on gcmd.Locator) gcmd.JobRequest { environment.Description.Id = gcmd.AsIdentifier(on) if resetEnv { return &cjobs.PutEnvironmentRequest{environment.Description} } return &cjobs.PatchEnvironmentRequest{environment.Description} }, Output: os.Stdout, Transport: t, }.StreamAndExit() }
func containerStatus(cmd *cobra.Command, args []string) { t := defaultTransport.Get() if err := gcmd.ExtractContainerLocatorsFromDeployment(t, deploymentPath, &args); err != nil { gcmd.Fail(1, err.Error()) } if len(args) < 1 { gcmd.Fail(1, "Valid arguments: <id> ...") } ids, err := gcmd.NewContainerLocators(t, args...) if err != nil { gcmd.Fail(1, "You must pass one or more valid service names: %s", err.Error()) } data, errors := gcmd.Executor{ On: ids, Serial: func(on gcmd.Locator) gcmd.JobRequest { return &cjobs.ContainerStatusRequest{ Id: gcmd.AsIdentifier(on), } }, Output: os.Stdout, Transport: t, }.Gather() for i := range data { if buf, ok := data[i].(*bytes.Buffer); ok { if i > 0 { fmt.Fprintf(os.Stdout, "\n-------------\n") } buf.WriteTo(os.Stdout) } } if len(errors) > 0 { for i := range errors { fmt.Fprintf(os.Stderr, "Error: %s\n", errors[i]) } os.Exit(1) } os.Exit(0) }
func showEnvironment(cmd *cobra.Command, args []string) { if len(args) < 1 { gcmd.Fail(1, "Valid arguments: <id> ...") } t := defaultTransport.Get() ids, err := gcmd.NewContainerLocators(t, args[0:]...) if err != nil { gcmd.Fail(1, "You must pass one or more valid environment ids: %s", err.Error()) } data, errors := gcmd.Executor{ On: ids, Serial: func(on gcmd.Locator) gcmd.JobRequest { return &cjobs.ContentRequest{ Locator: string(gcmd.AsIdentifier(on)), Type: cjobs.ContentTypeEnvironment, } }, Output: os.Stdout, Transport: t, }.Gather() for i := range data { if buf, ok := data[i].(*bytes.Buffer); ok { buf.WriteTo(os.Stdout) } } if len(errors) > 0 { for i := range errors { fmt.Fprintf(os.Stderr, "Error: %s\n", errors[i]) } os.Exit(1) } os.Exit(0) }
func deployContainers(cmd *cobra.Command, args []string) { if len(args) < 1 { gcmd.Fail(1, "Valid arguments: <deployment_file|URL> <host> ...") } t := defaultTransport.Get() path := args[0] if path == "" { gcmd.Fail(1, "Argument 1 must be deployment file or URL describing how the containers are related") } u, err := url.Parse(path) if nil != err { gcmd.Fail(1, "Cannot Parse Argument 1: %s", err.Error()) } var deploy *deployment.Deployment switch u.Scheme { case "": deploy, err = deployment.NewDeploymentFromFile(u.Path) case "file": deploy, err = deployment.NewDeploymentFromFile(u.Path) case "http", "https": deploy, err = deployment.NewDeploymentFromURL(u.String(), insecure, time.Duration(timeout)) default: gcmd.Fail(1, "Unsupported URL Scheme '%s' for deployment", u.Scheme) } if nil != err { gcmd.Fail(1, "Unable to load deployment from %s: %s", path, err.Error()) } if len(args) == 1 { args = append(args, transport.Local.String()) } servers, err := transport.NewTransportLocators(t, args[1:]...) if err != nil { gcmd.Fail(1, "You must pass zero or more valid host names (use '%s' or pass no arguments for the current server): %s", transport.Local.String(), err.Error()) } re := regexp.MustCompile("\\.\\d{8}\\-\\d{6}\\z") now := time.Now().Format(".20060102-150405") base := filepath.Base(path) base = re.ReplaceAllString(base, "") newPath := base + now fmt.Printf("==> Deploying %s\n", path) changes, removed, err := deploy.Describe(deployment.SimplePlacement(servers), t) if err != nil { gcmd.Fail(1, "Deployment is not valid: %s", err.Error()) } if len(removed) > 0 { removedIds, err := gcmd.LocatorsForDeploymentInstances(t, removed) if err != nil { gcmd.Fail(1, "Unable to generate deployment info: %s", err.Error()) } failures := gcmd.Executor{ On: removedIds, Serial: func(on gcmd.Locator) gcmd.JobRequest { return &cjobs.DeleteContainerRequest{ Id: gcmd.AsIdentifier(on), } }, Output: os.Stdout, OnSuccess: func(r *gcmd.CliJobResponse, w io.Writer, job gcmd.JobRequest) { fmt.Fprintf(w, "==> Deleted %s", string(job.(*cjobs.DeleteContainerRequest).Id)) }, Transport: t, }.Stream() for i := range failures { fmt.Fprintf(os.Stderr, failures[i].Error()) } } addedIds, err := gcmd.LocatorsForDeploymentInstances(t, changes.Instances.Added()) if err != nil { gcmd.Fail(1, "Unable to generate deployment info: %s", err.Error()) } errors := gcmd.Executor{ On: addedIds, Serial: func(on gcmd.Locator) gcmd.JobRequest { instance, _ := changes.Instances.Find(gcmd.AsIdentifier(on)) links := instance.NetworkLinks() return &cjobs.InstallContainerRequest{ RequestIdentifier: jobs.NewRequestIdentifier(), Id: instance.Id, Image: instance.Image, Isolate: isolate, Ports: instance.Ports.PortPairs(), NetworkLinks: &links, } }, OnSuccess: func(r *gcmd.CliJobResponse, w io.Writer, job gcmd.JobRequest) { installJob := job.(*cjobs.InstallContainerRequest) instance, _ := changes.Instances.Find(installJob.Id) if pairs, ok := installJob.PortMappingsFrom(r.Pending); ok { if !instance.Ports.Update(pairs) { fmt.Fprintf(os.Stderr, "Not all ports listed %+v were returned by the server %+v", instance.Ports, pairs) } } }, Output: os.Stdout, Transport: t, }.Stream() changes.UpdateLinks() for _, c := range changes.Containers { instances := c.Instances() if len(instances) > 0 { for _, link := range instances[0].NetworkLinks() { fmt.Printf("==> Linking %s: %s:%d -> %s:%d\n", c.Name, link.FromHost, link.FromPort, link.ToHost, link.ToPort) } } } contents, _ := json.MarshalIndent(changes, "", " ") contents = append(contents, []byte("\n")...) if err := ioutil.WriteFile(newPath, contents, 0664); err != nil { fmt.Fprintf(os.Stderr, "Unable to write %s: %s\n", newPath, err.Error()) } linkedIds, err := gcmd.LocatorsForDeploymentInstances(t, changes.Instances.Linked()) if err != nil { gcmd.Fail(1, "Unable to generate deployment info: %s", err.Error()) } gcmd.Executor{ On: linkedIds, Group: func(on ...gcmd.Locator) gcmd.JobRequest { links := []containers.ContainerLink{} for i := range on { instance, _ := changes.Instances.Find(gcmd.AsIdentifier(on[i])) network := instance.NetworkLinks() if len(network) > 0 { links = append(links, containers.ContainerLink{instance.Id, network}) } } return &cjobs.LinkContainersRequest{&containers.ContainerLinks{links}} }, Output: os.Stdout, Transport: t, }.Stream() gcmd.Executor{ On: addedIds, Serial: func(on gcmd.Locator) gcmd.JobRequest { return &cjobs.StartedContainerStateRequest{ Id: gcmd.AsIdentifier(on), } }, Output: os.Stdout, Transport: t, }.Stream() fmt.Printf("==> Deployed as %s\n", newPath) if len(errors) > 0 { for i := range errors { fmt.Fprintf(os.Stderr, "Error: %s\n", errors[i]) } os.Exit(1) } }