mirror of
https://github.com/containers/podman.git
synced 2025-08-06 19:44:14 +08:00
Merge pull request #23814 from ruihe774/quadlet-network-container
quadlet: support container network reusing
This commit is contained in:
@ -638,6 +638,10 @@ As a special case, if the `name` of the network ends with `.network`, a Podman n
|
|||||||
a dependency on the `$name-network.service`. Such a network can be automatically
|
a dependency on the `$name-network.service`. Such a network can be automatically
|
||||||
created by using a `$name.network` Quadlet file.
|
created by using a `$name.network` Quadlet file.
|
||||||
|
|
||||||
|
Another special case is that if the `name` ends with `.container`,
|
||||||
|
the container will reuse the network stack of another container created by `$name.container`.
|
||||||
|
The generated systemd service contains a dependency on `$name.service`.
|
||||||
|
|
||||||
This key can be listed multiple times.
|
This key can be listed multiple times.
|
||||||
|
|
||||||
### `NetworkAlias=`
|
### `NetworkAlias=`
|
||||||
|
@ -921,6 +921,13 @@ func ConvertContainer(container *parser.UnitFile, isUser bool, unitsInfoMap map[
|
|||||||
|
|
||||||
service.AddCmdline(ServiceGroup, "ExecStart", podman.Args)
|
service.AddCmdline(ServiceGroup, "ExecStart", podman.Args)
|
||||||
|
|
||||||
|
// XXX: only %N is handled.
|
||||||
|
// it is difficult to properly implement specifiers handling without consulting systemd.
|
||||||
|
resourceName := strings.ReplaceAll(containerName, "%N", unitInfo.ServiceName)
|
||||||
|
if !strings.Contains(resourceName, "%") {
|
||||||
|
unitInfo.ResourceName = resourceName
|
||||||
|
}
|
||||||
|
|
||||||
return service, nil
|
return service, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1859,23 +1866,38 @@ func addNetworks(quadletUnitFile *parser.UnitFile, groupName string, serviceUnit
|
|||||||
for _, network := range networks {
|
for _, network := range networks {
|
||||||
if len(network) > 0 {
|
if len(network) > 0 {
|
||||||
quadletNetworkName, options, found := strings.Cut(network, ":")
|
quadletNetworkName, options, found := strings.Cut(network, ":")
|
||||||
if strings.HasSuffix(quadletNetworkName, ".network") {
|
|
||||||
// the podman network name is systemd-$name if none is specified by the user.
|
isNetworkUnit := strings.HasSuffix(quadletNetworkName, ".network")
|
||||||
networkUnitInfo, ok := unitsInfoMap[quadletNetworkName]
|
isContainerUnit := strings.HasSuffix(quadletNetworkName, ".container")
|
||||||
|
|
||||||
|
if isNetworkUnit || isContainerUnit {
|
||||||
|
unitInfo, ok := unitsInfoMap[quadletNetworkName]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("requested Quadlet image %s was not found", quadletNetworkName)
|
return fmt.Errorf("requested Quadlet unit %s was not found", quadletNetworkName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX: this is usually because a '@' in service name
|
||||||
|
if len(unitInfo.ResourceName) == 0 {
|
||||||
|
return fmt.Errorf("cannot get the resource name of %s", quadletNetworkName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// the systemd unit name is $serviceName.service
|
// the systemd unit name is $serviceName.service
|
||||||
networkServiceName := networkUnitInfo.ServiceFileName()
|
serviceFileName := unitInfo.ServiceFileName()
|
||||||
|
|
||||||
serviceUnitFile.Add(UnitGroup, "Requires", networkServiceName)
|
serviceUnitFile.Add(UnitGroup, "Requires", serviceFileName)
|
||||||
serviceUnitFile.Add(UnitGroup, "After", networkServiceName)
|
serviceUnitFile.Add(UnitGroup, "After", serviceFileName)
|
||||||
|
|
||||||
if found {
|
if found {
|
||||||
network = fmt.Sprintf("%s:%s", networkUnitInfo.ResourceName, options)
|
if isContainerUnit {
|
||||||
|
return fmt.Errorf("extra options are not supported when joining another container's network")
|
||||||
|
}
|
||||||
|
network = fmt.Sprintf("%s:%s", unitInfo.ResourceName, options)
|
||||||
} else {
|
} else {
|
||||||
network = networkUnitInfo.ResourceName
|
if isContainerUnit {
|
||||||
|
network = fmt.Sprintf("container:%s", unitInfo.ResourceName)
|
||||||
|
} else {
|
||||||
|
network = unitInfo.ResourceName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
test/e2e/quadlet/network.reuse.container
Normal file
7
test/e2e/quadlet/network.reuse.container
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
## assert-podman-args "--network=container:systemd-basic"
|
||||||
|
## assert-key-is "Unit" "Requires" "basic.service"
|
||||||
|
## assert-key-is "Unit" "After" "network-online.target" "basic.service"
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=localhost/imagename
|
||||||
|
Network=basic.container
|
7
test/e2e/quadlet/network.reuse.name.container
Normal file
7
test/e2e/quadlet/network.reuse.name.container
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
## assert-podman-args "--network=container:foobar"
|
||||||
|
## assert-key-is "Unit" "Requires" "name.service"
|
||||||
|
## assert-key-is "Unit" "After" "network-online.target" "name.service"
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=localhost/imagename
|
||||||
|
Network=name.container
|
@ -1077,6 +1077,8 @@ BOGUS=foo
|
|||||||
Entry("Container - Quadlet Network overriding service name", "network.quadlet.servicename.container", []string{"service-name.network"}),
|
Entry("Container - Quadlet Network overriding service name", "network.quadlet.servicename.container", []string{"service-name.network"}),
|
||||||
Entry("Container - Quadlet Volume overriding service name", "volume.servicename.container", []string{"service-name.volume"}),
|
Entry("Container - Quadlet Volume overriding service name", "volume.servicename.container", []string{"service-name.volume"}),
|
||||||
Entry("Container - Quadlet build with multiple tags", "build.multiple-tags.container", []string{"multiple-tags.build"}),
|
Entry("Container - Quadlet build with multiple tags", "build.multiple-tags.container", []string{"multiple-tags.build"}),
|
||||||
|
Entry("Container - Reuse another container's network", "network.reuse.container", []string{"basic.container"}),
|
||||||
|
Entry("Container - Reuse another named container's network", "network.reuse.name.container", []string{"name.container"}),
|
||||||
|
|
||||||
Entry("Volume - Quadlet image (.build)", "build.quadlet.volume", []string{"basic.build"}),
|
Entry("Volume - Quadlet image (.build)", "build.quadlet.volume", []string{"basic.build"}),
|
||||||
Entry("Volume - Quadlet image (.image)", "image.quadlet.volume", []string{"basic.image"}),
|
Entry("Volume - Quadlet image (.image)", "image.quadlet.volume", []string{"basic.image"}),
|
||||||
|
Reference in New Issue
Block a user