|  | @@ -24,7 +24,6 @@ import (
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	"github.com/compose-spec/compose-go/types"
 | 
	
		
			
				|  |  |  	moby "github.com/docker/docker/api/types"
 | 
	
		
			
				|  |  | -	"github.com/docker/docker/api/types/filters"
 | 
	
		
			
				|  |  |  	"github.com/docker/docker/errdefs"
 | 
	
		
			
				|  |  |  	"golang.org/x/sync/errgroup"
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -41,7 +40,6 @@ func (s *composeService) Down(ctx context.Context, projectName string, options a
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func (s *composeService) down(ctx context.Context, projectName string, options api.DownOptions) error {
 | 
	
		
			
				|  |  | -	builtFromResources := options.Project == nil
 | 
	
		
			
				|  |  |  	w := progress.ContextWriter(ctx)
 | 
	
		
			
				|  |  |  	resourceToRemove := false
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -51,8 +49,9 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
 | 
	
		
			
				|  |  |  		return err
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	if builtFromResources {
 | 
	
		
			
				|  |  | -		options.Project, err = s.getProjectWithVolumes(ctx, containers, projectName)
 | 
	
		
			
				|  |  | +	project := options.Project
 | 
	
		
			
				|  |  | +	if project == nil {
 | 
	
		
			
				|  |  | +		project, err = s.getProjectWithResources(ctx, containers, projectName)
 | 
	
		
			
				|  |  |  		if err != nil {
 | 
	
		
			
				|  |  |  			return err
 | 
	
		
			
				|  |  |  		}
 | 
	
	
		
			
				|  | @@ -62,7 +61,7 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
 | 
	
		
			
				|  |  |  		resourceToRemove = true
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	err = InReverseDependencyOrder(ctx, options.Project, func(c context.Context, service string) error {
 | 
	
		
			
				|  |  | +	err = InReverseDependencyOrder(ctx, project, func(c context.Context, service string) error {
 | 
	
		
			
				|  |  |  		serviceContainers := containers.filter(isService(service))
 | 
	
		
			
				|  |  |  		err := s.removeContainers(ctx, w, serviceContainers, options.Timeout, options.Volumes)
 | 
	
		
			
				|  |  |  		return err
 | 
	
	
		
			
				|  | @@ -71,7 +70,7 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
 | 
	
		
			
				|  |  |  		return err
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	orphans := containers.filter(isNotService(options.Project.ServiceNames()...))
 | 
	
		
			
				|  |  | +	orphans := containers.filter(isNotService(project.ServiceNames()...))
 | 
	
		
			
				|  |  |  	if options.RemoveOrphans && len(orphans) > 0 {
 | 
	
		
			
				|  |  |  		err := s.removeContainers(ctx, w, orphans, options.Timeout, false)
 | 
	
		
			
				|  |  |  		if err != nil {
 | 
	
	
		
			
				|  | @@ -79,17 +78,14 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	ops, err := s.ensureNetworksDown(ctx, projectName)
 | 
	
		
			
				|  |  | -	if err != nil {
 | 
	
		
			
				|  |  | -		return err
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | +	ops := s.ensureNetworksDown(ctx, project, w)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	if options.Images != "" {
 | 
	
		
			
				|  |  |  		ops = append(ops, s.ensureImagesDown(ctx, projectName, options, w)...)
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	if options.Volumes {
 | 
	
		
			
				|  |  | -		ops = append(ops, s.ensureVolumesDown(ctx, options.Project, w)...)
 | 
	
		
			
				|  |  | +		ops = append(ops, s.ensureVolumesDown(ctx, project, w)...)
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	if !resourceToRemove && len(ops) == 0 {
 | 
	
	
		
			
				|  | @@ -106,6 +102,9 @@ func (s *composeService) down(ctx context.Context, projectName string, options a
 | 
	
		
			
				|  |  |  func (s *composeService) ensureVolumesDown(ctx context.Context, project *types.Project, w progress.Writer) []downOp {
 | 
	
		
			
				|  |  |  	var ops []downOp
 | 
	
		
			
				|  |  |  	for _, vol := range project.Volumes {
 | 
	
		
			
				|  |  | +		if vol.External.External {
 | 
	
		
			
				|  |  | +			continue
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  		volumeName := vol.Name
 | 
	
		
			
				|  |  |  		ops = append(ops, func() error {
 | 
	
		
			
				|  |  |  			return s.removeVolume(ctx, volumeName, w)
 | 
	
	
		
			
				|  | @@ -125,20 +124,18 @@ func (s *composeService) ensureImagesDown(ctx context.Context, projectName strin
 | 
	
		
			
				|  |  |  	return ops
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func (s *composeService) ensureNetworksDown(ctx context.Context, projectName string) ([]downOp, error) {
 | 
	
		
			
				|  |  | +func (s *composeService) ensureNetworksDown(ctx context.Context, project *types.Project, w progress.Writer) []downOp {
 | 
	
		
			
				|  |  |  	var ops []downOp
 | 
	
		
			
				|  |  | -	networks, err := s.apiClient().NetworkList(ctx, moby.NetworkListOptions{Filters: filters.NewArgs(projectFilter(projectName))})
 | 
	
		
			
				|  |  | -	if err != nil {
 | 
	
		
			
				|  |  | -		return ops, err
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	for _, n := range networks {
 | 
	
		
			
				|  |  | -		networkID := n.ID
 | 
	
		
			
				|  |  | +	for _, n := range project.Networks {
 | 
	
		
			
				|  |  | +		if n.External.External {
 | 
	
		
			
				|  |  | +			continue
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  |  		networkName := n.Name
 | 
	
		
			
				|  |  |  		ops = append(ops, func() error {
 | 
	
		
			
				|  |  | -			return s.removeNetwork(ctx, networkID, networkName)
 | 
	
		
			
				|  |  | +			return s.removeNetwork(ctx, networkName, w)
 | 
	
		
			
				|  |  |  		})
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	return ops, nil
 | 
	
		
			
				|  |  | +	return ops
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func (s *composeService) getServiceImages(options api.DownOptions, projectName string) map[string]struct{} {
 | 
	
	
		
			
				|  | @@ -233,21 +230,20 @@ func (s *composeService) removeContainers(ctx context.Context, w progress.Writer
 | 
	
		
			
				|  |  |  	return eg.Wait()
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func (s *composeService) getProjectWithVolumes(ctx context.Context, containers Containers, projectName string) (*types.Project, error) {
 | 
	
		
			
				|  |  | +func (s *composeService) getProjectWithResources(ctx context.Context, containers Containers, projectName string) (*types.Project, error) {
 | 
	
		
			
				|  |  |  	containers = containers.filter(isNotOneOff)
 | 
	
		
			
				|  |  |  	project, _ := s.projectFromName(containers, projectName)
 | 
	
		
			
				|  |  | -	volumes, err := s.apiClient().VolumeList(ctx, filters.NewArgs(projectFilter(projectName)))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	volumes, err := s.actualVolumes(ctx, projectName)
 | 
	
		
			
				|  |  |  	if err != nil {
 | 
	
		
			
				|  |  |  		return nil, err
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | +	project.Volumes = volumes
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	project.Volumes = types.Volumes{}
 | 
	
		
			
				|  |  | -	for _, vol := range volumes.Volumes {
 | 
	
		
			
				|  |  | -		project.Volumes[vol.Labels[api.VolumeLabel]] = types.VolumeConfig{
 | 
	
		
			
				|  |  | -			Name:   vol.Name,
 | 
	
		
			
				|  |  | -			Driver: vol.Driver,
 | 
	
		
			
				|  |  | -			Labels: vol.Labels,
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | +	networks, err := s.actualNetworks(ctx, projectName)
 | 
	
		
			
				|  |  | +	if err != nil {
 | 
	
		
			
				|  |  | +		return nil, err
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | +	project.Networks = networks
 | 
	
		
			
				|  |  |  	return project, nil
 | 
	
		
			
				|  |  |  }
 |