diff --git a/azure/backend.go b/azure/backend.go index 9d4b71e18..768a2fb84 100644 --- a/azure/backend.go +++ b/azure/backend.go @@ -179,6 +179,14 @@ func (cs *aciContainerService) Run(ctx context.Context, r containers.ContainerCo Ports: ports, Labels: r.Labels, Volumes: serviceConfigVolumes, + Deploy: &types.DeployConfig{ + Resources: types.Resources{ + Limits: &types.Resource{ + NanoCPUs: fmt.Sprintf("%f", r.CpuLimit), + MemoryBytes: types.UnitBytes(r.MemLimit.Value()), + }, + }, + }, }, }, Volumes: projectVolumes, diff --git a/azure/convert/convert.go b/azure/convert/convert.go index ba8510995..208a38a0f 100644 --- a/azure/convert/convert.go +++ b/azure/convert/convert.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "io/ioutil" + "strconv" "strings" "github.com/Azure/azure-sdk-for-go/profiles/latest/containerinstance/mgmt/containerinstance" @@ -262,18 +263,30 @@ func (s serviceConfigAciHelper) getAciContainer(volumesCache map[string]bool) (c } else { volumes = &allVolumes } + + memLimit := 1. // Default 1 Gb + var cpuLimit float64 = 1 + if s.Deploy != nil && s.Deploy.Resources.Limits != nil { + memLimit = float64(bytesToGb(s.Deploy.Resources.Limits.MemoryBytes)) + if s.Deploy.Resources.Limits.NanoCPUs != "" { + cpuLimit, err = strconv.ParseFloat(s.Deploy.Resources.Limits.NanoCPUs, 0) + if err != nil { + return containerinstance.Container{}, err + } + } + } return containerinstance.Container{ Name: to.StringPtr(s.Name), ContainerProperties: &containerinstance.ContainerProperties{ Image: to.StringPtr(s.Image), Resources: &containerinstance.ResourceRequirements{ Limits: &containerinstance.ResourceLimits{ - MemoryInGB: to.Float64Ptr(1), - CPU: to.Float64Ptr(1), + MemoryInGB: to.Float64Ptr(memLimit), + CPU: to.Float64Ptr(cpuLimit), }, Requests: &containerinstance.ResourceRequests{ - MemoryInGB: to.Float64Ptr(1), - CPU: to.Float64Ptr(1), + MemoryInGB: to.Float64Ptr(memLimit), // FIXME To implement + CPU: to.Float64Ptr(cpuLimit), // FIXME To implement }, }, VolumeMounts: volumes, @@ -282,6 +295,10 @@ func (s serviceConfigAciHelper) getAciContainer(volumesCache map[string]bool) (c } +func bytesToGb(b types.UnitBytes) int64 { + return int64(b) / 1024 / 1024 / 1024 // from bytes to gigabytes +} + // ContainerGroupToContainer composes a Container from an ACI container definition func ContainerGroupToContainer(containerID string, cg containerinstance.ContainerGroup, cc containerinstance.Container) (containers.Container, error) { memLimits := -1. diff --git a/cli/cmd/run/run.go b/cli/cmd/run/run.go index 4431b9bb1..942a9b264 100644 --- a/cli/cmd/run/run.go +++ b/cli/cmd/run/run.go @@ -44,6 +44,8 @@ func Command() *cobra.Command { cmd.Flags().StringArrayVarP(&opts.Labels, "label", "l", []string{}, "Set meta data on a container") cmd.Flags().StringArrayVarP(&opts.Volumes, "volume", "v", []string{}, "Volume. Ex: user:key@my_share:/absolute/path/to/target") cmd.Flags().BoolP("detach", "d", true, "Run container in background and print container ID") + cmd.Flags().Float64Var(&opts.Cpus, "cpus", 1., "Number of CPUs") + cmd.Flags().VarP(&opts.Memory, "memory", "m", "Memory limit") return cmd } diff --git a/cli/options/run/opts.go b/cli/options/run/opts.go index 2735df8dc..ed2b509a4 100644 --- a/cli/options/run/opts.go +++ b/cli/options/run/opts.go @@ -21,6 +21,7 @@ import ( "strconv" "strings" + "github.com/docker/cli/opts" "github.com/docker/docker/pkg/namesgenerator" "github.com/docker/go-connections/nat" @@ -33,6 +34,8 @@ type Opts struct { Publish []string Labels []string Volumes []string + Cpus float64 + Memory opts.MemBytes } // ToContainerConfig convert run options to a container configuration @@ -52,11 +55,13 @@ func (r *Opts) ToContainerConfig(image string) (containers.ContainerConfig, erro } return containers.ContainerConfig{ - ID: r.Name, - Image: image, - Ports: publish, - Labels: labels, - Volumes: r.Volumes, + ID: r.Name, + Image: image, + Ports: publish, + Labels: labels, + Volumes: r.Volumes, + MemLimit: r.Memory, + CpuLimit: r.Cpus, }, nil } diff --git a/containers/api.go b/containers/api.go index 49af959e0..fe14725b0 100644 --- a/containers/api.go +++ b/containers/api.go @@ -19,6 +19,8 @@ package containers import ( "context" "io" + + "github.com/docker/cli/opts" ) // Container represents a created container @@ -60,6 +62,10 @@ type ContainerConfig struct { Labels map[string]string // Volumes to be mounted Volumes []string + // Memlimit + MemLimit opts.MemBytes + // CPUlimit + CpuLimit float64 } // LogsRequest contains configuration about a log request