mirror of https://github.com/docker/compose.git
Allow to set memory / CPU limits higher than requests, ACI will request that limits are not higher than the total request for the container group. Also set requests = limits when only limits are set
Signed-off-by: Guillaume Tardif <guillaume.tardif@docker.com>
This commit is contained in:
parent
c09f771359
commit
343d54dac5
|
@ -353,34 +353,73 @@ func (s serviceConfigAciHelper) getAciContainer(volumesCache map[string]bool) (c
|
||||||
volumes = &allVolumes
|
volumes = &allVolumes
|
||||||
}
|
}
|
||||||
|
|
||||||
memRequest := 1. // Default 1 Gb
|
resource, err := s.getResourceRequestsLimits()
|
||||||
var cpuRequest float64 = 1
|
|
||||||
if s.Deploy != nil && s.Deploy.Resources.Reservations != nil {
|
|
||||||
if s.Deploy.Resources.Reservations.MemoryBytes != 0 {
|
|
||||||
memRequest = bytesToGb(s.Deploy.Resources.Reservations.MemoryBytes)
|
|
||||||
}
|
|
||||||
if s.Deploy.Resources.Reservations.NanoCPUs != "" {
|
|
||||||
cpuRequest, err = strconv.ParseFloat(s.Deploy.Resources.Reservations.NanoCPUs, 0)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return containerinstance.Container{}, err
|
return containerinstance.Container{}, err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return containerinstance.Container{
|
return containerinstance.Container{
|
||||||
Name: to.StringPtr(s.Name),
|
Name: to.StringPtr(s.Name),
|
||||||
ContainerProperties: &containerinstance.ContainerProperties{
|
ContainerProperties: &containerinstance.ContainerProperties{
|
||||||
Image: to.StringPtr(s.Image),
|
Image: to.StringPtr(s.Image),
|
||||||
Command: to.StringSlicePtr(s.Command),
|
Command: to.StringSlicePtr(s.Command),
|
||||||
EnvironmentVariables: getEnvVariables(s.Environment),
|
EnvironmentVariables: getEnvVariables(s.Environment),
|
||||||
Resources: &containerinstance.ResourceRequirements{
|
Resources: resource,
|
||||||
|
VolumeMounts: volumes,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s serviceConfigAciHelper) getResourceRequestsLimits() (*containerinstance.ResourceRequirements, error) {
|
||||||
|
memRequest := 1. // Default 1 Gb
|
||||||
|
var cpuRequest float64 = 1
|
||||||
|
var err error
|
||||||
|
hasMemoryRequest := func() bool {
|
||||||
|
return s.Deploy != nil && s.Deploy.Resources.Reservations != nil && s.Deploy.Resources.Reservations.MemoryBytes != 0
|
||||||
|
}
|
||||||
|
hasCPURequest := func() bool {
|
||||||
|
return s.Deploy != nil && s.Deploy.Resources.Reservations != nil && s.Deploy.Resources.Reservations.NanoCPUs != ""
|
||||||
|
}
|
||||||
|
if hasMemoryRequest() {
|
||||||
|
memRequest = bytesToGb(s.Deploy.Resources.Reservations.MemoryBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasCPURequest() {
|
||||||
|
cpuRequest, err = strconv.ParseFloat(s.Deploy.Resources.Reservations.NanoCPUs, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memLimit := memRequest
|
||||||
|
cpuLimit := cpuRequest
|
||||||
|
if s.Deploy != nil && s.Deploy.Resources.Limits != nil {
|
||||||
|
if s.Deploy.Resources.Limits.MemoryBytes != 0 {
|
||||||
|
memLimit = bytesToGb(s.Deploy.Resources.Limits.MemoryBytes)
|
||||||
|
if !hasMemoryRequest() {
|
||||||
|
memRequest = memLimit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if s.Deploy.Resources.Limits.NanoCPUs != "" {
|
||||||
|
cpuLimit, err = strconv.ParseFloat(s.Deploy.Resources.Limits.NanoCPUs, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !hasCPURequest() {
|
||||||
|
cpuRequest = cpuLimit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resources := containerinstance.ResourceRequirements{
|
||||||
Requests: &containerinstance.ResourceRequests{
|
Requests: &containerinstance.ResourceRequests{
|
||||||
MemoryInGB: to.Float64Ptr(memRequest),
|
MemoryInGB: to.Float64Ptr(memRequest),
|
||||||
CPU: to.Float64Ptr(cpuRequest),
|
CPU: to.Float64Ptr(cpuRequest),
|
||||||
},
|
},
|
||||||
|
Limits: &containerinstance.ResourceLimits{
|
||||||
|
MemoryInGB: to.Float64Ptr(memLimit),
|
||||||
|
CPU: to.Float64Ptr(cpuLimit),
|
||||||
},
|
},
|
||||||
VolumeMounts: volumes,
|
}
|
||||||
},
|
return &resources, nil
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getEnvVariables(composeEnv types.MappingWithEquals) *[]containerinstance.EnvironmentVariable {
|
func getEnvVariables(composeEnv types.MappingWithEquals) *[]containerinstance.EnvironmentVariable {
|
||||||
|
|
|
@ -561,6 +561,73 @@ func TestComposeContainerGroupToContainerResourceRequests(t *testing.T) {
|
||||||
request := *((*group.Containers)[0]).Resources.Requests
|
request := *((*group.Containers)[0]).Resources.Requests
|
||||||
assert.Equal(t, *request.CPU, float64(0.1))
|
assert.Equal(t, *request.CPU, float64(0.1))
|
||||||
assert.Equal(t, *request.MemoryInGB, float64(0.1))
|
assert.Equal(t, *request.MemoryInGB, float64(0.1))
|
||||||
|
limits := *((*group.Containers)[0]).Resources.Limits
|
||||||
|
assert.Equal(t, *limits.CPU, float64(0.1))
|
||||||
|
assert.Equal(t, *limits.MemoryInGB, float64(0.1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestComposeContainerGroupToContainerResourceRequestsAndLimits(t *testing.T) {
|
||||||
|
_0_1Gb := 0.1 * 1024 * 1024 * 1024
|
||||||
|
project := types.Project{
|
||||||
|
Services: []types.ServiceConfig{
|
||||||
|
{
|
||||||
|
Name: "service1",
|
||||||
|
Image: "image1",
|
||||||
|
Deploy: &types.DeployConfig{
|
||||||
|
Resources: types.Resources{
|
||||||
|
Reservations: &types.Resource{
|
||||||
|
NanoCPUs: "0.1",
|
||||||
|
MemoryBytes: types.UnitBytes(_0_1Gb),
|
||||||
|
},
|
||||||
|
Limits: &types.Resource{
|
||||||
|
NanoCPUs: "0.3",
|
||||||
|
MemoryBytes: types.UnitBytes(2 * _0_1Gb),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
request := *((*group.Containers)[0]).Resources.Requests
|
||||||
|
assert.Equal(t, *request.CPU, float64(0.1))
|
||||||
|
assert.Equal(t, *request.MemoryInGB, float64(0.1))
|
||||||
|
limits := *((*group.Containers)[0]).Resources.Limits
|
||||||
|
assert.Equal(t, *limits.CPU, float64(0.3))
|
||||||
|
assert.Equal(t, *limits.MemoryInGB, float64(0.2))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestComposeContainerGroupToContainerResourceLimitsOnly(t *testing.T) {
|
||||||
|
_0_1Gb := 0.1 * 1024 * 1024 * 1024
|
||||||
|
project := types.Project{
|
||||||
|
Services: []types.ServiceConfig{
|
||||||
|
{
|
||||||
|
Name: "service1",
|
||||||
|
Image: "image1",
|
||||||
|
Deploy: &types.DeployConfig{
|
||||||
|
Resources: types.Resources{
|
||||||
|
Limits: &types.Resource{
|
||||||
|
NanoCPUs: "0.3",
|
||||||
|
MemoryBytes: types.UnitBytes(2 * _0_1Gb),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
group, err := ToContainerGroup(context.TODO(), convertCtx, project, mockStorageHelper)
|
||||||
|
assert.NilError(t, err)
|
||||||
|
|
||||||
|
request := *((*group.Containers)[0]).Resources.Requests
|
||||||
|
assert.Equal(t, *request.CPU, float64(0.3))
|
||||||
|
assert.Equal(t, *request.MemoryInGB, float64(0.2))
|
||||||
|
limits := *((*group.Containers)[0]).Resources.Limits
|
||||||
|
assert.Equal(t, *limits.CPU, float64(0.3))
|
||||||
|
assert.Equal(t, *limits.MemoryInGB, float64(0.2))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestComposeContainerGroupToContainerResourceRequestsDefaults(t *testing.T) {
|
func TestComposeContainerGroupToContainerResourceRequestsDefaults(t *testing.T) {
|
||||||
|
|
Loading…
Reference in New Issue