| ... | ... |
@@ -77,7 +77,11 @@ func (b *BuilderClient) CmdRun(args string) error {
|
| 77 | 77 |
if err != nil {
|
| 78 | 78 |
return err |
| 79 | 79 |
} |
| 80 |
+ |
|
| 81 |
+ cmd, env := b.config.Cmd, b.config.Env |
|
| 82 |
+ b.config.Cmd = nil |
|
| 80 | 83 |
MergeConfig(b.config, config) |
| 84 |
+ |
|
| 81 | 85 |
body, statusCode, err := b.cli.call("POST", "/images/getCache", &ApiImageConfig{Id: b.image, Config: b.config})
|
| 82 | 86 |
if err != nil {
|
| 83 | 87 |
if statusCode != 404 {
|
| ... | ... |
@@ -89,11 +93,16 @@ func (b *BuilderClient) CmdRun(args string) error {
|
| 89 | 89 |
if err := json.Unmarshal(body, apiId); err != nil {
|
| 90 | 90 |
return err |
| 91 | 91 |
} |
| 92 |
+ utils.Debugf("Use cached version")
|
|
| 92 | 93 |
b.image = apiId.Id |
| 93 | 94 |
return nil |
| 94 | 95 |
} |
| 95 |
- b.commit() |
|
| 96 |
- return nil |
|
| 96 |
+ cid, err := b.run() |
|
| 97 |
+ if err != nil {
|
|
| 98 |
+ return err |
|
| 99 |
+ } |
|
| 100 |
+ b.config.Cmd, b.config.Env = cmd, env |
|
| 101 |
+ return b.commit(cid) |
|
| 97 | 102 |
} |
| 98 | 103 |
|
| 99 | 104 |
func (b *BuilderClient) CmdEnv(args string) error {
|
| ... | ... |
@@ -133,54 +142,80 @@ func (b *BuilderClient) CmdInsert(args string) error {
|
| 133 | 133 |
return fmt.Errorf("INSERT not implemented")
|
| 134 | 134 |
} |
| 135 | 135 |
|
| 136 |
-func (b *BuilderClient) commit() error {
|
|
| 137 |
- if b.config.Cmd == nil || len(b.config.Cmd) < 1 {
|
|
| 138 |
- b.config.Cmd = []string{"echo"}
|
|
| 136 |
+func (b *BuilderClient) run() (string, error) {
|
|
| 137 |
+ if b.image == "" {
|
|
| 138 |
+ return "", fmt.Errorf("Please provide a source image with `from` prior to run")
|
|
| 139 | 139 |
} |
| 140 |
- |
|
| 140 |
+ b.config.Image = b.image |
|
| 141 | 141 |
body, _, err := b.cli.call("POST", "/containers/create", b.config)
|
| 142 | 142 |
if err != nil {
|
| 143 |
- return err |
|
| 143 |
+ return "", err |
|
| 144 | 144 |
} |
| 145 | 145 |
|
| 146 |
- out := &ApiRun{}
|
|
| 147 |
- err = json.Unmarshal(body, out) |
|
| 148 |
- if err != nil {
|
|
| 149 |
- return err |
|
| 146 |
+ apiRun := &ApiRun{}
|
|
| 147 |
+ if err := json.Unmarshal(body, apiRun); err != nil {
|
|
| 148 |
+ return "", err |
|
| 150 | 149 |
} |
| 151 |
- |
|
| 152 |
- for _, warning := range out.Warnings {
|
|
| 150 |
+ for _, warning := range apiRun.Warnings {
|
|
| 153 | 151 |
fmt.Fprintln(os.Stderr, "WARNING: ", warning) |
| 154 | 152 |
} |
| 155 | 153 |
|
| 156 | 154 |
//start the container |
| 157 |
- _, _, err = b.cli.call("POST", "/containers/"+out.Id+"/start", nil)
|
|
| 155 |
+ _, _, err = b.cli.call("POST", "/containers/"+apiRun.Id+"/start", nil)
|
|
| 158 | 156 |
if err != nil {
|
| 159 |
- return err |
|
| 157 |
+ return "", err |
|
| 160 | 158 |
} |
| 161 |
- b.tmpContainers[out.Id] = struct{}{}
|
|
| 159 |
+ b.tmpContainers[apiRun.Id] = struct{}{}
|
|
| 162 | 160 |
|
| 163 | 161 |
// Wait for it to finish |
| 164 |
- _, _, err = b.cli.call("POST", "/containers/"+out.Id+"/wait", nil)
|
|
| 162 |
+ body, _, err = b.cli.call("POST", "/containers/"+apiRun.Id+"/wait", nil)
|
|
| 165 | 163 |
if err != nil {
|
| 166 |
- return err |
|
| 164 |
+ return "", err |
|
| 165 |
+ } |
|
| 166 |
+ apiWait := &ApiWait{}
|
|
| 167 |
+ if err := json.Unmarshal(body, apiWait); err != nil {
|
|
| 168 |
+ return "", err |
|
| 169 |
+ } |
|
| 170 |
+ if apiWait.StatusCode != 0 {
|
|
| 171 |
+ return "", fmt.Errorf("The command %v returned a non-zero code: %d", b.config.Cmd, apiWait.StatusCode)
|
|
| 172 |
+ } |
|
| 173 |
+ |
|
| 174 |
+ return apiRun.Id, nil |
|
| 175 |
+} |
|
| 176 |
+ |
|
| 177 |
+func (b *BuilderClient) commit(id string) error {
|
|
| 178 |
+ if b.image == "" {
|
|
| 179 |
+ return fmt.Errorf("Please provide a source image with `from` prior to run")
|
|
| 180 |
+ } |
|
| 181 |
+ b.config.Image = b.image |
|
| 182 |
+ |
|
| 183 |
+ if id == "" {
|
|
| 184 |
+ cmd := b.config.Cmd |
|
| 185 |
+ b.config.Cmd = []string{"true"}
|
|
| 186 |
+ if cid, err := b.run(); err != nil {
|
|
| 187 |
+ return err |
|
| 188 |
+ } else {
|
|
| 189 |
+ id = cid |
|
| 190 |
+ } |
|
| 191 |
+ b.config.Cmd = cmd |
|
| 167 | 192 |
} |
| 168 | 193 |
|
| 169 | 194 |
// Commit the container |
| 170 | 195 |
v := url.Values{}
|
| 171 |
- v.Set("container", out.Id)
|
|
| 196 |
+ v.Set("container", id)
|
|
| 172 | 197 |
v.Set("author", b.maintainer)
|
| 173 |
- body, _, err = b.cli.call("POST", "/commit?"+v.Encode(), b.config)
|
|
| 198 |
+ |
|
| 199 |
+ body, _, err := b.cli.call("POST", "/commit?"+v.Encode(), b.config)
|
|
| 174 | 200 |
if err != nil {
|
| 175 | 201 |
return err |
| 176 | 202 |
} |
| 177 | 203 |
apiId := &ApiId{}
|
| 178 |
- err = json.Unmarshal(body, apiId) |
|
| 179 |
- if err != nil {
|
|
| 204 |
+ if err := json.Unmarshal(body, apiId); err != nil {
|
|
| 180 | 205 |
return err |
| 181 | 206 |
} |
| 182 | 207 |
b.tmpImages[apiId.Id] = struct{}{}
|
| 183 | 208 |
b.image = apiId.Id |
| 209 |
+ b.needCommit = false |
|
| 184 | 210 |
return nil |
| 185 | 211 |
} |
| 186 | 212 |
|
| ... | ... |
@@ -221,7 +256,9 @@ func (b *BuilderClient) Build(dockerfile io.Reader) (string, error) {
|
| 221 | 221 |
fmt.Printf("===> %v\n", b.image)
|
| 222 | 222 |
} |
| 223 | 223 |
if b.needCommit {
|
| 224 |
- b.commit() |
|
| 224 |
+ if err := b.commit(""); err != nil {
|
|
| 225 |
+ return "", err |
|
| 226 |
+ } |
|
| 225 | 227 |
} |
| 226 | 228 |
if b.image != "" {
|
| 227 | 229 |
// The build is successful, keep the temporary containers and images |