Add run env variables support (KEY=AVLUE or KEY, will grab the process env value).

No support yet for env files
This commit is contained in:
Guillaume Tardif 2020-07-07 00:48:34 +02:00
parent 0c27fd6236
commit cb3ac513cc
8 changed files with 140 additions and 46 deletions

View File

@ -162,41 +162,11 @@ func (cs *aciContainerService) Run(ctx context.Context, r containers.ContainerCo
return errors.New(fmt.Sprintf("invalid container name. ACI container name cannot include %q", composeContainerSeparator)) return errors.New(fmt.Sprintf("invalid container name. ACI container name cannot include %q", composeContainerSeparator))
} }
var ports []types.ServicePortConfig project, err := convert.ContainerToComposeProject(r, singleContainerName)
for _, p := range r.Ports {
ports = append(ports, types.ServicePortConfig{
Target: p.ContainerPort,
Published: p.HostPort,
})
}
projectVolumes, serviceConfigVolumes, err := convert.GetRunVolumes(r.Volumes)
if err != nil { if err != nil {
return err return err
} }
project := types.Project{
Name: r.ID,
Services: []types.ServiceConfig{
{
Name: singleContainerName,
Image: r.Image,
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,
}
logrus.Debugf("Running container %q with name %q\n", r.Image, r.ID) logrus.Debugf("Running container %q with name %q\n", r.Image, r.ID)
groupDefinition, err := convert.ToContainerGroup(cs.ctx, project) groupDefinition, err := convert.ToContainerGroup(cs.ctx, project)
if err != nil { if err != nil {

View File

@ -0,0 +1,63 @@
package convert
import (
"fmt"
"strings"
"github.com/compose-spec/compose-go/types"
"github.com/docker/api/containers"
)
// ContainerToComposeProject convert container config to compose project
func ContainerToComposeProject(r containers.ContainerConfig, containerID string) (types.Project, error) {
var ports []types.ServicePortConfig
for _, p := range r.Ports {
ports = append(ports, types.ServicePortConfig{
Target: p.ContainerPort,
Published: p.HostPort,
})
}
projectVolumes, serviceConfigVolumes, err := GetRunVolumes(r.Volumes)
if err != nil {
return types.Project{}, err
}
project := types.Project{
Name: r.ID,
Services: []types.ServiceConfig{
{
Name: containerID,
Image: r.Image,
Ports: ports,
Labels: r.Labels,
Volumes: serviceConfigVolumes,
Environment: toComposeEnvs(r.Environment),
Deploy: &types.DeployConfig{
Resources: types.Resources{
Limits: &types.Resource{
NanoCPUs: fmt.Sprintf("%f", r.CPULimit),
MemoryBytes: types.UnitBytes(r.MemLimit.Value()),
},
},
},
},
},
Volumes: projectVolumes,
}
return project, nil
}
func toComposeEnvs(opts []string) types.MappingWithEquals {
result := map[string]*string{}
for _, env := range opts {
tokens := strings.Split(env, "=")
if len(tokens) > 1 {
result[tokens[0]] = &tokens[1]
} else {
result[env] = nil
}
}
return result
}

View File

@ -0,0 +1,54 @@
/*
Copyright 2020 Docker, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package convert
import (
"testing"
"github.com/Azure/go-autorest/autorest/to"
"github.com/compose-spec/compose-go/types"
"github.com/docker/api/containers"
. "github.com/onsi/gomega"
"github.com/stretchr/testify/suite"
)
type ContainerConvertTestSuite struct {
suite.Suite
}
func (suite *ContainerConvertTestSuite) TestConvertContainerEnvironment() {
container := containers.ContainerConfig{
ID: "container1",
Environment: []string{"key1=value1", "key2", "key3=value3"},
}
project, err := ContainerToComposeProject(container, "ID")
Expect(err).To(BeNil())
service1 := project.Services[0]
Expect(service1.Name).To(Equal("ID"))
Expect(service1.Environment).To(Equal(types.MappingWithEquals{
"key1": to.StringPtr("value1"),
"key2": nil,
"key3": to.StringPtr("value3"),
}))
}
func TestContainerConvertTestSuite(t *testing.T) {
RegisterTestingT(t)
suite.Run(t, new(ContainerConvertTestSuite))
}

View File

@ -262,7 +262,8 @@ func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerResourceLimit
} }
func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerenvVar() { func (suite *ConvertTestSuite) TestComposeContainerGroupToContainerenvVar() {
os.Setenv("key2", "value2") err := os.Setenv("key2", "value2")
Expect(err).To(BeNil())
project := types.Project{ project := types.Project{
Services: []types.ServiceConfig{ Services: []types.ServiceConfig{
{ {

View File

@ -51,6 +51,7 @@ func Command() *cobra.Command {
cmd.Flags().BoolVarP(&opts.Detach, "detach", "d", false, "Run container in background and print container ID") cmd.Flags().BoolVarP(&opts.Detach, "detach", "d", false, "Run container in background and print container ID")
cmd.Flags().Float64Var(&opts.Cpus, "cpus", 1., "Number of CPUs") cmd.Flags().Float64Var(&opts.Cpus, "cpus", 1., "Number of CPUs")
cmd.Flags().VarP(&opts.Memory, "memory", "m", "Memory limit") cmd.Flags().VarP(&opts.Memory, "memory", "m", "Memory limit")
cmd.Flags().StringArrayVarP(&opts.Environment, "env", "e", []string{}, "Set environment variables")
return cmd return cmd
} }

View File

@ -6,6 +6,7 @@ Usage:
Flags: Flags:
--cpus float Number of CPUs (default 1) --cpus float Number of CPUs (default 1)
-d, --detach Run container in background and print container ID -d, --detach Run container in background and print container ID
-e, --env stringArray Set environment variables
-l, --label stringArray Set meta data on a container -l, --label stringArray Set meta data on a container
-m, --memory bytes Memory limit -m, --memory bytes Memory limit
--name string Assign a name to the container --name string Assign a name to the container

View File

@ -30,13 +30,14 @@ import (
// Opts contain run command options // Opts contain run command options
type Opts struct { type Opts struct {
Name string Name string
Publish []string Publish []string
Labels []string Labels []string
Volumes []string Volumes []string
Cpus float64 Cpus float64
Memory formatter.MemBytes Memory formatter.MemBytes
Detach bool Detach bool
Environment []string
} }
// ToContainerConfig convert run options to a container configuration // ToContainerConfig convert run options to a container configuration
@ -56,13 +57,14 @@ func (r *Opts) ToContainerConfig(image string) (containers.ContainerConfig, erro
} }
return containers.ContainerConfig{ return containers.ContainerConfig{
ID: r.Name, ID: r.Name,
Image: image, Image: image,
Ports: publish, Ports: publish,
Labels: labels, Labels: labels,
Volumes: r.Volumes, Volumes: r.Volumes,
MemLimit: r.Memory, MemLimit: r.Memory,
CPULimit: r.Cpus, CPULimit: r.Cpus,
Environment: r.Environment,
}, nil }, nil
} }

View File

@ -68,6 +68,8 @@ type ContainerConfig struct {
MemLimit formatter.MemBytes MemLimit formatter.MemBytes
// CPUlimit // CPUlimit
CPULimit float64 CPULimit float64
// Environment variables
Environment []string
} }
// LogsRequest contains configuration about a log request // LogsRequest contains configuration about a log request