github.com/endophage/docker@v1.4.2-0.20161027011718-242853499895/client/image_build.go (about) 1 package client 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "io" 7 "net/http" 8 "net/url" 9 "regexp" 10 "strconv" 11 12 "golang.org/x/net/context" 13 14 "github.com/docker/docker/api/types" 15 "github.com/docker/docker/api/types/container" 16 ) 17 18 var headerRegexp = regexp.MustCompile(`\ADocker/.+\s\((.+)\)\z`) 19 20 // ImageBuild sends request to the daemon to build images. 21 // The Body in the response implement an io.ReadCloser and it's up to the caller to 22 // close it. 23 func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, options types.ImageBuildOptions) (types.ImageBuildResponse, error) { 24 query, err := imageBuildOptionsToQuery(options) 25 if err != nil { 26 return types.ImageBuildResponse{}, err 27 } 28 29 headers := http.Header(make(map[string][]string)) 30 buf, err := json.Marshal(options.AuthConfigs) 31 if err != nil { 32 return types.ImageBuildResponse{}, err 33 } 34 headers.Add("X-Registry-Config", base64.URLEncoding.EncodeToString(buf)) 35 headers.Set("Content-Type", "application/tar") 36 37 serverResp, err := cli.postRaw(ctx, "/build", query, buildContext, headers) 38 if err != nil { 39 return types.ImageBuildResponse{}, err 40 } 41 42 osType := GetDockerOS(serverResp.header.Get("Server")) 43 44 return types.ImageBuildResponse{ 45 Body: serverResp.body, 46 OSType: osType, 47 }, nil 48 } 49 50 func imageBuildOptionsToQuery(options types.ImageBuildOptions) (url.Values, error) { 51 query := url.Values{ 52 "t": options.Tags, 53 "securityopt": options.SecurityOpt, 54 } 55 if options.SuppressOutput { 56 query.Set("q", "1") 57 } 58 if options.RemoteContext != "" { 59 query.Set("remote", options.RemoteContext) 60 } 61 if options.NoCache { 62 query.Set("nocache", "1") 63 } 64 if options.Remove { 65 query.Set("rm", "1") 66 } else { 67 query.Set("rm", "0") 68 } 69 70 if options.ForceRemove { 71 query.Set("forcerm", "1") 72 } 73 74 if options.PullParent { 75 query.Set("pull", "1") 76 } 77 78 if options.Squash { 79 query.Set("squash", "1") 80 } 81 82 if !container.Isolation.IsDefault(options.Isolation) { 83 query.Set("isolation", string(options.Isolation)) 84 } 85 86 query.Set("cpusetcpus", options.CPUSetCPUs) 87 query.Set("networkmode", options.NetworkMode) 88 query.Set("cpusetmems", options.CPUSetMems) 89 query.Set("cpushares", strconv.FormatInt(options.CPUShares, 10)) 90 query.Set("cpuquota", strconv.FormatInt(options.CPUQuota, 10)) 91 query.Set("cpuperiod", strconv.FormatInt(options.CPUPeriod, 10)) 92 query.Set("memory", strconv.FormatInt(options.Memory, 10)) 93 query.Set("memswap", strconv.FormatInt(options.MemorySwap, 10)) 94 query.Set("cgroupparent", options.CgroupParent) 95 query.Set("shmsize", strconv.FormatInt(options.ShmSize, 10)) 96 query.Set("dockerfile", options.Dockerfile) 97 98 ulimitsJSON, err := json.Marshal(options.Ulimits) 99 if err != nil { 100 return query, err 101 } 102 query.Set("ulimits", string(ulimitsJSON)) 103 104 buildArgsJSON, err := json.Marshal(options.BuildArgs) 105 if err != nil { 106 return query, err 107 } 108 query.Set("buildargs", string(buildArgsJSON)) 109 110 labelsJSON, err := json.Marshal(options.Labels) 111 if err != nil { 112 return query, err 113 } 114 query.Set("labels", string(labelsJSON)) 115 116 cacheFromJSON, err := json.Marshal(options.CacheFrom) 117 if err != nil { 118 return query, err 119 } 120 query.Set("cachefrom", string(cacheFromJSON)) 121 122 return query, nil 123 } 124 125 // GetDockerOS returns the operating system based on the server header from the daemon. 126 func GetDockerOS(serverHeader string) string { 127 var osType string 128 matches := headerRegexp.FindStringSubmatch(serverHeader) 129 if len(matches) > 0 { 130 osType = matches[1] 131 } 132 return osType 133 }