(ctx context.Context, name string, volume types.VolumeConfig, project *types.Project)
| 1595 | } |
| 1596 | |
| 1597 | func (s *composeService) ensureVolume(ctx context.Context, name string, volume types.VolumeConfig, project *types.Project) (string, error) { |
| 1598 | inspected, err := s.apiClient().VolumeInspect(ctx, volume.Name, client.VolumeInspectOptions{}) |
| 1599 | if err != nil { |
| 1600 | if !errdefs.IsNotFound(err) { |
| 1601 | return "", err |
| 1602 | } |
| 1603 | if volume.External { |
| 1604 | return "", fmt.Errorf("external volume %q not found", volume.Name) |
| 1605 | } |
| 1606 | err = s.createVolume(ctx, volume) |
| 1607 | return volume.Name, err |
| 1608 | } |
| 1609 | |
| 1610 | if volume.External { |
| 1611 | return volume.Name, nil |
| 1612 | } |
| 1613 | |
| 1614 | // Volume exists with name, but let's double-check this is the expected one |
| 1615 | p, ok := inspected.Volume.Labels[api.ProjectLabel] |
| 1616 | if !ok { |
| 1617 | logrus.Warnf("volume %q already exists but was not created by Docker Compose. Use `external: true` to use an existing volume", volume.Name) |
| 1618 | } |
| 1619 | if ok && p != project.Name { |
| 1620 | logrus.Warnf("volume %q already exists but was created for project %q (expected %q). Use `external: true` to use an existing volume", volume.Name, p, project.Name) |
| 1621 | } |
| 1622 | |
| 1623 | expected, err := VolumeHash(volume) |
| 1624 | if err != nil { |
| 1625 | return "", err |
| 1626 | } |
| 1627 | actual, ok := inspected.Volume.Labels[api.ConfigHashLabel] |
| 1628 | if ok && actual != expected { |
| 1629 | msg := fmt.Sprintf("Volume %q exists but doesn't match configuration in compose file. Recreate (data will be lost)?", volume.Name) |
| 1630 | confirm, err := s.prompt(msg, false) |
| 1631 | if err != nil { |
| 1632 | return "", err |
| 1633 | } |
| 1634 | if confirm { |
| 1635 | err = s.removeDivergedVolume(ctx, name, volume, project) |
| 1636 | if err != nil { |
| 1637 | return "", err |
| 1638 | } |
| 1639 | return volume.Name, s.createVolume(ctx, volume) |
| 1640 | } |
| 1641 | } |
| 1642 | return inspected.Volume.Name, nil |
| 1643 | } |
| 1644 | |
| 1645 | func (s *composeService) removeDivergedVolume(ctx context.Context, name string, volume types.VolumeConfig, project *types.Project) error { |
| 1646 | // Remove services mounting divergent volume |
no test coverage detected