зеркало из https://github.com/docker/compose-cli.git
define compose labels within the compose API
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Родитель
ff0864237c
Коммит
89a63b79cb
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
Copyright 2020 Docker Compose CLI authors
|
||||
|
||||
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 compose
|
||||
|
||||
const (
|
||||
// ProjectLabel allow to track resource related to a compose project
|
||||
ProjectLabel = "com.docker.compose.project"
|
||||
// ServiceLabel allow to track resource related to a compose service
|
||||
ServiceLabel = "com.docker.compose.service"
|
||||
// ConfigHashLabel stores configuration hash for a compose service
|
||||
ConfigHashLabel = "com.docker.compose.config-hash"
|
||||
// ContainerNumberLabel stores the container index of a replicated service
|
||||
ContainerNumberLabel = "com.docker.compose.container-number"
|
||||
// VolumeLabel allow to track resource related to a compose volume
|
||||
VolumeLabel = "com.docker.compose.volume"
|
||||
// NetworkLabel allow to track resource related to a compose network
|
||||
NetworkLabel = "com.docker.compose.network"
|
||||
// WorkingDirLabel stores absolute path to compose project working directory
|
||||
WorkingDirLabel = "com.docker.compose.project.working_dir"
|
||||
// ConfigFilesLabel stores absolute path to compose project configuration files
|
||||
ConfigFilesLabel = "com.docker.compose.project.config_files"
|
||||
// EnvironmentFileLabel stores absolute path to compose project env file set by `--env-file`
|
||||
EnvironmentFileLabel = "com.docker.compose.project.environment_file"
|
||||
// OneoffLabel stores value 'True' for one-off containers created by `compose run`
|
||||
OneoffLabel = "com.docker.compose.oneoff"
|
||||
// SlugLabel stores unique slug used for one-off container identity
|
||||
SlugLabel = "com.docker.compose.slug"
|
||||
// VersionLabel stores the compose tool version used to run application
|
||||
VersionLabel = "com.docker.compose.version"
|
||||
)
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
Copyright 2020 Docker Compose CLI authors
|
||||
|
||||
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 compose
|
||||
|
||||
const (
|
||||
// ProjectTag allow to track resource related to a compose project
|
||||
ProjectTag = "com.docker.compose.project"
|
||||
// NetworkTag allow to track resource related to a compose network
|
||||
NetworkTag = "com.docker.compose.network"
|
||||
// ServiceTag allow to track resource related to a compose service
|
||||
ServiceTag = "com.docker.compose.service"
|
||||
// VolumeTag allow to track resource related to a compose volume
|
||||
VolumeTag = "com.docker.compose.volume"
|
||||
// EnvironmentFileLabel is set in containers with the option "--env-file" when set
|
||||
EnvironmentFileLabel = "com.docker.compose.project.environment_file"
|
||||
)
|
|
@ -289,8 +289,8 @@ func (b *ecsAPIService) parseExternalVolumes(ctx context.Context, project *types
|
|||
|
||||
logrus.Debugf("searching for existing filesystem as volume %q", name)
|
||||
tags := map[string]string{
|
||||
compose.ProjectTag: project.Name,
|
||||
compose.VolumeTag: name,
|
||||
compose.ProjectLabel: project.Name,
|
||||
compose.VolumeLabel: name,
|
||||
}
|
||||
previous, err := b.aws.ListFileSystems(ctx, tags)
|
||||
if err != nil {
|
||||
|
@ -397,11 +397,11 @@ func (b *ecsAPIService) ensureVolumes(r *awsResources, project *types.Project, t
|
|||
FileSystemPolicy: nil,
|
||||
FileSystemTags: []efs.FileSystem_ElasticFileSystemTag{
|
||||
{
|
||||
Key: compose.ProjectTag,
|
||||
Key: compose.ProjectLabel,
|
||||
Value: project.Name,
|
||||
},
|
||||
{
|
||||
Key: compose.VolumeTag,
|
||||
Key: compose.VolumeLabel,
|
||||
Value: name,
|
||||
},
|
||||
{
|
||||
|
|
|
@ -406,8 +406,8 @@ volumes:
|
|||
provisioned_throughput: 1024
|
||||
`, useDefaultVPC, func(m *MockAPIMockRecorder) {
|
||||
m.ListFileSystems(gomock.Any(), map[string]string{
|
||||
compose.ProjectTag: t.Name(),
|
||||
compose.VolumeTag: "db-data",
|
||||
compose.ProjectLabel: t.Name(),
|
||||
compose.VolumeLabel: "db-data",
|
||||
}).Return(nil, nil)
|
||||
})
|
||||
n := volumeResourceName("db-data")
|
||||
|
@ -452,8 +452,8 @@ volumes:
|
|||
db-data: {}
|
||||
`, useDefaultVPC, func(m *MockAPIMockRecorder) {
|
||||
m.ListFileSystems(gomock.Any(), map[string]string{
|
||||
compose.ProjectTag: t.Name(),
|
||||
compose.VolumeTag: "db-data",
|
||||
compose.ProjectLabel: t.Name(),
|
||||
compose.VolumeLabel: "db-data",
|
||||
}).Return([]awsResource{
|
||||
existingAWSResource{
|
||||
id: "fs-123abc",
|
||||
|
@ -521,7 +521,7 @@ services:
|
|||
for i := 0; i < tags.Len(); i++ {
|
||||
k := tags.Index(i).FieldByName("Key").String()
|
||||
v := tags.Index(i).FieldByName("Value").String()
|
||||
if k == compose.ProjectTag {
|
||||
if k == compose.ProjectLabel {
|
||||
assert.Equal(t, v, t.Name())
|
||||
}
|
||||
}
|
||||
|
|
12
ecs/sdk.go
12
ecs/sdk.go
|
@ -341,7 +341,7 @@ func (s sdk) CreateStack(ctx context.Context, name string, region string, templa
|
|||
},
|
||||
Tags: []*cloudformation.Tag{
|
||||
{
|
||||
Key: aws.String(compose.ProjectTag),
|
||||
Key: aws.String(compose.ProjectLabel),
|
||||
Value: aws.String(name),
|
||||
},
|
||||
},
|
||||
|
@ -455,7 +455,7 @@ func (s sdk) ListStacks(ctx context.Context) ([]compose.Stack, error) {
|
|||
}
|
||||
for _, stack := range response.Stacks {
|
||||
for _, t := range stack.Tags {
|
||||
if *t.Key == compose.ProjectTag {
|
||||
if *t.Key == compose.ProjectLabel {
|
||||
status := compose.RUNNING
|
||||
switch aws.StringValue(stack.StackStatus) {
|
||||
case "CREATE_IN_PROGRESS":
|
||||
|
@ -860,12 +860,12 @@ func (s sdk) DescribeService(ctx context.Context, cluster string, arn string) (c
|
|||
service := services.Services[0]
|
||||
var name string
|
||||
for _, t := range service.Tags {
|
||||
if *t.Key == compose.ServiceTag {
|
||||
if *t.Key == compose.ServiceLabel {
|
||||
name = aws.StringValue(t.Value)
|
||||
}
|
||||
}
|
||||
if name == "" {
|
||||
return compose.ServiceStatus{}, fmt.Errorf("service %s doesn't have a %s tag", *service.ServiceArn, compose.ServiceTag)
|
||||
return compose.ServiceStatus{}, fmt.Errorf("service %s doesn't have a %s tag", *service.ServiceArn, compose.ServiceLabel)
|
||||
}
|
||||
targetGroupArns := []string{}
|
||||
for _, lb := range service.LoadBalancers {
|
||||
|
@ -919,9 +919,9 @@ func (s sdk) DescribeServiceTasks(ctx context.Context, cluster string, project s
|
|||
var service string
|
||||
for _, tag := range t.Tags {
|
||||
switch aws.StringValue(tag.Key) {
|
||||
case compose.ProjectTag:
|
||||
case compose.ProjectLabel:
|
||||
project = aws.StringValue(tag.Value)
|
||||
case compose.ServiceTag:
|
||||
case compose.ServiceLabel:
|
||||
service = aws.StringValue(tag.Value)
|
||||
}
|
||||
}
|
||||
|
|
10
ecs/tags.go
10
ecs/tags.go
|
@ -26,7 +26,7 @@ import (
|
|||
func projectTags(project *types.Project) []tags.Tag {
|
||||
return []tags.Tag{
|
||||
{
|
||||
Key: compose.ProjectTag,
|
||||
Key: compose.ProjectLabel,
|
||||
Value: project.Name,
|
||||
},
|
||||
}
|
||||
|
@ -35,11 +35,11 @@ func projectTags(project *types.Project) []tags.Tag {
|
|||
func serviceTags(project *types.Project, service types.ServiceConfig) []tags.Tag {
|
||||
return []tags.Tag{
|
||||
{
|
||||
Key: compose.ProjectTag,
|
||||
Key: compose.ProjectLabel,
|
||||
Value: project.Name,
|
||||
},
|
||||
{
|
||||
Key: compose.ServiceTag,
|
||||
Key: compose.ServiceLabel,
|
||||
Value: service.Name,
|
||||
},
|
||||
}
|
||||
|
@ -48,11 +48,11 @@ func serviceTags(project *types.Project, service types.ServiceConfig) []tags.Tag
|
|||
func networkTags(project *types.Project, net types.NetworkConfig) []tags.Tag {
|
||||
return []tags.Tag{
|
||||
{
|
||||
Key: compose.ProjectTag,
|
||||
Key: compose.ProjectLabel,
|
||||
Value: project.Name,
|
||||
},
|
||||
{
|
||||
Key: compose.NetworkTag,
|
||||
Key: compose.NetworkLabel,
|
||||
Value: net.Name,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -63,11 +63,11 @@ func (b *ecsAPIService) createAccessPoints(project *types.Project, r awsResource
|
|||
ap := efs.AccessPoint{
|
||||
AccessPointTags: []efs.AccessPoint_AccessPointTag{
|
||||
{
|
||||
Key: compose.ProjectTag,
|
||||
Key: compose.ProjectLabel,
|
||||
Value: project.Name,
|
||||
},
|
||||
{
|
||||
Key: compose.VolumeTag,
|
||||
Key: compose.VolumeLabel,
|
||||
Value: name,
|
||||
},
|
||||
{
|
||||
|
|
|
@ -77,7 +77,7 @@ func NewKubeClient(config genericclioptions.RESTClientGetter) (*KubeClient, erro
|
|||
// GetPod retrieves a service pod
|
||||
func (kc KubeClient) GetPod(ctx context.Context, projectName, serviceName string) (*corev1.Pod, error) {
|
||||
pods, err := kc.client.CoreV1().Pods(kc.namespace).List(ctx, metav1.ListOptions{
|
||||
LabelSelector: fmt.Sprintf("%s=%s", compose.ProjectTag, projectName),
|
||||
LabelSelector: fmt.Sprintf("%s=%s", compose.ProjectLabel, projectName),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -87,7 +87,7 @@ func (kc KubeClient) GetPod(ctx context.Context, projectName, serviceName string
|
|||
}
|
||||
var pod corev1.Pod
|
||||
for _, p := range pods.Items {
|
||||
service := p.Labels[compose.ServiceTag]
|
||||
service := p.Labels[compose.ServiceLabel]
|
||||
if service == serviceName {
|
||||
pod = p
|
||||
break
|
||||
|
@ -155,7 +155,7 @@ func (kc KubeClient) GetContainers(ctx context.Context, projectName string, all
|
|||
}
|
||||
|
||||
pods, err := kc.client.CoreV1().Pods(kc.namespace).List(ctx, metav1.ListOptions{
|
||||
LabelSelector: fmt.Sprintf("%s=%s", compose.ProjectTag, projectName),
|
||||
LabelSelector: fmt.Sprintf("%s=%s", compose.ProjectLabel, projectName),
|
||||
FieldSelector: fieldSelector,
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -165,7 +165,7 @@ func (kc KubeClient) GetContainers(ctx context.Context, projectName string, all
|
|||
result := []compose.ContainerSummary{}
|
||||
for _, pod := range pods.Items {
|
||||
summary := podToContainerSummary(pod)
|
||||
serviceName := pod.GetObjectMeta().GetLabels()[compose.ServiceTag]
|
||||
serviceName := pod.GetObjectMeta().GetLabels()[compose.ServiceLabel]
|
||||
ports, ok := services[serviceName]
|
||||
if !ok {
|
||||
s, err := kc.client.CoreV1().Services(kc.namespace).Get(ctx, serviceName, metav1.GetOptions{})
|
||||
|
@ -202,7 +202,7 @@ func (kc KubeClient) GetContainers(ctx context.Context, projectName string, all
|
|||
// GetLogs retrieves pod logs
|
||||
func (kc *KubeClient) GetLogs(ctx context.Context, projectName string, consumer compose.LogConsumer, follow bool) error {
|
||||
pods, err := kc.client.CoreV1().Pods(kc.namespace).List(ctx, metav1.ListOptions{
|
||||
LabelSelector: fmt.Sprintf("%s=%s", compose.ProjectTag, projectName),
|
||||
LabelSelector: fmt.Sprintf("%s=%s", compose.ProjectLabel, projectName),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -210,7 +210,7 @@ func (kc *KubeClient) GetLogs(ctx context.Context, projectName string, consumer
|
|||
eg, ctx := errgroup.WithContext(ctx)
|
||||
for _, pod := range pods.Items {
|
||||
request := kc.client.CoreV1().Pods(kc.namespace).GetLogs(pod.Name, &corev1.PodLogOptions{Follow: follow})
|
||||
service := pod.Labels[compose.ServiceTag]
|
||||
service := pod.Labels[compose.ServiceLabel]
|
||||
w := utils.GetWriter(func(line string) {
|
||||
consumer.Log(pod.Name, service, line)
|
||||
})
|
||||
|
@ -243,7 +243,7 @@ func (kc KubeClient) WaitForPodState(ctx context.Context, opts WaitForStatusOpti
|
|||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
pods, err := kc.client.CoreV1().Pods(kc.namespace).List(ctx, metav1.ListOptions{
|
||||
LabelSelector: fmt.Sprintf("%s=%s", compose.ProjectTag, opts.ProjectName),
|
||||
LabelSelector: fmt.Sprintf("%s=%s", compose.ProjectLabel, opts.ProjectName),
|
||||
})
|
||||
if err != nil {
|
||||
errch <- err
|
||||
|
|
|
@ -34,8 +34,8 @@ func TestPodToContainerSummary(t *testing.T) {
|
|||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "c1-123",
|
||||
Labels: map[string]string{
|
||||
compose.ProjectTag: "myproject",
|
||||
compose.ServiceTag: "service1",
|
||||
compose.ProjectLabel: "myproject",
|
||||
compose.ServiceLabel: "service1",
|
||||
},
|
||||
},
|
||||
Status: v1.PodStatus{
|
||||
|
|
|
@ -47,9 +47,9 @@ func podToContainerSummary(pod corev1.Pod) compose.ContainerSummary {
|
|||
return compose.ContainerSummary{
|
||||
ID: pod.GetObjectMeta().GetName(),
|
||||
Name: pod.GetObjectMeta().GetName(),
|
||||
Service: pod.GetObjectMeta().GetLabels()[compose.ServiceTag],
|
||||
Service: pod.GetObjectMeta().GetLabels()[compose.ServiceLabel],
|
||||
State: state,
|
||||
Project: pod.GetObjectMeta().GetLabels()[compose.ProjectTag],
|
||||
Project: pod.GetObjectMeta().GetLabels()[compose.ProjectLabel],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ func checkPodsState(services []string, pods []corev1.Pod, status string) (bool,
|
|||
servicePods := map[string]string{}
|
||||
stateReached := true
|
||||
for _, pod := range pods {
|
||||
service := pod.Labels[compose.ServiceTag]
|
||||
service := pod.Labels[compose.ServiceLabel]
|
||||
|
||||
if len(services) > 0 && !utils.StringContains(services, service) {
|
||||
continue
|
||||
|
|
|
@ -151,8 +151,8 @@ func mapToDeployment(project *types.Project, service types.ServiceConfig) (*apps
|
|||
|
||||
func selectorLabels(projectName string, serviceName string) map[string]string {
|
||||
return map[string]string{
|
||||
compose.ProjectTag: projectName,
|
||||
compose.ServiceTag: serviceName,
|
||||
compose.ProjectLabel: projectName,
|
||||
compose.ServiceLabel: serviceName,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ func (s *composeService) attach(ctx context.Context, project *types.Project, lis
|
|||
}
|
||||
|
||||
func (s *composeService) attachContainer(ctx context.Context, container moby.Container, listener compose.ContainerEventListener, project *types.Project) error {
|
||||
serviceName := container.Labels[serviceLabel]
|
||||
serviceName := container.Labels[compose.ServiceLabel]
|
||||
containerName := getContainerNameWithoutProject(container)
|
||||
service, err := project.GetService(serviceName)
|
||||
if err != nil {
|
||||
|
|
|
@ -56,8 +56,8 @@ func getCanonicalContainerName(c moby.Container) string {
|
|||
|
||||
func getContainerNameWithoutProject(c moby.Container) string {
|
||||
name := getCanonicalContainerName(c)
|
||||
project := c.Labels[projectLabel]
|
||||
prefix := fmt.Sprintf("%s_%s_", project, c.Labels[serviceLabel])
|
||||
project := c.Labels[compose.ProjectLabel]
|
||||
prefix := fmt.Sprintf("%s_%s_", project, c.Labels[compose.ServiceLabel])
|
||||
if strings.HasPrefix(name, prefix) {
|
||||
return name[len(project)+1:]
|
||||
}
|
||||
|
|
|
@ -18,12 +18,12 @@ package compose
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
moby "github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
|
||||
"github.com/docker/compose-cli/api/compose"
|
||||
"github.com/docker/compose-cli/utils"
|
||||
)
|
||||
|
||||
|
@ -40,21 +40,19 @@ const (
|
|||
|
||||
func (s *composeService) getContainers(ctx context.Context, project string, oneOff oneOff, stopped bool, selectedServices ...string) (Containers, error) {
|
||||
var containers Containers
|
||||
f := filters.NewArgs(
|
||||
projectFilter(project),
|
||||
)
|
||||
f := []filters.KeyValuePair{projectFilter(project)}
|
||||
if len(selectedServices) == 1 {
|
||||
f.Add("label", fmt.Sprintf("%s=%s", serviceLabel, selectedServices[0]))
|
||||
f = append(f, serviceFilter(selectedServices[0]))
|
||||
}
|
||||
switch oneOff {
|
||||
case oneOffOnly:
|
||||
f.Add("label", fmt.Sprintf("%s=%s", oneoffLabel, "True"))
|
||||
f = append(f, oneOffFilter(true))
|
||||
case oneOffExclude:
|
||||
f.Add("label", fmt.Sprintf("%s=%s", oneoffLabel, "False"))
|
||||
f = append(f, oneOffFilter(false))
|
||||
case oneOffInclude:
|
||||
}
|
||||
containers, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{
|
||||
Filters: f,
|
||||
Filters: filters.NewArgs(f...),
|
||||
All: stopped,
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -71,20 +69,20 @@ type containerPredicate func(c moby.Container) bool
|
|||
|
||||
func isService(services ...string) containerPredicate {
|
||||
return func(c moby.Container) bool {
|
||||
service := c.Labels[serviceLabel]
|
||||
service := c.Labels[compose.ServiceLabel]
|
||||
return utils.StringContains(services, service)
|
||||
}
|
||||
}
|
||||
|
||||
func isNotService(services ...string) containerPredicate {
|
||||
return func(c moby.Container) bool {
|
||||
service := c.Labels[serviceLabel]
|
||||
service := c.Labels[compose.ServiceLabel]
|
||||
return !utils.StringContains(services, service)
|
||||
}
|
||||
}
|
||||
|
||||
func isNotOneOff(c moby.Container) bool {
|
||||
v, ok := c.Labels[oneoffLabel]
|
||||
v, ok := c.Labels[compose.OneoffLabel]
|
||||
return !ok || v == "False"
|
||||
}
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ func (s *composeService) ensureService(ctx context.Context, project *types.Proje
|
|||
container := container
|
||||
name := getContainerProgressName(container)
|
||||
|
||||
diverged := container.Labels[configHashLabel] != expected
|
||||
diverged := container.Labels[compose.ConfigHashLabel] != expected
|
||||
if diverged || recreate == compose.RecreateForce || service.Extensions[extLifecycle] == forceRecreate {
|
||||
eg.Go(func() error {
|
||||
return s.recreateContainer(ctx, project, service, container, inherit, timeout)
|
||||
|
@ -190,7 +190,7 @@ func (s *composeService) waitDependencies(ctx context.Context, project *types.Pr
|
|||
func nextContainerNumber(containers []moby.Container) (int, error) {
|
||||
max := 0
|
||||
for _, c := range containers {
|
||||
n, err := strconv.Atoi(c.Labels[containerNumberLabel])
|
||||
n, err := strconv.Atoi(c.Labels[compose.ContainerNumberLabel])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ func (s *composeService) recreateContainer(ctx context.Context, project *types.P
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
number, err := strconv.Atoi(container.Labels[containerNumberLabel])
|
||||
number, err := strconv.Atoi(container.Labels[compose.ContainerNumberLabel])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ func (s *composeService) Copy(ctx context.Context, project *types.Project, opts
|
|||
serviceFilter(serviceName),
|
||||
)
|
||||
if !opts.All {
|
||||
f.Add("label", fmt.Sprintf("%s=%d", containerNumberLabel, opts.Index))
|
||||
f.Add("label", fmt.Sprintf("%s=%d", compose.ContainerNumberLabel, opts.Index))
|
||||
}
|
||||
containers, err := s.apiClient.ContainerList(ctx, apitypes.ContainerListOptions{Filters: f})
|
||||
if err != nil {
|
||||
|
|
|
@ -39,6 +39,7 @@ import (
|
|||
|
||||
"github.com/docker/compose-cli/api/compose"
|
||||
"github.com/docker/compose-cli/api/progress"
|
||||
"github.com/docker/compose-cli/internal"
|
||||
convert "github.com/docker/compose-cli/local/moby"
|
||||
"github.com/docker/compose-cli/utils"
|
||||
)
|
||||
|
@ -138,9 +139,9 @@ func prepareVolumes(p *types.Project) error {
|
|||
|
||||
func prepareNetworks(project *types.Project) {
|
||||
for k, network := range project.Networks {
|
||||
network.Labels = network.Labels.Add(networkLabel, k)
|
||||
network.Labels = network.Labels.Add(projectLabel, project.Name)
|
||||
network.Labels = network.Labels.Add(versionLabel, ComposeVersion)
|
||||
network.Labels = network.Labels.Add(compose.NetworkLabel, k)
|
||||
network.Labels = network.Labels.Add(compose.ProjectLabel, project.Name)
|
||||
network.Labels = network.Labels.Add(compose.VersionLabel, internal.Version)
|
||||
project.Networks[k] = network
|
||||
}
|
||||
}
|
||||
|
@ -181,9 +182,9 @@ func (s *composeService) ensureNetworks(ctx context.Context, networks types.Netw
|
|||
|
||||
func (s *composeService) ensureProjectVolumes(ctx context.Context, project *types.Project) error {
|
||||
for k, volume := range project.Volumes {
|
||||
volume.Labels = volume.Labels.Add(volumeLabel, k)
|
||||
volume.Labels = volume.Labels.Add(projectLabel, project.Name)
|
||||
volume.Labels = volume.Labels.Add(versionLabel, ComposeVersion)
|
||||
volume.Labels = volume.Labels.Add(compose.VolumeLabel, k)
|
||||
volume.Labels = volume.Labels.Add(compose.ProjectLabel, project.Name)
|
||||
volume.Labels = volume.Labels.Add(compose.VersionLabel, internal.Version)
|
||||
err := s.ensureVolume(ctx, volume)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -213,16 +214,16 @@ func (s *composeService) getCreateOptions(ctx context.Context, p *types.Project,
|
|||
labels[k] = v
|
||||
}
|
||||
|
||||
labels[projectLabel] = p.Name
|
||||
labels[serviceLabel] = service.Name
|
||||
labels[versionLabel] = ComposeVersion
|
||||
if _, ok := service.Labels[oneoffLabel]; !ok {
|
||||
labels[oneoffLabel] = "False"
|
||||
labels[compose.ProjectLabel] = p.Name
|
||||
labels[compose.ServiceLabel] = service.Name
|
||||
labels[compose.VersionLabel] = internal.Version
|
||||
if _, ok := service.Labels[compose.OneoffLabel]; !ok {
|
||||
labels[compose.OneoffLabel] = "False"
|
||||
}
|
||||
labels[configHashLabel] = hash
|
||||
labels[workingDirLabel] = p.WorkingDir
|
||||
labels[configFilesLabel] = strings.Join(p.ComposeFiles, ",")
|
||||
labels[containerNumberLabel] = strconv.Itoa(number)
|
||||
labels[compose.ConfigHashLabel] = hash
|
||||
labels[compose.WorkingDirLabel] = p.WorkingDir
|
||||
labels[compose.ConfigFilesLabel] = strings.Join(p.ComposeFiles, ",")
|
||||
labels[compose.ContainerNumberLabel] = strconv.Itoa(number)
|
||||
|
||||
var (
|
||||
runCmd strslice.StrSlice
|
||||
|
|
|
@ -21,6 +21,8 @@ import (
|
|||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/compose-cli/internal"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
composetypes "github.com/compose-spec/compose-go/types"
|
||||
mountTypes "github.com/docker/docker/api/types/mount"
|
||||
|
@ -76,6 +78,6 @@ func TestPrepareNetworkLabels(t *testing.T) {
|
|||
assert.DeepEqual(t, project.Networks["skynet"].Labels, types.Labels(map[string]string{
|
||||
"com.docker.compose.network": "skynet",
|
||||
"com.docker.compose.project": "myProject",
|
||||
"com.docker.compose.version": "1.0-alpha",
|
||||
"com.docker.compose.version": internal.Version,
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -259,7 +259,7 @@ func (s *composeService) projectFromContainerLabels(containers Containers, proje
|
|||
if options.ConfigPaths[0] == "-" {
|
||||
for _, container := range containers {
|
||||
fakeProject.Services = append(fakeProject.Services, types.ServiceConfig{
|
||||
Name: container.Labels[serviceLabel],
|
||||
Name: container.Labels[compose.ServiceLabel],
|
||||
})
|
||||
}
|
||||
return fakeProject, nil
|
||||
|
@ -273,8 +273,8 @@ func (s *composeService) projectFromContainerLabels(containers Containers, proje
|
|||
}
|
||||
|
||||
func loadProjectOptionsFromLabels(c moby.Container) (*cli.ProjectOptions, error) {
|
||||
return cli.NewProjectOptions(strings.Split(c.Labels[configFilesLabel], ","),
|
||||
return cli.NewProjectOptions(strings.Split(c.Labels[compose.ConfigFilesLabel], ","),
|
||||
cli.WithOsEnv,
|
||||
cli.WithWorkingDirectory(c.Labels[workingDirLabel]),
|
||||
cli.WithName(c.Labels[projectLabel]))
|
||||
cli.WithWorkingDirectory(c.Labels[compose.WorkingDirLabel]),
|
||||
cli.WithName(c.Labels[compose.ProjectLabel]))
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ func (s *composeService) Events(ctx context.Context, project string, options com
|
|||
continue
|
||||
}
|
||||
|
||||
service := event.Actor.Attributes[serviceLabel]
|
||||
service := event.Actor.Attributes[compose.ServiceLabel]
|
||||
if len(options.Services) > 0 && !utils.StringContains(options.Services, service) {
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ func (s *composeService) getExecTarget(ctx context.Context, project *types.Proje
|
|||
Filters: filters.NewArgs(
|
||||
projectFilter(project.Name),
|
||||
serviceFilter(service.Name),
|
||||
filters.Arg("label", fmt.Sprintf("%s=%d", containerNumberLabel, opts.Index)),
|
||||
containerNumberFilter(opts.Index),
|
||||
),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
@ -19,36 +19,34 @@ package compose
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
|
||||
"github.com/docker/compose-cli/api/compose"
|
||||
)
|
||||
|
||||
const (
|
||||
containerNumberLabel = "com.docker.compose.container-number"
|
||||
oneoffLabel = "com.docker.compose.oneoff"
|
||||
slugLabel = "com.docker.compose.slug"
|
||||
projectLabel = compose.ProjectTag
|
||||
volumeLabel = compose.VolumeTag
|
||||
workingDirLabel = "com.docker.compose.project.working_dir"
|
||||
configFilesLabel = "com.docker.compose.project.config_files"
|
||||
serviceLabel = compose.ServiceTag
|
||||
versionLabel = "com.docker.compose.version"
|
||||
configHashLabel = "com.docker.compose.config-hash"
|
||||
networkLabel = compose.NetworkTag
|
||||
|
||||
// ComposeVersion Compose version
|
||||
ComposeVersion = "1.0-alpha"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
)
|
||||
|
||||
func projectFilter(projectName string) filters.KeyValuePair {
|
||||
return filters.Arg("label", fmt.Sprintf("%s=%s", projectLabel, projectName))
|
||||
return filters.Arg("label", fmt.Sprintf("%s=%s", compose.ProjectLabel, projectName))
|
||||
}
|
||||
|
||||
func serviceFilter(serviceName string) filters.KeyValuePair {
|
||||
return filters.Arg("label", fmt.Sprintf("%s=%s", serviceLabel, serviceName))
|
||||
return filters.Arg("label", fmt.Sprintf("%s=%s", compose.ServiceLabel, serviceName))
|
||||
}
|
||||
|
||||
func slugFilter(slug string) filters.KeyValuePair {
|
||||
return filters.Arg("label", fmt.Sprintf("%s=%s", compose.SlugLabel, slug))
|
||||
}
|
||||
|
||||
func oneOffFilter(b bool) filters.KeyValuePair {
|
||||
v := "False"
|
||||
if b {
|
||||
v = "True"
|
||||
}
|
||||
return filters.Arg("label", fmt.Sprintf("%s=%s", compose.OneoffLabel, v))
|
||||
}
|
||||
|
||||
func containerNumberFilter(index int) filters.KeyValuePair {
|
||||
return filters.Arg("label", fmt.Sprintf("%s=%d", compose.ContainerNumberLabel, index))
|
||||
}
|
||||
|
||||
func hasProjectLabelFilter() filters.KeyValuePair {
|
||||
return filters.Arg("label", projectLabel)
|
||||
return filters.Arg("label", compose.ProjectLabel)
|
||||
}
|
|
@ -42,7 +42,7 @@ func (s *composeService) Images(ctx context.Context, projectName string, options
|
|||
if len(options.Services) > 0 {
|
||||
// filter service containers
|
||||
for _, c := range allContainers {
|
||||
if utils.StringContains(options.Services, c.Labels[compose.ServiceTag]) {
|
||||
if utils.StringContains(options.Services, c.Labels[compose.ServiceLabel]) {
|
||||
containers = append(containers, c)
|
||||
|
||||
}
|
||||
|
|
|
@ -86,7 +86,11 @@ func testContainer(service string, id string) apitypes.Container {
|
|||
func containerLabels(service string) map[string]string {
|
||||
workingdir, _ := filepath.Abs("testdata")
|
||||
composefile := filepath.Join(workingdir, "docker-compose.yml")
|
||||
return map[string]string{serviceLabel: service, configFilesLabel: composefile, workingDirLabel: workingdir, projectLabel: testProject}
|
||||
return map[string]string{
|
||||
compose.ServiceLabel: service,
|
||||
compose.ConfigFilesLabel: composefile,
|
||||
compose.WorkingDirLabel: workingdir,
|
||||
compose.ProjectLabel: testProject}
|
||||
}
|
||||
|
||||
func anyCancellableContext() gomock.Matcher {
|
||||
|
|
|
@ -37,7 +37,7 @@ func (s *composeService) Logs(ctx context.Context, projectName string, consumer
|
|||
eg, ctx := errgroup.WithContext(ctx)
|
||||
for _, c := range list {
|
||||
c := c
|
||||
service := c.Labels[serviceLabel]
|
||||
service := c.Labels[compose.ServiceLabel]
|
||||
container, err := s.apiClient.ContainerInspect(ctx, c.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -40,7 +40,7 @@ func (s *composeService) List(ctx context.Context, opts compose.ListOptions) ([]
|
|||
}
|
||||
|
||||
func containersToStacks(containers []moby.Container) ([]compose.Stack, error) {
|
||||
containersByLabel, keys, err := groupContainerByLabel(containers, projectLabel)
|
||||
containersByLabel, keys, err := groupContainerByLabel(containers, compose.ProjectLabel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -30,17 +30,17 @@ func TestContainersToStacks(t *testing.T) {
|
|||
{
|
||||
ID: "service1",
|
||||
State: "running",
|
||||
Labels: map[string]string{projectLabel: "project1"},
|
||||
Labels: map[string]string{compose.ProjectLabel: "project1"},
|
||||
},
|
||||
{
|
||||
ID: "service2",
|
||||
State: "running",
|
||||
Labels: map[string]string{projectLabel: "project1"},
|
||||
Labels: map[string]string{compose.ProjectLabel: "project1"},
|
||||
},
|
||||
{
|
||||
ID: "service3",
|
||||
State: "running",
|
||||
Labels: map[string]string{projectLabel: "project2"},
|
||||
Labels: map[string]string{compose.ProjectLabel: "project2"},
|
||||
},
|
||||
}
|
||||
stacks, err := containersToStacks(containers)
|
||||
|
|
|
@ -31,7 +31,7 @@ func (s *composeService) Port(ctx context.Context, project string, service strin
|
|||
Filters: filters.NewArgs(
|
||||
projectFilter(project),
|
||||
serviceFilter(service),
|
||||
filters.Arg("label", fmt.Sprintf("%s=%d", containerNumberLabel, options.Index)),
|
||||
containerNumberFilter(options.Index),
|
||||
),
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
@ -81,8 +81,8 @@ func (s *composeService) Ps(ctx context.Context, projectName string, options com
|
|||
summary[i] = compose.ContainerSummary{
|
||||
ID: container.ID,
|
||||
Name: getCanonicalContainerName(container),
|
||||
Project: container.Labels[projectLabel],
|
||||
Service: container.Labels[serviceLabel],
|
||||
Project: container.Labels[compose.ProjectLabel],
|
||||
Service: container.Labels[compose.ServiceLabel],
|
||||
State: container.State,
|
||||
Health: health,
|
||||
ExitCode: exitCode,
|
||||
|
|
|
@ -50,8 +50,8 @@ func (s *composeService) RunOneOffContainer(ctx context.Context, project *types.
|
|||
}
|
||||
service.Scale = 1
|
||||
service.StdinOpen = true
|
||||
service.Labels = service.Labels.Add(slugLabel, slug)
|
||||
service.Labels = service.Labels.Add(oneoffLabel, "True")
|
||||
service.Labels = service.Labels.Add(compose.SlugLabel, slug)
|
||||
service.Labels = service.Labels.Add(compose.OneoffLabel, "True")
|
||||
|
||||
if err := s.ensureImagesExists(ctx, project, observedState, false); err != nil { // all dependencies already checked, but might miss service img
|
||||
return 0, err
|
||||
|
@ -74,9 +74,7 @@ func (s *composeService) RunOneOffContainer(ctx context.Context, project *types.
|
|||
}
|
||||
|
||||
containers, err := s.apiClient.ContainerList(ctx, apitypes.ContainerListOptions{
|
||||
Filters: filters.NewArgs(
|
||||
filters.Arg("label", fmt.Sprintf("%s=%s", slugLabel, slug)),
|
||||
),
|
||||
Filters: filters.NewArgs(slugFilter(slug)),
|
||||
All: true,
|
||||
})
|
||||
if err != nil {
|
||||
|
|
|
@ -95,7 +95,7 @@ func (s *composeService) watchContainers(project *types.Project, services []stri
|
|||
listener(compose.ContainerEvent{
|
||||
Type: compose.ContainerEventExit,
|
||||
Container: name,
|
||||
Service: container.Labels[serviceLabel],
|
||||
Service: container.Labels[compose.ServiceLabel],
|
||||
ExitCode: inspected.State.ExitCode,
|
||||
Restarting: willRestart,
|
||||
})
|
||||
|
|
Загрузка…
Ссылка в новой задаче