Browse Source

Check external filesystems exist on compose up

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof 5 years ago
parent
commit
e903326e1a
3 changed files with 62 additions and 2 deletions
  1. 2 0
      api/compose/tags.go
  2. 28 2
      ecs/awsResources.go
  3. 32 0
      ecs/sdk.go

+ 2 - 0
api/compose/tags.go

@@ -23,4 +23,6 @@ const (
 	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"
 )

+ 28 - 2
ecs/awsResources.go

@@ -38,6 +38,7 @@ type awsResources struct {
 	loadBalancer     string
 	loadBalancerType string
 	securityGroups   map[string]string
+	filesystems      map[string]string
 }
 
 func (r *awsResources) serviceSecurityGroups(service types.ServiceConfig) []string {
@@ -72,7 +73,7 @@ func (b *ecsAPIService) parse(ctx context.Context, project *types.Project) (awsR
 	if err != nil {
 		return r, err
 	}
-	r.securityGroups, err = b.parseSecurityGroupExtension(ctx, project)
+	r.securityGroups, err = b.parseExternalNetworks(ctx, project)
 	if err != nil {
 		return r, err
 	}
@@ -139,7 +140,7 @@ func (b *ecsAPIService) parseLoadBalancerExtension(ctx context.Context, project
 	return "", "", nil
 }
 
-func (b *ecsAPIService) parseSecurityGroupExtension(ctx context.Context, project *types.Project) (map[string]string, error) {
+func (b *ecsAPIService) parseExternalNetworks(ctx context.Context, project *types.Project) (map[string]string, error) {
 	securityGroups := make(map[string]string, len(project.Networks))
 	for name, net := range project.Networks {
 		if !net.External.External {
@@ -163,6 +164,25 @@ func (b *ecsAPIService) parseSecurityGroupExtension(ctx context.Context, project
 	return securityGroups, nil
 }
 
+func (b *ecsAPIService) parseExternalVolumes(ctx context.Context, project *types.Project) (map[string]string, error) {
+	filesystems := make(map[string]string, len(project.Volumes))
+	// project.Volumes.filter(|v| v.External.External).first(|v| b.SDK.FileSystemExists(ctx, vol.Name))?
+	for name, vol := range project.Volumes {
+		if !vol.External.External {
+			continue
+		}
+		exists, err := b.SDK.FileSystemExists(ctx, vol.Name)
+		if err != nil {
+			return nil, err
+		}
+		if !exists {
+			return nil, fmt.Errorf("EFS file system %s doesn't exist", vol.Name)
+		}
+		filesystems[name] = vol.Name
+	}
+	return filesystems, nil
+}
+
 // ensureResources create required resources in template if not yet defined
 func (b *ecsAPIService) ensureResources(resources *awsResources, project *types.Project, template *cloudformation.Template) {
 	b.ensureCluster(resources, project, template)
@@ -210,6 +230,12 @@ func (b *ecsAPIService) ensureNetworks(r *awsResources, project *types.Project,
 	}
 }
 
+func (b *ecsAPIService) ensureVolumes(r *awsResources, project *types.Project, template *cloudformation.Template) {
+	if r.filesystems == nil {
+		r.filesystems = make(map[string]string, len(project.Volumes))
+	}
+}
+
 func (b *ecsAPIService) ensureLoadBalancer(r *awsResources, project *types.Project, template *cloudformation.Template) {
 	if r.loadBalancer != "" {
 		return

+ 32 - 0
ecs/sdk.go

@@ -858,3 +858,35 @@ func (s sdk) DeleteAutoscalingGroup(ctx context.Context, arn string) error {
 	})
 	return err
 }
+
+func (s sdk) FileSystemExists(ctx context.Context, id string) (bool, error) {
+	desc, err := s.EFS.DescribeFileSystemsWithContext(ctx, &efs.DescribeFileSystemsInput{
+		FileSystemId: aws.String(id),
+	})
+	if err != nil {
+		return false, err
+	}
+	return len(desc.FileSystems) > 0, nil
+}
+
+func (s sdk) CreateFileSystem(ctx context.Context, name string) (string, error) {
+	res, err := s.EFS.CreateFileSystemWithContext(ctx, &efs.CreateFileSystemInput{
+		Tags: []*efs.Tag{
+			{
+				Key:   aws.String(compose.VolumeTag),
+				Value: aws.String(name),
+			},
+		},
+	})
+	if err != nil {
+		return "", err
+	}
+	return aws.StringValue(res.FileSystemId), nil
+}
+
+func (s sdk) DeleteFileSystem(ctx context.Context, id string) error {
+	_, err := s.EFS.DeleteFileSystemWithContext(ctx, &efs.DeleteFileSystemInput{
+		FileSystemId: aws.String(id),
+	})
+	return err
+}