// RemoveOrphans implements project.RuntimeProject.RemoveOrphans. // It will remove orphan containers that are part of the project but not to any services. func (p *Project) RemoveOrphans(ctx context.Context, projectName string, serviceConfigs *config.ServiceConfigs) error { client := p.clientFactory.Create(nil) filter := filters.NewArgs() filter.Add("label", labels.PROJECT.EqString(projectName)) containers, err := client.ContainerList(ctx, types.ContainerListOptions{ Filter: filter, }) if err != nil { return err } currentServices := map[string]struct{}{} for _, serviceName := range serviceConfigs.Keys() { currentServices[serviceName] = struct{}{} } for _, container := range containers { serviceLabel := container.Labels[labels.SERVICE.Str()] if _, ok := currentServices[serviceLabel]; !ok { if err := client.ContainerKill(ctx, container.ID, "SIGKILL"); err != nil { return err } if err := client.ContainerRemove(ctx, container.ID, types.ContainerRemoveOptions{ Force: true, }); err != nil { return err } } } return nil }
func getVolumesFrom(volumesFrom []string, serviceConfigs *config.ServiceConfigs, projectName string) ([]string, error) { volumes := []string{} for _, volumeFrom := range volumesFrom { if serviceConfig, ok := serviceConfigs.Get(volumeFrom); ok { // It's a service - Use the first one name := fmt.Sprintf("%s_%s_1", projectName, volumeFrom) // If a container name is specified, use that instead if serviceConfig.ContainerName != "" { name = serviceConfig.ContainerName } volumes = append(volumes, name) } else { volumes = append(volumes, volumeFrom) } } return volumes, nil }
// NetworksFromServices creates a new Networks struct based on networks configurations and // services configuration. If a network is defined but not used by any service, it will return // an error along the Networks. func NetworksFromServices(cli client.NetworkAPIClient, projectName string, networkConfigs map[string]*config.NetworkConfig, services *config.ServiceConfigs, networkEnabled bool) (*Networks, error) { var err error networks := make([]*Network, 0, len(networkConfigs)) networkNames := map[string]*yaml.Network{} for _, serviceName := range services.Keys() { serviceConfig, _ := services.Get(serviceName) if serviceConfig.NetworkMode != "" || serviceConfig.Networks == nil || len(serviceConfig.Networks.Networks) == 0 { continue } for _, network := range serviceConfig.Networks.Networks { if network.Name != "default" { if _, ok := networkConfigs[network.Name]; !ok { return nil, fmt.Errorf(`Service "%s" uses an undefined network "%s"`, serviceName, network.Name) } } networkNames[network.Name] = network } } for name, config := range networkConfigs { network := NewNetwork(projectName, name, config, cli) networks = append(networks, network) } if len(networkNames) != len(networks) { unused := []string{} for name := range networkConfigs { if name == "default" { continue } if _, ok := networkNames[name]; !ok { unused = append(unused, name) } } if len(unused) != 0 { err = fmt.Errorf("Some networks were defined but are not used by any service: %v", strings.Join(unused, " ")) } } return &Networks{ networks: networks, networkEnabled: networkEnabled, }, err }
// ConvertToTaskDefinition transforms the yaml configs to its ecs equivalent (task definition) func ConvertToTaskDefinition(taskDefinitionName string, context *project.Context, serviceConfigs *config.ServiceConfigs) (*ecs.TaskDefinition, error) { if serviceConfigs.Len() == 0 { return nil, errors.New("cannot create a task definition with no containers; invalid service config") } logUnsupportedConfigFields(context.Project) containerDefinitions := []*ecs.ContainerDefinition{} volumes := make(map[string]string) // map with key:=hostSourcePath value:=VolumeName for _, name := range serviceConfigs.Keys() { serviceConfig, ok := serviceConfigs.Get(name) if !ok { return nil, fmt.Errorf("Couldn't get service with name=[%s]", name) } logUnsupportedServiceConfigFields(name, serviceConfig) containerDef := &ecs.ContainerDefinition{ Name: aws.String(name), } if err := convertToContainerDef(context, serviceConfig, volumes, containerDef); err != nil { return nil, err } containerDefinitions = append(containerDefinitions, containerDef) } taskDefinition := &ecs.TaskDefinition{ Family: aws.String(taskDefinitionName), ContainerDefinitions: containerDefinitions, Volumes: convertToECSVolumes(volumes), } return taskDefinition, nil }