func (cli *DockerCli) call(method, path string, data interface{}, passAuthInfo bool) (io.ReadCloser, int, error) { params, err := cli.encodeData(data) if err != nil { return nil, -1, err } req, err := http.NewRequest(method, fmt.Sprintf("/v%s%s", api.APIVERSION, path), params) if err != nil { return nil, -1, err } if passAuthInfo { cli.LoadConfigFile() // Resolve the Auth config relevant for this server authConfig := cli.configFile.ResolveAuthConfig(registry.IndexServerAddress()) getHeaders := func(authConfig registry.AuthConfig) (map[string][]string, error) { buf, err := json.Marshal(authConfig) if err != nil { return nil, err } registryAuthHeader := []string{ base64.URLEncoding.EncodeToString(buf), } return map[string][]string{"X-Registry-Auth": registryAuthHeader}, nil } if headers, err := getHeaders(authConfig); err == nil && headers != nil { for k, v := range headers { req.Header[k] = v } } } req.Header.Set("User-Agent", "Docker-Client/"+dockerversion.VERSION) req.URL.Host = cli.addr req.URL.Scheme = cli.scheme if data != nil { req.Header.Set("Content-Type", "application/json") } else if method == "POST" { req.Header.Set("Content-Type", "plain/text") } resp, err := cli.HTTPClient().Do(req) if err != nil { if strings.Contains(err.Error(), "connection refused") { return nil, -1, ErrConnectionRefused } if cli.tlsConfig == nil { return nil, -1, fmt.Errorf("%v. Are you trying to connect to a TLS-enabled daemon without TLS?", err) } return nil, -1, fmt.Errorf("An error occurred trying to connect: %v", err) } if resp.StatusCode < 200 || resp.StatusCode >= 400 { body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, -1, err } if len(body) == 0 { return nil, resp.StatusCode, fmt.Errorf("Error: request returned %s for API route and version %s, check if the server supports the requested API version", http.StatusText(resp.StatusCode), req.URL) } return nil, resp.StatusCode, fmt.Errorf("Error response from daemon: %s", bytes.TrimSpace(body)) } return resp.Body, resp.StatusCode, nil }
func main() { var insecureDockerRegistries registries var dockerRegistryIPs ips flagSet := flag.NewFlagSet("builder", flag.ExitOnError) dockerImageURL := flagSet.String( "dockerImageURL", "", "docker image uri in docker://[registry/][scope/]repository[#tag] format", ) dockerRef := flagSet.String( "dockerRef", "", "docker image reference in standard docker string format", ) outputFilename := flagSet.String( "outputMetadataJSONFilename", "/tmp/result/result.json", "filename in which to write the app metadata", ) flagSet.Var( &insecureDockerRegistries, "insecureDockerRegistries", "insecure Docker Registry addresses (host:port)", ) dockerDaemonExecutablePath := flagSet.String( "dockerDaemonExecutablePath", "/tmp/docker_app_lifecycle/docker", "path to the 'docker' executable", ) cacheDockerImage := flagSet.Bool( "cacheDockerImage", false, "Caches Docker images to private docker registry", ) flagSet.Var( &dockerRegistryIPs, "dockerRegistryIPs", "Docker Registry IPs", ) dockerRegistryHost := flagSet.String( "dockerRegistryHost", "", "Docker Registry host", ) dockerRegistryPort := flagSet.Int( "dockerRegistryPort", 8080, "Docker Registry port", ) dockerLoginServer := flagSet.String( "dockerLoginServer", registry.IndexServerAddress(), "Docker Login server address", ) dockerUser := flagSet.String( "dockerUser", "", "User for pulling from docker registry", ) dockerPassword := flagSet.String( "dockerPassword", "", "Password for pulling from docker registry", ) dockerEmail := flagSet.String( "dockerEmail", "", "Email for pulling from docker registry", ) if err := flagSet.Parse(os.Args[1:len(os.Args)]); err != nil { println(err.Error()) os.Exit(1) } var repoName string var tag string if len(*dockerImageURL) > 0 { parts, err := url.Parse(*dockerImageURL) if err != nil { println("invalid dockerImageURL: " + *dockerImageURL) flagSet.PrintDefaults() os.Exit(1) } repoName, tag = helpers.ParseDockerURL(parts) } else if len(*dockerRef) > 0 { repoName, tag = helpers.ParseDockerRef(*dockerRef) } else { println("missing flag: dockerImageURL or dockerRef required") flagSet.PrintDefaults() os.Exit(1) } builder := Builder{ RepoName: repoName, Tag: tag, OutputFilename: *outputFilename, DockerDaemonExecutablePath: *dockerDaemonExecutablePath, InsecureDockerRegistries: insecureDockerRegistries, DockerDaemonTimeout: 10 * time.Second, CacheDockerImage: *cacheDockerImage, DockerRegistryIPs: dockerRegistryIPs, DockerRegistryHost: *dockerRegistryHost, DockerRegistryPort: *dockerRegistryPort, DockerLoginServer: *dockerLoginServer, DockerUser: *dockerUser, DockerPassword: *dockerPassword, DockerEmail: *dockerEmail, } members := grouper.Members{ {"builder", ifrit.RunFunc(builder.Run)}, } if *cacheDockerImage { if len(dockerRegistryIPs) == 0 { println("missing flag: dockerRegistryIPs required") os.Exit(1) } if len(*dockerRegistryHost) == 0 { println("missing flag: dockerRegistryHost required") os.Exit(1) } if strings.Contains(*dockerRegistryHost, ":") { println("invalid host format", *dockerRegistryHost) os.Exit(1) } if *dockerRegistryPort < 0 { println("negative port number", *dockerRegistryPort) os.Exit(1) } if *dockerRegistryPort > 65535 { println("port number too big", *dockerRegistryPort) os.Exit(1) } validateCredentials(*dockerLoginServer, *dockerUser, *dockerPassword, *dockerEmail) if _, err := os.Stat(*dockerDaemonExecutablePath); err != nil { println("docker daemon not found in", *dockerDaemonExecutablePath) os.Exit(1) } dockerDaemon := DockerDaemon{ DockerDaemonPath: *dockerDaemonExecutablePath, InsecureDockerRegistries: insecureDockerRegistries, DockerRegistryIPs: dockerRegistryIPs, DockerRegistryHost: *dockerRegistryHost, } members = append(members, grouper.Member{"docker_daemon", ifrit.RunFunc(dockerDaemon.Run)}) } group := grouper.NewParallel(os.Interrupt, members) process := ifrit.Invoke(sigmon.New(group)) fmt.Println("Staging process started ...") err := <-process.Wait() if err != nil { println("Staging process failed:", err.Error()) os.Exit(2) } fmt.Println("Staging process finished") }