mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Remove engine.Job from builder.CmdBuildConfig.
Signed-off-by: David Calavera <david.calavera@gmail.com>
This commit is contained in:
parent
9a2c009751
commit
ae4063585e
7 changed files with 196 additions and 202 deletions
20
api/server/form.go
Normal file
20
api/server/form.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func boolValue(r *http.Request, k string) bool {
|
||||||
|
s := strings.ToLower(strings.TrimSpace(r.FormValue(k)))
|
||||||
|
return !(s == "" || s == "0" || s == "no" || s == "false" || s == "none")
|
||||||
|
}
|
||||||
|
|
||||||
|
func int64Value(r *http.Request, k string) int64 {
|
||||||
|
val, err := strconv.ParseInt(r.FormValue(k), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
}
|
55
api/server/form_test.go
Normal file
55
api/server/form_test.go
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBoolValue(t *testing.T) {
|
||||||
|
cases := map[string]bool{
|
||||||
|
"": false,
|
||||||
|
"0": false,
|
||||||
|
"no": false,
|
||||||
|
"false": false,
|
||||||
|
"none": false,
|
||||||
|
"1": true,
|
||||||
|
"yes": true,
|
||||||
|
"true": true,
|
||||||
|
"one": true,
|
||||||
|
"100": true,
|
||||||
|
}
|
||||||
|
|
||||||
|
for c, e := range cases {
|
||||||
|
v := url.Values{}
|
||||||
|
v.Set("test", c)
|
||||||
|
r, _ := http.NewRequest("POST", "", nil)
|
||||||
|
r.Form = v
|
||||||
|
|
||||||
|
a := boolValue(r, "test")
|
||||||
|
if a != e {
|
||||||
|
t.Fatalf("Value: %s, expected: %v, actual: %v", c, e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInt64Value(t *testing.T) {
|
||||||
|
cases := map[string]int64{
|
||||||
|
"": 0,
|
||||||
|
"asdf": 0,
|
||||||
|
"0": 0,
|
||||||
|
"1": 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
for c, e := range cases {
|
||||||
|
v := url.Values{}
|
||||||
|
v.Set("test", c)
|
||||||
|
r, _ := http.NewRequest("POST", "", nil)
|
||||||
|
r.Form = v
|
||||||
|
|
||||||
|
a := int64Value(r, "test")
|
||||||
|
if a != e {
|
||||||
|
t.Fatalf("Value: %s, expected: %v, actual: %v", c, e, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -381,7 +381,7 @@ func (s *Server) getImagesJSON(eng *engine.Engine, version version.Version, w ht
|
||||||
Filters: r.Form.Get("filters"),
|
Filters: r.Form.Get("filters"),
|
||||||
// FIXME this parameter could just be a match filter
|
// FIXME this parameter could just be a match filter
|
||||||
Filter: r.Form.Get("filter"),
|
Filter: r.Form.Get("filter"),
|
||||||
All: toBool(r.Form.Get("all")),
|
All: boolValue(r, "all"),
|
||||||
}
|
}
|
||||||
|
|
||||||
images, err := s.daemon.Repositories().Images(&imagesConfig)
|
images, err := s.daemon.Repositories().Images(&imagesConfig)
|
||||||
|
@ -597,8 +597,8 @@ func (s *Server) getContainersJSON(eng *engine.Engine, version version.Version,
|
||||||
}
|
}
|
||||||
|
|
||||||
config := &daemon.ContainersConfig{
|
config := &daemon.ContainersConfig{
|
||||||
All: toBool(r.Form.Get("all")),
|
All: boolValue(r, "all"),
|
||||||
Size: toBool(r.Form.Get("size")),
|
Size: boolValue(r, "size"),
|
||||||
Since: r.Form.Get("since"),
|
Since: r.Form.Get("since"),
|
||||||
Before: r.Form.Get("before"),
|
Before: r.Form.Get("before"),
|
||||||
Filters: r.Form.Get("filters"),
|
Filters: r.Form.Get("filters"),
|
||||||
|
@ -640,14 +640,14 @@ func (s *Server) getContainersLogs(eng *engine.Engine, version version.Version,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate args here, because we can't return not StatusOK after job.Run() call
|
// Validate args here, because we can't return not StatusOK after job.Run() call
|
||||||
stdout, stderr := toBool(r.Form.Get("stdout")), toBool(r.Form.Get("stderr"))
|
stdout, stderr := boolValue(r, "stdout"), boolValue(r, "stderr")
|
||||||
if !(stdout || stderr) {
|
if !(stdout || stderr) {
|
||||||
return fmt.Errorf("Bad parameters: you must choose at least one stream")
|
return fmt.Errorf("Bad parameters: you must choose at least one stream")
|
||||||
}
|
}
|
||||||
|
|
||||||
logsConfig := &daemon.ContainerLogsConfig{
|
logsConfig := &daemon.ContainerLogsConfig{
|
||||||
Follow: toBool(r.Form.Get("follow")),
|
Follow: boolValue(r, "follow"),
|
||||||
Timestamps: toBool(r.Form.Get("timestamps")),
|
Timestamps: boolValue(r, "timestamps"),
|
||||||
Tail: r.Form.Get("tail"),
|
Tail: r.Form.Get("tail"),
|
||||||
UseStdout: stdout,
|
UseStdout: stdout,
|
||||||
UseStderr: stderr,
|
UseStderr: stderr,
|
||||||
|
@ -671,7 +671,7 @@ func (s *Server) postImagesTag(eng *engine.Engine, version version.Version, w ht
|
||||||
|
|
||||||
repo := r.Form.Get("repo")
|
repo := r.Form.Get("repo")
|
||||||
tag := r.Form.Get("tag")
|
tag := r.Form.Get("tag")
|
||||||
force := toBool(r.Form.Get("force"))
|
force := boolValue(r, "force")
|
||||||
if err := s.daemon.Repositories().Tag(repo, tag, vars["name"], force); err != nil {
|
if err := s.daemon.Repositories().Tag(repo, tag, vars["name"], force); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -690,11 +690,20 @@ func (s *Server) postCommit(eng *engine.Engine, version version.Version, w http.
|
||||||
|
|
||||||
cont := r.Form.Get("container")
|
cont := r.Form.Get("container")
|
||||||
|
|
||||||
pause := toBool(r.Form.Get("pause"))
|
pause := boolValue(r, "pause")
|
||||||
if r.FormValue("pause") == "" && version.GreaterThanOrEqualTo("1.13") {
|
if r.FormValue("pause") == "" && version.GreaterThanOrEqualTo("1.13") {
|
||||||
pause = true
|
pause = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c, _, err := runconfig.DecodeContainerConfig(r.Body)
|
||||||
|
if err != nil && err != io.EOF { //Do not fail if body is empty.
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if c == nil {
|
||||||
|
c = &runconfig.Config{}
|
||||||
|
}
|
||||||
|
|
||||||
containerCommitConfig := &daemon.ContainerCommitConfig{
|
containerCommitConfig := &daemon.ContainerCommitConfig{
|
||||||
Pause: pause,
|
Pause: pause,
|
||||||
Repo: r.Form.Get("repo"),
|
Repo: r.Form.Get("repo"),
|
||||||
|
@ -702,10 +711,10 @@ func (s *Server) postCommit(eng *engine.Engine, version version.Version, w http.
|
||||||
Author: r.Form.Get("author"),
|
Author: r.Form.Get("author"),
|
||||||
Comment: r.Form.Get("comment"),
|
Comment: r.Form.Get("comment"),
|
||||||
Changes: r.Form["changes"],
|
Changes: r.Form["changes"],
|
||||||
Config: r.Body,
|
Config: c,
|
||||||
}
|
}
|
||||||
|
|
||||||
imgID, err := s.daemon.ContainerCommit(cont, containerCommitConfig)
|
imgID, err := builder.Commit(s.daemon, eng, cont, containerCommitConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -782,10 +791,15 @@ func (s *Server) postImagesCreate(eng *engine.Engine, version version.Version, w
|
||||||
imageImportConfig.Json = false
|
imageImportConfig.Json = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.daemon.Repositories().Import(src, repo, tag, imageImportConfig, eng); err != nil {
|
newConfig, err := builder.BuildFromConfig(s.daemon, eng, &runconfig.Config{}, imageImportConfig.Changes)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
imageImportConfig.ContainerConfig = newConfig
|
||||||
|
|
||||||
|
if err := s.daemon.Repositories().Import(src, repo, tag, imageImportConfig); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -977,9 +991,9 @@ func (s *Server) deleteContainers(eng *engine.Engine, version version.Version, w
|
||||||
|
|
||||||
name := vars["name"]
|
name := vars["name"]
|
||||||
config := &daemon.ContainerRmConfig{
|
config := &daemon.ContainerRmConfig{
|
||||||
ForceRemove: toBool(r.Form.Get("force")),
|
ForceRemove: boolValue(r, "force"),
|
||||||
RemoveVolume: toBool(r.Form.Get("v")),
|
RemoveVolume: boolValue(r, "v"),
|
||||||
RemoveLink: toBool(r.Form.Get("link")),
|
RemoveLink: boolValue(r, "link"),
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.daemon.ContainerRm(name, config); err != nil {
|
if err := s.daemon.ContainerRm(name, config); err != nil {
|
||||||
|
@ -1004,8 +1018,8 @@ func (s *Server) deleteImages(eng *engine.Engine, version version.Version, w htt
|
||||||
}
|
}
|
||||||
|
|
||||||
name := vars["name"]
|
name := vars["name"]
|
||||||
force := toBool(r.Form.Get("force"))
|
force := boolValue(r, "force")
|
||||||
noprune := toBool(r.Form.Get("noprune"))
|
noprune := boolValue(r, "noprune")
|
||||||
|
|
||||||
list, err := s.daemon.ImageDelete(name, force, noprune)
|
list, err := s.daemon.ImageDelete(name, force, noprune)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1152,19 +1166,19 @@ func (s *Server) postContainersAttach(eng *engine.Engine, version version.Versio
|
||||||
} else {
|
} else {
|
||||||
errStream = outStream
|
errStream = outStream
|
||||||
}
|
}
|
||||||
logs := toBool(r.Form.Get("logs"))
|
logs := boolValue(r, "logs")
|
||||||
stream := toBool(r.Form.Get("stream"))
|
stream := boolValue(r, "stream")
|
||||||
|
|
||||||
var stdin io.ReadCloser
|
var stdin io.ReadCloser
|
||||||
var stdout, stderr io.Writer
|
var stdout, stderr io.Writer
|
||||||
|
|
||||||
if toBool(r.Form.Get("stdin")) {
|
if boolValue(r, "stdin") {
|
||||||
stdin = inStream
|
stdin = inStream
|
||||||
}
|
}
|
||||||
if toBool(r.Form.Get("stdout")) {
|
if boolValue(r, "stdout") {
|
||||||
stdout = outStream
|
stdout = outStream
|
||||||
}
|
}
|
||||||
if toBool(r.Form.Get("stderr")) {
|
if boolValue(r, "stderr") {
|
||||||
stderr = errStream
|
stderr = errStream
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1246,11 +1260,9 @@ func (s *Server) postBuild(eng *engine.Engine, version version.Version, w http.R
|
||||||
authConfig = ®istry.AuthConfig{}
|
authConfig = ®istry.AuthConfig{}
|
||||||
configFileEncoded = r.Header.Get("X-Registry-Config")
|
configFileEncoded = r.Header.Get("X-Registry-Config")
|
||||||
configFile = ®istry.ConfigFile{}
|
configFile = ®istry.ConfigFile{}
|
||||||
job = builder.NewBuildConfig(eng.Logging, eng.Stderr)
|
buildConfig = builder.NewBuildConfig()
|
||||||
)
|
)
|
||||||
|
|
||||||
b := &builder.BuilderJob{eng, getDaemon(eng)}
|
|
||||||
|
|
||||||
// This block can be removed when API versions prior to 1.9 are deprecated.
|
// This block can be removed when API versions prior to 1.9 are deprecated.
|
||||||
// Both headers will be parsed and sent along to the daemon, but if a non-empty
|
// Both headers will be parsed and sent along to the daemon, but if a non-empty
|
||||||
// ConfigFile is present, any value provided as an AuthConfig directly will
|
// ConfigFile is present, any value provided as an AuthConfig directly will
|
||||||
|
@ -1273,39 +1285,41 @@ func (s *Server) postBuild(eng *engine.Engine, version version.Version, w http.R
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stdout := engine.NewOutput()
|
||||||
|
stdout.Set(utils.NewWriteFlusher(w))
|
||||||
|
|
||||||
if version.GreaterThanOrEqualTo("1.8") {
|
if version.GreaterThanOrEqualTo("1.8") {
|
||||||
job.JSONFormat = true
|
w.Header().Set("Content-Type", "application/json")
|
||||||
streamJSON(job.Stdout, w, true)
|
buildConfig.JSONFormat = true
|
||||||
} else {
|
|
||||||
job.Stdout.Add(utils.NewWriteFlusher(w))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if toBool(r.FormValue("forcerm")) && version.GreaterThanOrEqualTo("1.12") {
|
if boolValue(r, "forcerm") && version.GreaterThanOrEqualTo("1.12") {
|
||||||
job.Remove = true
|
buildConfig.Remove = true
|
||||||
} else if r.FormValue("rm") == "" && version.GreaterThanOrEqualTo("1.12") {
|
} else if r.FormValue("rm") == "" && version.GreaterThanOrEqualTo("1.12") {
|
||||||
job.Remove = true
|
buildConfig.Remove = true
|
||||||
} else {
|
} else {
|
||||||
job.Remove = toBool(r.FormValue("rm"))
|
buildConfig.Remove = boolValue(r, "rm")
|
||||||
}
|
}
|
||||||
if toBool(r.FormValue("pull")) && version.GreaterThanOrEqualTo("1.16") {
|
if boolValue(r, "pull") && version.GreaterThanOrEqualTo("1.16") {
|
||||||
job.Pull = true
|
buildConfig.Pull = true
|
||||||
}
|
}
|
||||||
job.Stdin.Add(r.Body)
|
|
||||||
|
|
||||||
// FIXME(calavera): !!!!! Remote might not be used. Solve the mistery before merging
|
buildConfig.Stdout = stdout
|
||||||
//job.Setenv("remote", r.FormValue("remote"))
|
buildConfig.Context = r.Body
|
||||||
job.DockerfileName = r.FormValue("dockerfile")
|
|
||||||
job.RepoName = r.FormValue("t")
|
buildConfig.RemoteURL = r.FormValue("remote")
|
||||||
job.SuppressOutput = toBool(r.FormValue("q"))
|
buildConfig.DockerfileName = r.FormValue("dockerfile")
|
||||||
job.NoCache = toBool(r.FormValue("nocache"))
|
buildConfig.RepoName = r.FormValue("t")
|
||||||
job.ForceRemove = toBool(r.FormValue("forcerm"))
|
buildConfig.SuppressOutput = boolValue(r, "q")
|
||||||
job.AuthConfig = authConfig
|
buildConfig.NoCache = boolValue(r, "nocache")
|
||||||
job.ConfigFile = configFile
|
buildConfig.ForceRemove = boolValue(r, "forcerm")
|
||||||
job.MemorySwap = toInt64(r.FormValue("memswap"))
|
buildConfig.AuthConfig = authConfig
|
||||||
job.Memory = toInt64(r.FormValue("memory"))
|
buildConfig.ConfigFile = configFile
|
||||||
job.CpuShares = toInt64(r.FormValue("cpushares"))
|
buildConfig.MemorySwap = int64Value(r, "memswap")
|
||||||
job.CpuSetCpus = r.FormValue("cpusetcpus")
|
buildConfig.Memory = int64Value(r, "memory")
|
||||||
job.CpuSetMems = r.FormValue("cpusetmems")
|
buildConfig.CpuShares = int64Value(r, "cpushares")
|
||||||
|
buildConfig.CpuSetCpus = r.FormValue("cpusetcpus")
|
||||||
|
buildConfig.CpuSetMems = r.FormValue("cpusetmems")
|
||||||
|
|
||||||
// Job cancellation. Note: not all job types support this.
|
// Job cancellation. Note: not all job types support this.
|
||||||
if closeNotifier, ok := w.(http.CloseNotifier); ok {
|
if closeNotifier, ok := w.(http.CloseNotifier); ok {
|
||||||
|
@ -1316,13 +1330,13 @@ func (s *Server) postBuild(eng *engine.Engine, version version.Version, w http.R
|
||||||
case <-finished:
|
case <-finished:
|
||||||
case <-closeNotifier.CloseNotify():
|
case <-closeNotifier.CloseNotify():
|
||||||
logrus.Infof("Client disconnected, cancelling job: build")
|
logrus.Infof("Client disconnected, cancelling job: build")
|
||||||
job.Cancel()
|
buildConfig.Cancel()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := b.CmdBuild(job); err != nil {
|
if err := builder.Build(s.daemon, eng, buildConfig); err != nil {
|
||||||
if !job.Stdout.Used() {
|
if !stdout.Used() {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sf := streamformatter.NewStreamFormatter(version.GreaterThanOrEqualTo("1.8"))
|
sf := streamformatter.NewStreamFormatter(version.GreaterThanOrEqualTo("1.8"))
|
||||||
|
@ -1676,17 +1690,3 @@ func allocateDaemonPort(addr string) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func toBool(s string) bool {
|
|
||||||
s = strings.ToLower(strings.TrimSpace(s))
|
|
||||||
return !(s == "" || s == "0" || s == "no" || s == "false" || s == "none")
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME(calavera): This is a copy of the Env.GetInt64
|
|
||||||
func toInt64(s string) int64 {
|
|
||||||
val, err := strconv.ParseInt(s, 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package builder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
@ -18,7 +17,6 @@ import (
|
||||||
"github.com/docker/docker/graph"
|
"github.com/docker/docker/graph"
|
||||||
"github.com/docker/docker/pkg/archive"
|
"github.com/docker/docker/pkg/archive"
|
||||||
"github.com/docker/docker/pkg/httputils"
|
"github.com/docker/docker/pkg/httputils"
|
||||||
"github.com/docker/docker/pkg/ioutils"
|
|
||||||
"github.com/docker/docker/pkg/parsers"
|
"github.com/docker/docker/pkg/parsers"
|
||||||
"github.com/docker/docker/pkg/streamformatter"
|
"github.com/docker/docker/pkg/streamformatter"
|
||||||
"github.com/docker/docker/pkg/urlutil"
|
"github.com/docker/docker/pkg/urlutil"
|
||||||
|
@ -38,11 +36,6 @@ var validCommitCommands = map[string]bool{
|
||||||
"onbuild": true,
|
"onbuild": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
type BuilderJob struct {
|
|
||||||
Engine *engine.Engine
|
|
||||||
Daemon *daemon.Daemon
|
|
||||||
}
|
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
DockerfileName string
|
DockerfileName string
|
||||||
RemoteURL string
|
RemoteURL string
|
||||||
|
@ -61,9 +54,8 @@ type Config struct {
|
||||||
AuthConfig *registry.AuthConfig
|
AuthConfig *registry.AuthConfig
|
||||||
ConfigFile *registry.ConfigFile
|
ConfigFile *registry.ConfigFile
|
||||||
|
|
||||||
Stdout *engine.Output
|
Stdout io.Writer
|
||||||
Stderr *engine.Output
|
Context io.ReadCloser
|
||||||
Stdin *engine.Input
|
|
||||||
// When closed, the job has been cancelled.
|
// When closed, the job has been cancelled.
|
||||||
// Note: not all jobs implement cancellation.
|
// Note: not all jobs implement cancellation.
|
||||||
// See Job.Cancel() and Job.WaitCancelled()
|
// See Job.Cancel() and Job.WaitCancelled()
|
||||||
|
@ -83,24 +75,15 @@ func (b *Config) WaitCancelled() <-chan struct{} {
|
||||||
return b.cancelled
|
return b.cancelled
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBuildConfig(logging bool, err io.Writer) *Config {
|
func NewBuildConfig() *Config {
|
||||||
c := &Config{
|
return &Config{
|
||||||
Stdout: engine.NewOutput(),
|
AuthConfig: ®istry.AuthConfig{},
|
||||||
Stderr: engine.NewOutput(),
|
ConfigFile: ®istry.ConfigFile{},
|
||||||
Stdin: engine.NewInput(),
|
cancelled: make(chan struct{}),
|
||||||
cancelled: make(chan struct{}),
|
|
||||||
}
|
}
|
||||||
if logging {
|
|
||||||
c.Stderr.Add(ioutils.NopWriteCloser(err))
|
|
||||||
}
|
|
||||||
return c
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BuilderJob) Install() {
|
func Build(d *daemon.Daemon, e *engine.Engine, buildConfig *Config) error {
|
||||||
b.Engine.Register("build_config", b.CmdBuildConfig)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *BuilderJob) CmdBuild(buildConfig *Config) error {
|
|
||||||
var (
|
var (
|
||||||
repoName string
|
repoName string
|
||||||
tag string
|
tag string
|
||||||
|
@ -109,7 +92,7 @@ func (b *BuilderJob) CmdBuild(buildConfig *Config) error {
|
||||||
|
|
||||||
repoName, tag = parsers.ParseRepositoryTag(buildConfig.RepoName)
|
repoName, tag = parsers.ParseRepositoryTag(buildConfig.RepoName)
|
||||||
if repoName != "" {
|
if repoName != "" {
|
||||||
if err := registry.ValidateRepositoryName(buildConfig.RepoName); err != nil {
|
if err := registry.ValidateRepositoryName(repoName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(tag) > 0 {
|
if len(tag) > 0 {
|
||||||
|
@ -120,7 +103,7 @@ func (b *BuilderJob) CmdBuild(buildConfig *Config) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if buildConfig.RemoteURL == "" {
|
if buildConfig.RemoteURL == "" {
|
||||||
context = ioutil.NopCloser(buildConfig.Stdin)
|
context = ioutil.NopCloser(buildConfig.Context)
|
||||||
} else if urlutil.IsGitURL(buildConfig.RemoteURL) {
|
} else if urlutil.IsGitURL(buildConfig.RemoteURL) {
|
||||||
if !urlutil.IsGitTransport(buildConfig.RemoteURL) {
|
if !urlutil.IsGitTransport(buildConfig.RemoteURL) {
|
||||||
buildConfig.RemoteURL = "https://" + buildConfig.RemoteURL
|
buildConfig.RemoteURL = "https://" + buildConfig.RemoteURL
|
||||||
|
@ -166,8 +149,8 @@ func (b *BuilderJob) CmdBuild(buildConfig *Config) error {
|
||||||
sf := streamformatter.NewStreamFormatter(buildConfig.JSONFormat)
|
sf := streamformatter.NewStreamFormatter(buildConfig.JSONFormat)
|
||||||
|
|
||||||
builder := &Builder{
|
builder := &Builder{
|
||||||
Daemon: b.Daemon,
|
Daemon: d,
|
||||||
Engine: b.Engine,
|
Engine: e,
|
||||||
OutStream: &streamformatter.StdoutFormater{
|
OutStream: &streamformatter.StdoutFormater{
|
||||||
Writer: buildConfig.Stdout,
|
Writer: buildConfig.Stdout,
|
||||||
StreamFormatter: sf,
|
StreamFormatter: sf,
|
||||||
|
@ -200,41 +183,28 @@ func (b *BuilderJob) CmdBuild(buildConfig *Config) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if repoName != "" {
|
if repoName != "" {
|
||||||
b.Daemon.Repositories().Tag(repoName, tag, id, true)
|
return d.Repositories().Tag(repoName, tag, id, true)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *BuilderJob) CmdBuildConfig(job *engine.Job) error {
|
func BuildFromConfig(d *daemon.Daemon, e *engine.Engine, c *runconfig.Config, changes []string) (*runconfig.Config, error) {
|
||||||
if len(job.Args) != 0 {
|
|
||||||
return fmt.Errorf("Usage: %s\n", job.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
changes = job.GetenvList("changes")
|
|
||||||
newConfig runconfig.Config
|
|
||||||
)
|
|
||||||
|
|
||||||
if err := job.GetenvJson("config", &newConfig); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
ast, err := parser.Parse(bytes.NewBufferString(strings.Join(changes, "\n")))
|
ast, err := parser.Parse(bytes.NewBufferString(strings.Join(changes, "\n")))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure that the commands are valid
|
// ensure that the commands are valid
|
||||||
for _, n := range ast.Children {
|
for _, n := range ast.Children {
|
||||||
if !validCommitCommands[n.Value] {
|
if !validCommitCommands[n.Value] {
|
||||||
return fmt.Errorf("%s is not a valid change command", n.Value)
|
return nil, fmt.Errorf("%s is not a valid change command", n.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder := &Builder{
|
builder := &Builder{
|
||||||
Daemon: b.Daemon,
|
Daemon: d,
|
||||||
Engine: b.Engine,
|
Engine: e,
|
||||||
Config: &newConfig,
|
Config: c,
|
||||||
OutStream: ioutil.Discard,
|
OutStream: ioutil.Discard,
|
||||||
ErrStream: ioutil.Discard,
|
ErrStream: ioutil.Discard,
|
||||||
disableCommit: true,
|
disableCommit: true,
|
||||||
|
@ -242,12 +212,32 @@ func (b *BuilderJob) CmdBuildConfig(job *engine.Job) error {
|
||||||
|
|
||||||
for i, n := range ast.Children {
|
for i, n := range ast.Children {
|
||||||
if err := builder.dispatch(i, n); err != nil {
|
if err := builder.dispatch(i, n); err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.NewEncoder(job.Stdout).Encode(builder.Config); err != nil {
|
return builder.Config, nil
|
||||||
return err
|
}
|
||||||
}
|
|
||||||
return nil
|
func Commit(d *daemon.Daemon, eng *engine.Engine, name string, c *daemon.ContainerCommitConfig) (string, error) {
|
||||||
|
container, err := d.Get(name)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
newConfig, err := BuildFromConfig(d, eng, c.Config, c.Changes)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := runconfig.Merge(newConfig, container.Config); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
img, err := d.Commit(container, c.Repo, c.Tag, c.Comment, c.Author, c.Pause, newConfig)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return img.ID, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
package daemon
|
package daemon
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"io"
|
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
|
||||||
"github.com/docker/docker/engine"
|
|
||||||
"github.com/docker/docker/image"
|
"github.com/docker/docker/image"
|
||||||
"github.com/docker/docker/runconfig"
|
"github.com/docker/docker/runconfig"
|
||||||
)
|
)
|
||||||
|
@ -18,49 +12,7 @@ type ContainerCommitConfig struct {
|
||||||
Author string
|
Author string
|
||||||
Comment string
|
Comment string
|
||||||
Changes []string
|
Changes []string
|
||||||
Config io.ReadCloser
|
Config *runconfig.Config
|
||||||
}
|
|
||||||
|
|
||||||
func (daemon *Daemon) ContainerCommit(name string, c *ContainerCommitConfig) (string, error) {
|
|
||||||
container, err := daemon.Get(name)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
subenv engine.Env
|
|
||||||
config = container.Config
|
|
||||||
stdoutBuffer = bytes.NewBuffer(nil)
|
|
||||||
newConfig runconfig.Config
|
|
||||||
)
|
|
||||||
|
|
||||||
if err := subenv.Decode(c.Config); err != nil {
|
|
||||||
logrus.Errorf("%s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
buildConfigJob := daemon.eng.Job("build_config")
|
|
||||||
buildConfigJob.Stdout.Add(stdoutBuffer)
|
|
||||||
buildConfigJob.SetenvList("changes", c.Changes)
|
|
||||||
// FIXME this should be remove when we remove deprecated config param
|
|
||||||
buildConfigJob.SetenvSubEnv("config", &subenv)
|
|
||||||
|
|
||||||
if err := buildConfigJob.Run(); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if err := json.NewDecoder(stdoutBuffer).Decode(&newConfig); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := runconfig.Merge(&newConfig, config); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
img, err := daemon.Commit(container, c.Repo, c.Tag, c.Comment, c.Author, c.Pause, &newConfig)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return img.ID, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit creates a new filesystem image from the current state of a container.
|
// Commit creates a new filesystem image from the current state of a container.
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
apiserver "github.com/docker/docker/api/server"
|
apiserver "github.com/docker/docker/api/server"
|
||||||
"github.com/docker/docker/autogen/dockerversion"
|
"github.com/docker/docker/autogen/dockerversion"
|
||||||
"github.com/docker/docker/builder"
|
|
||||||
"github.com/docker/docker/daemon"
|
"github.com/docker/docker/daemon"
|
||||||
_ "github.com/docker/docker/daemon/execdriver/lxc"
|
_ "github.com/docker/docker/daemon/execdriver/lxc"
|
||||||
_ "github.com/docker/docker/daemon/execdriver/native"
|
_ "github.com/docker/docker/daemon/execdriver/native"
|
||||||
|
@ -141,9 +140,6 @@ func mainDaemon() {
|
||||||
"graphdriver": d.GraphDriver().String(),
|
"graphdriver": d.GraphDriver().String(),
|
||||||
}).Info("Docker daemon")
|
}).Info("Docker daemon")
|
||||||
|
|
||||||
b := &builder.BuilderJob{eng, d}
|
|
||||||
b.Install()
|
|
||||||
|
|
||||||
// after the daemon is done setting up we can tell the api to start
|
// after the daemon is done setting up we can tell the api to start
|
||||||
// accepting connections with specified daemon
|
// accepting connections with specified daemon
|
||||||
api.AcceptConnections(d)
|
api.AcceptConnections(d)
|
||||||
|
@ -155,7 +151,6 @@ func mainDaemon() {
|
||||||
if errAPI != nil {
|
if errAPI != nil {
|
||||||
logrus.Fatalf("Shutting down due to ServeAPI error: %v", errAPI)
|
logrus.Fatalf("Shutting down due to ServeAPI error: %v", errAPI)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// currentUserIsOwner checks whether the current user is the owner of the given
|
// currentUserIsOwner checks whether the current user is the owner of the given
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
package graph
|
package graph
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/docker/docker/engine"
|
|
||||||
"github.com/docker/docker/pkg/archive"
|
"github.com/docker/docker/pkg/archive"
|
||||||
"github.com/docker/docker/pkg/httputils"
|
"github.com/docker/docker/pkg/httputils"
|
||||||
"github.com/docker/docker/pkg/progressreader"
|
"github.com/docker/docker/pkg/progressreader"
|
||||||
|
@ -17,20 +14,18 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type ImageImportConfig struct {
|
type ImageImportConfig struct {
|
||||||
Changes []string
|
Changes []string
|
||||||
InConfig io.ReadCloser
|
InConfig io.ReadCloser
|
||||||
Json bool
|
Json bool
|
||||||
OutStream io.Writer
|
OutStream io.Writer
|
||||||
//OutStream WriteFlusher
|
ContainerConfig *runconfig.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TagStore) Import(src string, repo string, tag string, imageImportConfig *ImageImportConfig, eng *engine.Engine) error {
|
func (s *TagStore) Import(src string, repo string, tag string, imageImportConfig *ImageImportConfig) error {
|
||||||
var (
|
var (
|
||||||
sf = streamformatter.NewStreamFormatter(imageImportConfig.Json)
|
sf = streamformatter.NewStreamFormatter(imageImportConfig.Json)
|
||||||
archive archive.ArchiveReader
|
archive archive.ArchiveReader
|
||||||
resp *http.Response
|
resp *http.Response
|
||||||
stdoutBuffer = bytes.NewBuffer(nil)
|
|
||||||
newConfig runconfig.Config
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if src == "-" {
|
if src == "-" {
|
||||||
|
@ -63,20 +58,7 @@ func (s *TagStore) Import(src string, repo string, tag string, imageImportConfig
|
||||||
archive = progressReader
|
archive = progressReader
|
||||||
}
|
}
|
||||||
|
|
||||||
buildConfigJob := eng.Job("build_config")
|
img, err := s.graph.Create(archive, "", "", "Imported from "+src, "", nil, imageImportConfig.ContainerConfig)
|
||||||
buildConfigJob.Stdout.Add(stdoutBuffer)
|
|
||||||
buildConfigJob.SetenvList("changes", imageImportConfig.Changes)
|
|
||||||
// FIXME this should be remove when we remove deprecated config param
|
|
||||||
//buildConfigJob.Setenv("config", job.Getenv("config"))
|
|
||||||
|
|
||||||
if err := buildConfigJob.Run(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := json.NewDecoder(stdoutBuffer).Decode(&newConfig); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
img, err := s.graph.Create(archive, "", "", "Imported from "+src, "", nil, &newConfig)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue