1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #18977 from anusha-ragunathan/builder

Use ImageBuildOptions in builder.
This commit is contained in:
David Calavera 2016-01-05 11:54:21 -08:00
commit acfd5eb947
14 changed files with 147 additions and 178 deletions

View file

@ -16,6 +16,7 @@ import (
"github.com/docker/docker/api"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/builder/dockerignore"
Cli "github.com/docker/docker/cli"
"github.com/docker/docker/opts"
@ -207,6 +208,14 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
}
}
var shmSize int64
if *flShmSize != "" {
shmSize, err = units.RAMInBytes(*flShmSize)
if err != nil {
return err
}
}
var remoteContext string
if isRemote {
remoteContext = cmd.Arg(0)
@ -223,17 +232,17 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
Remove: *rm,
ForceRemove: *forceRm,
PullParent: *pull,
Isolation: *isolation,
IsolationLevel: container.IsolationLevel(*isolation),
CPUSetCPUs: *flCPUSetCpus,
CPUSetMems: *flCPUSetMems,
CPUShares: *flCPUShares,
CPUQuota: *flCPUQuota,
CPUPeriod: *flCPUPeriod,
CgroupParent: *flCgroupParent,
ShmSize: *flShmSize,
Dockerfile: relDockerfile,
ShmSize: shmSize,
Ulimits: flUlimits.GetList(),
BuildArgs: flBuildArg.GetAll(),
BuildArgs: runconfigopts.ConvertKVStringsToMap(flBuildArg.GetAll()),
AuthConfigs: cli.configFile.AuthConfigs,
}

View file

@ -11,7 +11,6 @@ import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/go-units"
)
var headerRegexp = regexp.MustCompile(`\ADocker/.+\s\((.+)\)\z`)
@ -73,8 +72,8 @@ func imageBuildOptionsToQuery(options types.ImageBuildOptions) (url.Values, erro
query.Set("pull", "1")
}
if !container.IsolationLevel.IsDefault(container.IsolationLevel(options.Isolation)) {
query.Set("isolation", options.Isolation)
if !container.IsolationLevel.IsDefault(options.IsolationLevel) {
query.Set("isolation", string(options.IsolationLevel))
}
query.Set("cpusetcpus", options.CPUSetCPUs)
@ -85,15 +84,7 @@ func imageBuildOptionsToQuery(options types.ImageBuildOptions) (url.Values, erro
query.Set("memory", strconv.FormatInt(options.Memory, 10))
query.Set("memswap", strconv.FormatInt(options.MemorySwap, 10))
query.Set("cgroupparent", options.CgroupParent)
if options.ShmSize != "" {
parsedShmSize, err := units.RAMInBytes(options.ShmSize)
if err != nil {
return query, err
}
query.Set("shmsize", strconv.FormatInt(parsedShmSize, 10))
}
query.Set("shmsize", strconv.FormatInt(options.ShmSize, 10))
query.Set("dockerfile", options.Dockerfile)
ulimitsJSON, err := json.Marshal(options.Ulimits)
@ -102,8 +93,7 @@ func imageBuildOptionsToQuery(options types.ImageBuildOptions) (url.Values, erro
}
query.Set("ulimits", string(ulimitsJSON))
buildArgs := convertKVStringsToMap(options.BuildArgs)
buildArgsJSON, err := json.Marshal(buildArgs)
buildArgsJSON, err := json.Marshal(options.BuildArgs)
if err != nil {
return query, err
}

View file

@ -68,11 +68,72 @@ func sanitizeRepoAndTags(names []string) ([]reference.Named, error) {
return repoAndTags, nil
}
func newImageBuildOptions(ctx context.Context, r *http.Request) (*types.ImageBuildOptions, error) {
version := httputils.VersionFromContext(ctx)
options := &types.ImageBuildOptions{}
if httputils.BoolValue(r, "forcerm") && version.GreaterThanOrEqualTo("1.12") {
options.Remove = true
} else if r.FormValue("rm") == "" && version.GreaterThanOrEqualTo("1.12") {
options.Remove = true
} else {
options.Remove = httputils.BoolValue(r, "rm")
}
if httputils.BoolValue(r, "pull") && version.GreaterThanOrEqualTo("1.16") {
options.PullParent = true
}
options.Dockerfile = r.FormValue("dockerfile")
options.SuppressOutput = httputils.BoolValue(r, "q")
options.NoCache = httputils.BoolValue(r, "nocache")
options.ForceRemove = httputils.BoolValue(r, "forcerm")
options.MemorySwap = httputils.Int64ValueOrZero(r, "memswap")
options.Memory = httputils.Int64ValueOrZero(r, "memory")
options.CPUShares = httputils.Int64ValueOrZero(r, "cpushares")
options.CPUPeriod = httputils.Int64ValueOrZero(r, "cpuperiod")
options.CPUQuota = httputils.Int64ValueOrZero(r, "cpuquota")
options.CPUSetCPUs = r.FormValue("cpusetcpus")
options.CPUSetMems = r.FormValue("cpusetmems")
options.CgroupParent = r.FormValue("cgroupparent")
if r.Form.Get("shmsize") != "" {
shmSize, err := strconv.ParseInt(r.Form.Get("shmsize"), 10, 64)
if err != nil {
return nil, err
}
options.ShmSize = shmSize
}
if i := container.IsolationLevel(r.FormValue("isolation")); i != "" {
if !container.IsolationLevel.IsValid(i) {
return nil, fmt.Errorf("Unsupported isolation: %q", i)
}
options.IsolationLevel = i
}
var buildUlimits = []*units.Ulimit{}
ulimitsJSON := r.FormValue("ulimits")
if ulimitsJSON != "" {
if err := json.NewDecoder(strings.NewReader(ulimitsJSON)).Decode(&buildUlimits); err != nil {
return nil, err
}
options.Ulimits = buildUlimits
}
var buildArgs = map[string]string{}
buildArgsJSON := r.FormValue("buildargs")
if buildArgsJSON != "" {
if err := json.NewDecoder(strings.NewReader(buildArgsJSON)).Decode(&buildArgs); err != nil {
return nil, err
}
options.BuildArgs = buildArgs
}
return options, nil
}
func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
var (
authConfigs = map[string]types.AuthConfig{}
authConfigsEncoded = r.Header.Get("X-Registry-Config")
buildConfig = &dockerfile.Config{}
notVerboseBuffer = bytes.NewBuffer(nil)
)
@ -87,12 +148,11 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
w.Header().Set("Content-Type", "application/json")
version := httputils.VersionFromContext(ctx)
output := ioutils.NewWriteFlusher(w)
defer output.Close()
sf := streamformatter.NewJSONStreamFormatter()
errf := func(err error) error {
if !buildConfig.Verbose && notVerboseBuffer.Len() > 0 {
if httputils.BoolValue(r, "q") && notVerboseBuffer.Len() > 0 {
output.Write(notVerboseBuffer.Bytes())
}
// Do not write the error in the http output if it's still empty.
@ -107,15 +167,9 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
return nil
}
if httputils.BoolValue(r, "forcerm") && version.GreaterThanOrEqualTo("1.12") {
buildConfig.Remove = true
} else if r.FormValue("rm") == "" && version.GreaterThanOrEqualTo("1.12") {
buildConfig.Remove = true
} else {
buildConfig.Remove = httputils.BoolValue(r, "rm")
}
if httputils.BoolValue(r, "pull") && version.GreaterThanOrEqualTo("1.16") {
buildConfig.Pull = true
buildOptions, err := newImageBuildOptions(ctx, r)
if err != nil {
return errf(err)
}
repoAndTags, err := sanitizeRepoAndTags(r.Form["t"])
@ -123,59 +177,13 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
return errf(err)
}
buildConfig.DockerfileName = r.FormValue("dockerfile")
buildConfig.Verbose = !httputils.BoolValue(r, "q")
buildConfig.UseCache = !httputils.BoolValue(r, "nocache")
buildConfig.ForceRemove = httputils.BoolValue(r, "forcerm")
buildConfig.MemorySwap = httputils.Int64ValueOrZero(r, "memswap")
buildConfig.Memory = httputils.Int64ValueOrZero(r, "memory")
buildConfig.CPUShares = httputils.Int64ValueOrZero(r, "cpushares")
buildConfig.CPUPeriod = httputils.Int64ValueOrZero(r, "cpuperiod")
buildConfig.CPUQuota = httputils.Int64ValueOrZero(r, "cpuquota")
buildConfig.CPUSetCpus = r.FormValue("cpusetcpus")
buildConfig.CPUSetMems = r.FormValue("cpusetmems")
buildConfig.CgroupParent = r.FormValue("cgroupparent")
if r.Form.Get("shmsize") != "" {
shmSize, err := strconv.ParseInt(r.Form.Get("shmsize"), 10, 64)
if err != nil {
return errf(err)
}
buildConfig.ShmSize = &shmSize
}
if i := container.IsolationLevel(r.FormValue("isolation")); i != "" {
if !container.IsolationLevel.IsValid(i) {
return errf(fmt.Errorf("Unsupported isolation: %q", i))
}
buildConfig.Isolation = i
}
var buildUlimits = []*units.Ulimit{}
ulimitsJSON := r.FormValue("ulimits")
if ulimitsJSON != "" {
if err := json.NewDecoder(strings.NewReader(ulimitsJSON)).Decode(&buildUlimits); err != nil {
return errf(err)
}
buildConfig.Ulimits = buildUlimits
}
var buildArgs = map[string]string{}
buildArgsJSON := r.FormValue("buildargs")
if buildArgsJSON != "" {
if err := json.NewDecoder(strings.NewReader(buildArgsJSON)).Decode(&buildArgs); err != nil {
return errf(err)
}
buildConfig.BuildArgs = buildArgs
}
remoteURL := r.FormValue("remote")
// Currently, only used if context is from a remote url.
// Look at code in DetectContextFromRemoteURL for more information.
createProgressReader := func(in io.ReadCloser) io.ReadCloser {
progressOutput := sf.NewProgressOutput(output, true)
if !buildConfig.Verbose {
if buildOptions.SuppressOutput {
progressOutput = sf.NewProgressOutput(notVerboseBuffer, true)
}
return progress.NewProgressReader(in, progressOutput, r.ContentLength, "Downloading context", remoteURL)
@ -194,6 +202,9 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
logrus.Debugf("[BUILDER] failed to remove temporary context: %v", err)
}
}()
if len(dockerfileName) > 0 {
buildOptions.Dockerfile = dockerfileName
}
uidMaps, gidMaps := br.backend.GetUIDGIDMaps()
defaultArchiver := &archive.Archiver{
@ -201,23 +212,28 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
UIDMaps: uidMaps,
GIDMaps: gidMaps,
}
docker := &daemonbuilder.Docker{
Daemon: br.backend,
OutOld: output,
AuthConfigs: authConfigs,
Archiver: defaultArchiver,
}
if !buildConfig.Verbose {
if buildOptions.SuppressOutput {
docker.OutOld = notVerboseBuffer
}
b, err := dockerfile.NewBuilder(buildConfig, docker, builder.DockerIgnoreContext{ModifiableContext: context}, nil)
b, err := dockerfile.NewBuilder(
buildOptions, // result of newBuildConfig
docker,
builder.DockerIgnoreContext{ModifiableContext: context},
nil)
if err != nil {
return errf(err)
}
b.Stdout = &streamformatter.StdoutFormatter{Writer: output, StreamFormatter: sf}
b.Stderr = &streamformatter.StderrFormatter{Writer: output, StreamFormatter: sf}
if !buildConfig.Verbose {
if buildOptions.SuppressOutput {
b.Stdout = &streamformatter.StdoutFormatter{Writer: notVerboseBuffer, StreamFormatter: sf}
b.Stderr = &streamformatter.StderrFormatter{Writer: notVerboseBuffer, StreamFormatter: sf}
}
@ -235,10 +251,6 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
}()
}
if len(dockerfileName) > 0 {
b.DockerfileName = dockerfileName
}
imgID, err := b.Build()
if err != nil {
return errf(err)
@ -252,7 +264,7 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
// Everything worked so if -q was provided the output from the daemon
// should be just the image ID and we'll print that to stdout.
if !buildConfig.Verbose {
if buildOptions.SuppressOutput {
stdout := &streamformatter.StdoutFormatter{Writer: output, StreamFormatter: sf}
fmt.Fprintf(stdout, "%s\n", string(imgID))
}

View file

@ -127,7 +127,7 @@ type ImageBuildOptions struct {
Remove bool
ForceRemove bool
PullParent bool
Isolation string
IsolationLevel container.IsolationLevel
CPUSetCPUs string
CPUSetMems string
CPUShares int64
@ -136,10 +136,10 @@ type ImageBuildOptions struct {
Memory int64
MemorySwap int64
CgroupParent string
ShmSize string
ShmSize int64
Dockerfile string
Ulimits []*units.Ulimit
BuildArgs []string
BuildArgs map[string]string
AuthConfigs map[string]AuthConfig
Context io.Reader
}

View file

@ -216,7 +216,7 @@ type HostConfig struct {
SecurityOpt []string // List of string values to customize labels for MLS systems, such as SELinux.
Tmpfs map[string]string `json:",omitempty"` // List of tmpfs (mounts) used for the container
UTSMode UTSMode // UTS namespace to use for the container
ShmSize *int64 // Total shm memory usage
ShmSize int64 // Total shm memory usage
// Applicable to Windows
ConsoleSize [2]int // Initial console size

View file

@ -10,11 +10,11 @@ import (
"sync"
"github.com/Sirupsen/logrus"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/builder"
"github.com/docker/docker/builder/dockerfile/parser"
"github.com/docker/docker/pkg/stringid"
"github.com/docker/go-units"
)
var validCommitCommands = map[string]bool{
@ -41,38 +41,10 @@ var BuiltinAllowedBuildArgs = map[string]bool{
"no_proxy": true,
}
// Config constitutes the configuration for a Dockerfile builder.
type Config struct {
// only used if Dockerfile has to be extracted from Context
DockerfileName string
Verbose bool
UseCache bool
Remove bool
ForceRemove bool
Pull bool
BuildArgs map[string]string // build-time args received in build context for expansion/substitution and commands in 'run'.
Isolation container.IsolationLevel
// resource constraints
// TODO: factor out to be reused with Run ?
Memory int64
MemorySwap int64
ShmSize *int64
CPUShares int64
CPUPeriod int64
CPUQuota int64
CPUSetCpus string
CPUSetMems string
CgroupParent string
Ulimits []*units.Ulimit
}
// Builder is a Dockerfile builder
// It implements the builder.Backend interface.
type Builder struct {
*Config
options *types.ImageBuildOptions
Stdout io.Writer
Stderr io.Writer
@ -101,18 +73,18 @@ type Builder struct {
// 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(config *Config, docker builder.Backend, context builder.Context, dockerfile io.ReadCloser) (b *Builder, err error) {
func NewBuilder(config *types.ImageBuildOptions, backend builder.Backend, context builder.Context, dockerfile io.ReadCloser) (b *Builder, err error) {
if config == nil {
config = new(Config)
config = new(types.ImageBuildOptions)
}
if config.BuildArgs == nil {
config.BuildArgs = make(map[string]string)
}
b = &Builder{
Config: config,
options: config,
Stdout: os.Stdout,
Stderr: os.Stderr,
docker: docker,
docker: backend,
context: context,
runConfig: new(container.Config),
tmpContainers: map[string]struct{}{},
@ -162,14 +134,14 @@ func (b *Builder) Build() (string, error) {
// Not cancelled yet, keep going...
}
if err := b.dispatch(i, n); err != nil {
if b.ForceRemove {
if b.options.ForceRemove {
b.clearTmp()
}
return "", err
}
shortImgID = stringid.TruncateID(b.image)
fmt.Fprintf(b.Stdout, " ---> %s\n", shortImgID)
if b.Remove {
if b.options.Remove {
b.clearTmp()
}
}
@ -177,7 +149,7 @@ func (b *Builder) Build() (string, error) {
// check if there are any leftover build-args that were passed but not
// consumed during build. Return an error, if there are any.
leftoverArgs := []string{}
for arg := range b.BuildArgs {
for arg := range b.options.BuildArgs {
if !b.isBuildArgAllowed(arg) {
leftoverArgs = append(leftoverArgs, arg)
}

View file

@ -209,7 +209,7 @@ func from(b *Builder, args []string, attributes map[string]bool, original string
err error
)
// TODO: don't use `name`, instead resolve it to a digest
if !b.Pull {
if !b.options.PullParent {
image, err = b.docker.GetImage(name)
// TODO: shouldn't we error out if error is different from "not found" ?
}
@ -339,7 +339,7 @@ func run(b *Builder, args []string, attributes map[string]bool, original string)
// lookup for same image built with same build time environment.
cmdBuildEnv := []string{}
configEnv := runconfigopts.ConvertKVStringsToMap(b.runConfig.Env)
for key, val := range b.BuildArgs {
for key, val := range b.options.BuildArgs {
if !b.isBuildArgAllowed(key) {
// skip build-args that are not in allowed list, meaning they have
// not been defined by an "ARG" Dockerfile command yet.
@ -622,8 +622,8 @@ func arg(b *Builder, args []string, attributes map[string]bool, original string)
// If there is a default value associated with this arg then add it to the
// b.buildArgs if one is not already passed to the builder. The args passed
// to builder override the default value of 'arg'.
if _, ok := b.BuildArgs[name]; !ok && hasDefault {
b.BuildArgs[name] = value
if _, ok := b.options.BuildArgs[name]; !ok && hasDefault {
b.options.BuildArgs[name] = value
}
return b.commit("", b.runConfig.Cmd, fmt.Sprintf("ARG %s", arg))

View file

@ -148,7 +148,7 @@ func (b *Builder) dispatch(stepN int, ast *parser.Node) error {
// a subsequent one. So, putting the buildArgs list after the Config.Env
// list, in 'envs', is safe.
envs := b.runConfig.Env
for key, val := range b.BuildArgs {
for key, val := range b.options.BuildArgs {
if !b.isBuildArgAllowed(key) {
// skip build-args that are not in allowed list, meaning they have
// not been defined by an "ARG" Dockerfile command yet.

View file

@ -450,7 +450,7 @@ func (b *Builder) processImageFrom(img builder.Image) error {
// If there is any error, it returns `(false, err)`.
func (b *Builder) probeCache() (bool, error) {
c, ok := b.docker.(builder.ImageCache)
if !ok || !b.UseCache || b.cacheBusted {
if !ok || b.options.NoCache || b.cacheBusted {
return false, nil
}
cache, err := c.GetCachedImage(b.image, b.runConfig)
@ -477,21 +477,21 @@ func (b *Builder) create() (string, error) {
b.runConfig.Image = b.image
resources := container.Resources{
CgroupParent: b.CgroupParent,
CPUShares: b.CPUShares,
CPUPeriod: b.CPUPeriod,
CPUQuota: b.CPUQuota,
CpusetCpus: b.CPUSetCpus,
CpusetMems: b.CPUSetMems,
Memory: b.Memory,
MemorySwap: b.MemorySwap,
Ulimits: b.Ulimits,
CgroupParent: b.options.CgroupParent,
CPUShares: b.options.CPUShares,
CPUPeriod: b.options.CPUPeriod,
CPUQuota: b.options.CPUQuota,
CpusetCpus: b.options.CPUSetCPUs,
CpusetMems: b.options.CPUSetMems,
Memory: b.options.Memory,
MemorySwap: b.options.MemorySwap,
Ulimits: b.options.Ulimits,
}
// TODO: why not embed a hostconfig in builder?
hostConfig := &container.HostConfig{
Isolation: b.Isolation,
ShmSize: b.ShmSize,
Isolation: b.options.IsolationLevel,
ShmSize: b.options.ShmSize,
Resources: resources,
}
@ -587,20 +587,20 @@ func (b *Builder) readDockerfile() error {
// If no -f was specified then look for 'Dockerfile'. If we can't find
// that then look for 'dockerfile'. If neither are found then default
// back to 'Dockerfile' and use that in the error message.
if b.DockerfileName == "" {
b.DockerfileName = api.DefaultDockerfileName
if _, _, err := b.context.Stat(b.DockerfileName); os.IsNotExist(err) {
lowercase := strings.ToLower(b.DockerfileName)
if b.options.Dockerfile == "" {
b.options.Dockerfile = api.DefaultDockerfileName
if _, _, err := b.context.Stat(b.options.Dockerfile); os.IsNotExist(err) {
lowercase := strings.ToLower(b.options.Dockerfile)
if _, _, err := b.context.Stat(lowercase); err == nil {
b.DockerfileName = lowercase
b.options.Dockerfile = lowercase
}
}
}
f, err := b.context.Open(b.DockerfileName)
f, err := b.context.Open(b.options.Dockerfile)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("Cannot locate specified Dockerfile: %s", b.DockerfileName)
return fmt.Errorf("Cannot locate specified Dockerfile: %s", b.options.Dockerfile)
}
return err
}
@ -611,7 +611,7 @@ func (b *Builder) readDockerfile() error {
return fmt.Errorf("Unexpected error reading Dockerfile: %v", err)
}
if fi.Size() == 0 {
return fmt.Errorf("The Dockerfile (%s) cannot be empty", b.DockerfileName)
return fmt.Errorf("The Dockerfile (%s) cannot be empty", b.options.Dockerfile)
}
}
b.dockerfile, err = parser.Parse(f)
@ -629,7 +629,7 @@ func (b *Builder) readDockerfile() error {
// Note that this assumes the Dockerfile has been read into memory and
// is now safe to be removed.
if dockerIgnore, ok := b.context.(builder.DockerIgnoreContext); ok {
dockerIgnore.Process([]string{b.DockerfileName})
dockerIgnore.Process([]string{b.options.Dockerfile})
}
return nil
}

View file

@ -899,8 +899,8 @@ func (daemon *Daemon) setupIpcDirs(c *container.Container) error {
}
shmSize := container.DefaultSHMSize
if c.HostConfig.ShmSize != nil {
shmSize = *c.HostConfig.ShmSize
if c.HostConfig.ShmSize != 0 {
shmSize = c.HostConfig.ShmSize
}
shmproperty := "mode=1777,size=" + strconv.FormatInt(shmSize, 10)
if err := syscall.Mount("shm", shmPath, "tmpfs", uintptr(syscall.MS_NOEXEC|syscall.MS_NOSUID|syscall.MS_NODEV), label.FormatMountLabel(shmproperty, c.GetMountLabel())); err != nil {

View file

@ -191,9 +191,8 @@ func (daemon *Daemon) adaptContainerSettings(hostConfig *containertypes.HostConf
// By default, MemorySwap is set to twice the size of Memory.
hostConfig.MemorySwap = hostConfig.Memory * 2
}
if hostConfig.ShmSize == nil {
shmSize := container.DefaultSHMSize
hostConfig.ShmSize = &shmSize
if hostConfig.ShmSize == 0 {
hostConfig.ShmSize = container.DefaultSHMSize
}
var err error
if hostConfig.SecurityOpt == nil {
@ -365,7 +364,7 @@ func verifyPlatformContainerSettings(daemon *Daemon, hostConfig *containertypes.
}
warnings = append(warnings, w...)
if hostConfig.ShmSize != nil && *hostConfig.ShmSize <= 0 {
if hostConfig.ShmSize < 0 {
return warnings, fmt.Errorf("SHM size must be greater then 0")
}

View file

@ -1403,18 +1403,6 @@ func (s *DockerSuite) TestPostContainersCreateShmSizeNegative(c *check.C) {
c.Assert(string(body), checker.Contains, "SHM size must be greater then 0")
}
func (s *DockerSuite) TestPostContainersCreateShmSizeZero(c *check.C) {
config := map[string]interface{}{
"Image": "busybox",
"HostConfig": map[string]interface{}{"ShmSize": 0},
}
status, body, err := sockRequest("POST", "/containers/create", config)
c.Assert(err, check.IsNil)
c.Assert(status, check.Equals, http.StatusInternalServerError)
c.Assert(string(body), checker.Contains, "SHM size must be greater then 0")
}
func (s *DockerSuite) TestPostContainersCreateShmSizeHostConfigOmitted(c *check.C) {
var defaultSHMSize int64 = 67108864
config := map[string]interface{}{
@ -1436,7 +1424,7 @@ func (s *DockerSuite) TestPostContainersCreateShmSizeHostConfigOmitted(c *check.
var containerJSON types.ContainerJSON
c.Assert(json.Unmarshal(body, &containerJSON), check.IsNil)
c.Assert(*containerJSON.HostConfig.ShmSize, check.Equals, defaultSHMSize)
c.Assert(containerJSON.HostConfig.ShmSize, check.Equals, defaultSHMSize)
out, _ := dockerCmd(c, "start", "-i", containerJSON.ID)
shmRegexp := regexp.MustCompile(`shm on /dev/shm type tmpfs(.*)size=65536k`)
@ -1466,7 +1454,7 @@ func (s *DockerSuite) TestPostContainersCreateShmSizeOmitted(c *check.C) {
var containerJSON types.ContainerJSON
c.Assert(json.Unmarshal(body, &containerJSON), check.IsNil)
c.Assert(*containerJSON.HostConfig.ShmSize, check.Equals, int64(67108864))
c.Assert(containerJSON.HostConfig.ShmSize, check.Equals, int64(67108864))
out, _ := dockerCmd(c, "start", "-i", containerJSON.ID)
shmRegexp := regexp.MustCompile(`shm on /dev/shm type tmpfs(.*)size=65536k`)
@ -1496,7 +1484,7 @@ func (s *DockerSuite) TestPostContainersCreateWithShmSize(c *check.C) {
var containerJSON types.ContainerJSON
c.Assert(json.Unmarshal(body, &containerJSON), check.IsNil)
c.Assert(*containerJSON.HostConfig.ShmSize, check.Equals, int64(1073741824))
c.Assert(containerJSON.HostConfig.ShmSize, check.Equals, int64(1073741824))
out, _ := dockerCmd(c, "start", "-i", containerJSON.ID)
shmRegex := regexp.MustCompile(`shm on /dev/shm type tmpfs(.*)size=1048576k`)

View file

@ -186,13 +186,12 @@ func Parse(cmd *flag.FlagSet, args []string) (*container.Config, *container.Host
return nil, nil, cmd, fmt.Errorf("Invalid value: %d. Valid memory swappiness range is 0-100", swappiness)
}
var parsedShm *int64
var shmSize int64
if *flShmSize != "" {
shmSize, err := units.RAMInBytes(*flShmSize)
shmSize, err = units.RAMInBytes(*flShmSize)
if err != nil {
return nil, nil, cmd, err
}
parsedShm = &shmSize
}
var binds []string
@ -397,7 +396,7 @@ func Parse(cmd *flag.FlagSet, args []string) (*container.Config, *container.Host
LogConfig: container.LogConfig{Type: *flLoggingDriver, Config: loggingOpts},
VolumeDriver: *flVolumeDriver,
Isolation: container.IsolationLevel(*flIsolation),
ShmSize: parsedShm,
ShmSize: shmSize,
Resources: resources,
Tmpfs: tmpfs,
}

View file

@ -535,8 +535,8 @@ func TestParseModes(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if *hostconfig.ShmSize != 134217728 {
t.Fatalf("Expected a valid ShmSize, got %d", *hostconfig.ShmSize)
if hostconfig.ShmSize != 134217728 {
t.Fatalf("Expected a valid ShmSize, got %d", hostconfig.ShmSize)
}
}