(ctx context.Context, n *types.NetworkConfig)
| 1544 | } |
| 1545 | |
| 1546 | func (s *composeService) resolveExternalNetwork(ctx context.Context, n *types.NetworkConfig) (string, error) { |
| 1547 | // NetworkInspect will match on ID prefix, so NetworkList with a name |
| 1548 | // filter is used to look for an exact match to prevent e.g. a network |
| 1549 | // named `db` from getting erroneously matched to a network with an ID |
| 1550 | // like `db9086999caf` |
| 1551 | res, err := s.apiClient().NetworkList(ctx, client.NetworkListOptions{ |
| 1552 | Filters: make(client.Filters).Add("name", n.Name), |
| 1553 | }) |
| 1554 | if err != nil { |
| 1555 | return "", err |
| 1556 | } |
| 1557 | networks := res.Items |
| 1558 | |
| 1559 | if len(networks) == 0 { |
| 1560 | // in this instance, n.Name is really an ID |
| 1561 | sn, err := s.apiClient().NetworkInspect(ctx, n.Name, client.NetworkInspectOptions{}) |
| 1562 | if err == nil { |
| 1563 | networks = append(networks, network.Summary{Network: sn.Network.Network}) |
| 1564 | } else if !errdefs.IsNotFound(err) { |
| 1565 | return "", err |
| 1566 | } |
| 1567 | } |
| 1568 | |
| 1569 | // NetworkList API doesn't return the exact name match, so we can retrieve more than one network with a request |
| 1570 | networks = slices.DeleteFunc(networks, func(net network.Summary) bool { |
| 1571 | // this function is called during the rebuild stage of `compose watch`. |
| 1572 | // we still require just one network back, but we need to run the search on the ID |
| 1573 | return net.Name != n.Name && net.ID != n.Name |
| 1574 | }) |
| 1575 | |
| 1576 | switch len(networks) { |
| 1577 | case 1: |
| 1578 | return networks[0].ID, nil |
| 1579 | case 0: |
| 1580 | enabled, err := s.isSwarmEnabled(ctx) |
| 1581 | if err != nil { |
| 1582 | return "", err |
| 1583 | } |
| 1584 | if enabled { |
| 1585 | // Swarm nodes do not register overlay networks that were |
| 1586 | // created on a different node unless they're in use. |
| 1587 | // So we can't preemptively check network exists, but |
| 1588 | // networkAttach will later fail anyway if network actually doesn't exist |
| 1589 | return "swarm", nil |
| 1590 | } |
| 1591 | return "", fmt.Errorf("network %s declared as external, but could not be found", n.Name) |
| 1592 | default: |
| 1593 | return "", fmt.Errorf("multiple networks with name %q were found. Use network ID as `name` to avoid ambiguity", n.Name) |
| 1594 | } |
| 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{}) |
no test coverage detected