github.com/dougm/docker@v1.5.0/builder/job.go (about)

     1  package builder
     2  
     3  import (
     4  	"io"
     5  	"io/ioutil"
     6  	"os"
     7  	"os/exec"
     8  
     9  	"github.com/docker/docker/api"
    10  	"github.com/docker/docker/daemon"
    11  	"github.com/docker/docker/engine"
    12  	"github.com/docker/docker/graph"
    13  	"github.com/docker/docker/pkg/archive"
    14  	"github.com/docker/docker/pkg/parsers"
    15  	"github.com/docker/docker/pkg/urlutil"
    16  	"github.com/docker/docker/registry"
    17  	"github.com/docker/docker/utils"
    18  )
    19  
    20  type BuilderJob struct {
    21  	Engine *engine.Engine
    22  	Daemon *daemon.Daemon
    23  }
    24  
    25  func (b *BuilderJob) Install() {
    26  	b.Engine.Register("build", b.CmdBuild)
    27  }
    28  
    29  func (b *BuilderJob) CmdBuild(job *engine.Job) engine.Status {
    30  	if len(job.Args) != 0 {
    31  		return job.Errorf("Usage: %s\n", job.Name)
    32  	}
    33  	var (
    34  		dockerfileName = job.Getenv("dockerfile")
    35  		remoteURL      = job.Getenv("remote")
    36  		repoName       = job.Getenv("t")
    37  		suppressOutput = job.GetenvBool("q")
    38  		noCache        = job.GetenvBool("nocache")
    39  		rm             = job.GetenvBool("rm")
    40  		forceRm        = job.GetenvBool("forcerm")
    41  		pull           = job.GetenvBool("pull")
    42  		authConfig     = &registry.AuthConfig{}
    43  		configFile     = &registry.ConfigFile{}
    44  		tag            string
    45  		context        io.ReadCloser
    46  	)
    47  
    48  	job.GetenvJson("authConfig", authConfig)
    49  	job.GetenvJson("configFile", configFile)
    50  
    51  	repoName, tag = parsers.ParseRepositoryTag(repoName)
    52  	if repoName != "" {
    53  		if err := registry.ValidateRepositoryName(repoName); err != nil {
    54  			return job.Error(err)
    55  		}
    56  		if len(tag) > 0 {
    57  			if err := graph.ValidateTagName(tag); err != nil {
    58  				return job.Error(err)
    59  			}
    60  		}
    61  	}
    62  
    63  	if dockerfileName == "" {
    64  		dockerfileName = api.DefaultDockerfileName
    65  	}
    66  
    67  	if remoteURL == "" {
    68  		context = ioutil.NopCloser(job.Stdin)
    69  	} else if urlutil.IsGitURL(remoteURL) {
    70  		if !urlutil.IsGitTransport(remoteURL) {
    71  			remoteURL = "https://" + remoteURL
    72  		}
    73  		root, err := ioutil.TempDir("", "docker-build-git")
    74  		if err != nil {
    75  			return job.Error(err)
    76  		}
    77  		defer os.RemoveAll(root)
    78  
    79  		if output, err := exec.Command("git", "clone", "--recursive", remoteURL, root).CombinedOutput(); err != nil {
    80  			return job.Errorf("Error trying to use git: %s (%s)", err, output)
    81  		}
    82  
    83  		c, err := archive.Tar(root, archive.Uncompressed)
    84  		if err != nil {
    85  			return job.Error(err)
    86  		}
    87  		context = c
    88  	} else if urlutil.IsURL(remoteURL) {
    89  		f, err := utils.Download(remoteURL)
    90  		if err != nil {
    91  			return job.Error(err)
    92  		}
    93  		defer f.Body.Close()
    94  		dockerFile, err := ioutil.ReadAll(f.Body)
    95  		if err != nil {
    96  			return job.Error(err)
    97  		}
    98  		c, err := archive.Generate(dockerfileName, string(dockerFile))
    99  		if err != nil {
   100  			return job.Error(err)
   101  		}
   102  		context = c
   103  	}
   104  	defer context.Close()
   105  
   106  	sf := utils.NewStreamFormatter(job.GetenvBool("json"))
   107  
   108  	builder := &Builder{
   109  		Daemon: b.Daemon,
   110  		Engine: b.Engine,
   111  		OutStream: &utils.StdoutFormater{
   112  			Writer:          job.Stdout,
   113  			StreamFormatter: sf,
   114  		},
   115  		ErrStream: &utils.StderrFormater{
   116  			Writer:          job.Stdout,
   117  			StreamFormatter: sf,
   118  		},
   119  		Verbose:         !suppressOutput,
   120  		UtilizeCache:    !noCache,
   121  		Remove:          rm,
   122  		ForceRemove:     forceRm,
   123  		Pull:            pull,
   124  		OutOld:          job.Stdout,
   125  		StreamFormatter: sf,
   126  		AuthConfig:      authConfig,
   127  		AuthConfigFile:  configFile,
   128  		dockerfileName:  dockerfileName,
   129  	}
   130  
   131  	id, err := builder.Run(context)
   132  	if err != nil {
   133  		return job.Error(err)
   134  	}
   135  
   136  	if repoName != "" {
   137  		b.Daemon.Repositories().Set(repoName, tag, id, true)
   138  	}
   139  	return engine.StatusOK
   140  }