// BuildImage builds an image func (c *Cluster) BuildImage(buildContext io.Reader, buildImage *types.ImageBuildOptions, out io.Writer) error { c.scheduler.Lock() // get an engine config := cluster.BuildContainerConfig(containertypes.Config{Env: convertMapToKVStrings(buildImage.BuildArgs)}, containertypes.HostConfig{Resources: containertypes.Resources{CPUShares: buildImage.CPUShares, Memory: buildImage.Memory}}, networktypes.NetworkingConfig{}) buildImage.BuildArgs = convertKVStringsToMap(config.Env) nodes, err := c.scheduler.SelectNodesForContainer(c.listNodes(), config) c.scheduler.Unlock() if err != nil { return err } n := nodes[0] reader, err := c.engines[n.ID].BuildImage(buildContext, buildImage) if err != nil { return err } if _, err := io.Copy(out, reader); err != nil { return err } c.engines[n.ID].RefreshImages() return nil }
// NewBuilder creates a new Dockerfile builder from an optional dockerfile and a Config. // If dockerfile is nil, the Dockerfile specified by Config.DockerfileName, // will be read from the Context passed to Build(). func NewBuilder(clientCtx context.Context, config *types.ImageBuildOptions, backend builder.Backend, buildContext builder.Context, dockerfile io.ReadCloser) (b *Builder, err error) { if config == nil { config = new(types.ImageBuildOptions) } if config.BuildArgs == nil { config.BuildArgs = make(map[string]string) } ctx, cancel := context.WithCancel(clientCtx) b = &Builder{ clientCtx: ctx, cancel: cancel, options: config, Stdout: os.Stdout, Stderr: os.Stderr, docker: backend, context: buildContext, runConfig: new(container.Config), tmpContainers: map[string]struct{}{}, id: stringid.GenerateNonCryptoID(), allowedBuildArgs: make(map[string]bool), } if dockerfile != nil { b.dockerfile, err = parser.Parse(dockerfile) if err != nil { return nil, err } } return b, nil }
// BuildImage build an image func (c *Cluster) BuildImage(buildImage *types.ImageBuildOptions, out io.Writer) error { c.scheduler.Lock() // get an engine config := cluster.BuildContainerConfig(dockerclient.ContainerConfig{ CpuShares: buildImage.CPUShares, Memory: buildImage.Memory, Env: convertMapToKVStrings(buildImage.BuildArgs), }) buildImage.BuildArgs = convertKVStringsToMap(config.Env) nodes, err := c.scheduler.SelectNodesForContainer(c.listNodes(), config) c.scheduler.Unlock() if err != nil { return err } n := nodes[0] reader, err := c.engines[n.ID].BuildImage(buildImage) if err != nil { return err } if _, err := io.Copy(out, reader); err != nil { return err } c.engines[n.ID].RefreshImages() return nil }
// BuildImage builds the image according to specified options func (d *stiDocker) BuildImage(opts BuildImageOptions) error { dockerOpts := dockertypes.ImageBuildOptions{ Tags: []string{opts.Name}, NoCache: true, SuppressOutput: false, Remove: true, ForceRemove: true, } if opts.CGroupLimits != nil { dockerOpts.Memory = opts.CGroupLimits.MemoryLimitBytes dockerOpts.MemorySwap = opts.CGroupLimits.MemorySwap dockerOpts.CPUShares = opts.CGroupLimits.CPUShares dockerOpts.CPUPeriod = opts.CGroupLimits.CPUPeriod dockerOpts.CPUQuota = opts.CGroupLimits.CPUQuota } glog.V(2).Infof("Building container using config: %+v", dockerOpts) resp, err := d.client.ImageBuild(context.Background(), opts.Stdin, dockerOpts) if err != nil { return err } defer resp.Body.Close() // since can't pass in output stream to engine-api, need to copy contents of // the output stream they create into our output stream _, err = io.Copy(opts.Stdout, resp.Body) return err }
// BuildImage builds the image according to specified options func (d *stiDocker) BuildImage(opts BuildImageOptions) error { dockerOpts := dockertypes.ImageBuildOptions{ Tags: []string{opts.Name}, NoCache: true, SuppressOutput: false, Remove: true, ForceRemove: true, } if opts.CGroupLimits != nil { dockerOpts.Memory = opts.CGroupLimits.MemoryLimitBytes dockerOpts.MemorySwap = opts.CGroupLimits.MemorySwap dockerOpts.CPUShares = opts.CGroupLimits.CPUShares dockerOpts.CPUPeriod = opts.CGroupLimits.CPUPeriod dockerOpts.CPUQuota = opts.CGroupLimits.CPUQuota } glog.V(2).Infof("Building container using config: %+v", dockerOpts) ctx, cancel := getDefaultContext(((1<<63 - 1) * time.Nanosecond)) // infinite duration ... go does not expost max duration constant defer cancel() resp, err := d.client.ImageBuild(ctx, opts.Stdin, dockerOpts) if err != nil { return err } defer resp.Body.Close() // since can't pass in output stream to engine-api, need to copy contents of // the output stream they create into our output stream _, err = io.Copy(opts.Stdout, resp.Body) return err }
// BuildFromContext builds a new image from a given context. func (bm *BuildManager) BuildFromContext(ctx context.Context, src io.ReadCloser, remote string, buildOptions *types.ImageBuildOptions, pg backend.ProgressWriter) (string, error) { buildContext, dockerfileName, err := builder.DetectContextFromRemoteURL(src, remote, pg.ProgressReaderFunc) if err != nil { return "", err } defer func() { if err := buildContext.Close(); err != nil { logrus.Debugf("[BUILDER] failed to remove temporary context: %v", err) } }() if len(dockerfileName) > 0 { buildOptions.Dockerfile = dockerfileName } b, err := NewBuilder(ctx, buildOptions, bm.backend, builder.DockerIgnoreContext{ModifiableContext: buildContext}, nil) if err != nil { return "", err } return b.build(pg.StdoutFormatter, pg.StderrFormatter, pg.Output) }
// NewBuilder creates a new Dockerfile builder from an optional dockerfile and a Config. // If dockerfile is nil, the Dockerfile specified by Config.DockerfileName, // will be read from the Context passed to Build(). func NewBuilder(clientCtx context.Context, config *types.ImageBuildOptions, backend builder.Backend, buildContext builder.Context, dockerfile io.ReadCloser) (b *Builder, err error) { if config == nil { config = new(types.ImageBuildOptions) } if config.BuildArgs == nil { config.BuildArgs = make(map[string]string) } ctx, cancel := context.WithCancel(clientCtx) b = &Builder{ clientCtx: ctx, cancel: cancel, options: config, Stdout: os.Stdout, Stderr: os.Stderr, docker: backend, context: buildContext, runConfig: new(container.Config), tmpContainers: map[string]struct{}{}, id: stringid.GenerateNonCryptoID(), allowedBuildArgs: make(map[string]bool), directive: parser.Directive{ EscapeSeen: false, LookingForDirectives: true, }, } parser.SetEscapeToken(parser.DefaultEscapeToken, &b.directive) // Assume the default token for escape if dockerfile != nil { b.dockerfile, err = parser.Parse(dockerfile, &b.directive) if err != nil { return nil, err } } return b, nil }