func serviceAdd(args Add) { if args.ContainerEnvironment == nil { args.ContainerEnvironment = make([]string, 0) } // Parse command if cmdAddCommand != "" { command, err := shlex.Split(cmdAddCommand) if err != nil { fmt.Fprintf(os.Stderr, "Fatal, cannot split command %s\n", err) return } args.ContainerCommand = command } // Parse Entrypoint if cmdAddEntrypoint != "" { entrypoint, err := shlex.Split(cmdAddEntrypoint) if err != nil { fmt.Fprintf(os.Stderr, "Fatal, cannot split command %s\n", err) return } args.ContainerEntrypoint = entrypoint } // Parse volumes if len(cmdAddVolume) > 0 { args.Volumes = make(map[string]VolumeConfig) } for _, vol := range cmdAddVolume { t := strings.Split(vol, ":") if len(t) == 2 { args.Volumes[t[0]] = VolumeConfig{Size: t[1]} } else if len(t) == 1 { args.Volumes[t[0]] = VolumeConfig{Size: "10"} } else { fmt.Fprintf(os.Stderr, "Error: Volume parameter '%s' not formated correctly\n", vol) os.Exit(1) } } // Parse links if len(redeployLink) > 0 { args.Links = make(map[string]string) } for _, link := range cmdAddLink { t := strings.Split(link, ":") if len(t) == 1 { args.Links[t[0]] = t[0] } else { args.Links[t[0]] = t[1] } } // Parse ContainerNetworks arguments for _, network := range cmdAddNetwork { args.ContainerNetwork[network] = make(map[string][]string) } for _, gat := range cmdAddGateway { t := strings.Split(gat, ":") if len(t) != 2 { fmt.Fprintf(os.Stderr, "Invalid gateway parameter, should be \"input:output\". Typically, output will be one of 'predictor', 'public'") os.Exit(1) } if _, ok := args.ContainerNetwork[t[0]]; !ok { fmt.Fprintf(os.Stderr, "Automatically adding %s to network list\n", t[0]) args.ContainerNetwork[t[0]] = make(map[string][]string) } if _, ok := args.ContainerNetwork[t[1]]; !ok { fmt.Fprintf(os.Stderr, "Automatically adding %s to network list\n", t[0]) args.ContainerNetwork[t[1]] = make(map[string][]string) } args.ContainerNetwork[t[0]]["gateway_to"] = append(args.ContainerNetwork[t[0]]["gateway_to"], t[1]) } // Parse ContainerPorts args.ContainerPorts = parsePublishedPort(addPublish) path := fmt.Sprintf("/applications/%s/services/%s", args.Application, args.Service) body, err := json.MarshalIndent(args, " ", " ") if err != nil { fmt.Fprintf(os.Stderr, "Fatal: %s\n", err) return } stream := "" if !addBatch { stream = "?stream" } buffer, code, err := internal.Stream("POST", path+stream, body) // http.Request failed for some reason if err != nil { fmt.Fprintf(os.Stderr, "Error: %s\n", err) return } // If we are in ensure mode, fallback to redeploy if code == 409 && cmdAddRedeploy { ensureMode(args) return } else if code >= 400 { body, err = ioutil.ReadAll(buffer) internal.Check(err) internal.FormatOutputError(body) return } line, err := internal.DisplayStream(buffer) // If we are in ensure mode, fallback to redeploy if err != nil { e := internal.DecodeError(line) if e != nil && e.Code == 409 && cmdAddRedeploy { ensureMode(args) return } internal.FormatOutputError(line) return } // Always start service if internal.Format == "pretty" { fmt.Fprintf(os.Stderr, "Starting service %s/%s...\n", args.Application, args.Service) } serviceStart(args.Application, args.Service, addBatch) }
func serviceAdd(args Add) { if args.ContainerEnvironment == nil { args.ContainerEnvironment = make([]string, 0) } // Parse volumes if len(cmdAddVolume) > 0 { args.Volumes = make(map[string]VolumeConfig) } for _, vol := range cmdAddVolume { t := strings.Split(vol, ":") if len(t) == 2 { args.Volumes[t[0]] = VolumeConfig{Size: t[1]} } else if len(t) == 1 { args.Volumes[t[0]] = VolumeConfig{Size: "10"} } else { fmt.Fprintf(os.Stderr, "Error: Volume parameter '%s' not formated correctly\n", vol) os.Exit(1) } } // Parse links if len(redeployLink) > 0 { args.Links = make(map[string]string) } for _, link := range cmdAddLink { t := strings.Split(link, ":") if len(t) == 1 { args.Links[t[0]] = t[0] } else { args.Links[t[0]] = t[1] } } // Parse ContainerNetworks arguments for _, network := range cmdAddNetwork { args.ContainerNetwork[network] = make(map[string][]string) } for _, gat := range cmdAddGateway { t := strings.Split(gat, ":") if len(t) != 2 { fmt.Fprintf(os.Stderr, "Invalid gateway parameter, should be \"input:output\". Typically, output will be one of 'predictor', 'public'") os.Exit(1) } if _, ok := args.ContainerNetwork[t[0]]; !ok { fmt.Fprintf(os.Stderr, "Automatically adding %s to network list\n", t[0]) args.ContainerNetwork[t[0]] = make(map[string][]string) } if _, ok := args.ContainerNetwork[t[1]]; !ok { fmt.Fprintf(os.Stderr, "Automatically adding %s to network list\n", t[0]) args.ContainerNetwork[t[1]] = make(map[string][]string) } args.ContainerNetwork[t[0]]["gateway_to"] = append(args.ContainerNetwork[t[0]]["gateway_to"], t[1]) } // Parse ContainerPorts args.ContainerPorts = parsePublishedPort(addPublish) path := fmt.Sprintf("/applications/%s/services/%s", args.Application, args.Service) body, err := json.MarshalIndent(args, " ", " ") if err != nil { fmt.Fprintf(os.Stderr, "Fatal: %s\n", err) return } if addBatch { ret, code, err := internal.Request("POST", path, body) // http.Request failed for some reason if err != nil { fmt.Fprintf(os.Stderr, "Error: %s\n", err) return } // If we are in ensure mode, fallback to redeploy if code == 409 && cmdAddRedeploy { ensureMode(args) return } // If API returned a json error e := internal.DecodeError(ret) if e != nil { fmt.Fprintf(os.Stderr, "%s\n", e) return } // Just print data internal.FormatOutputDef(ret) // Always start service if internal.Format == "pretty" { fmt.Fprintf(os.Stderr, "Starting service %s/%s...\n", args.Application, args.Service) } serviceStart(args.Application, args.Service, false) return } buffer, code, err := internal.Stream("POST", path+"?stream", body) if err != nil { fmt.Fprintf(os.Stderr, "Error: %s\n", err) return } if code == 409 && cmdAddRedeploy { ensureMode(args) return } line, err := internal.DisplayStream(buffer) internal.Check(err) if line != nil { var data map[string]interface{} err = json.Unmarshal(line, &data) internal.Check(err) fmt.Printf("Hostname: %v\n", data["hostname"]) fmt.Printf("Running containers: %v/%v\n", data["container_number"], data["container_target"]) } }