Skip to content

Commit 378a6ad

Browse files
Andrew Cassidyzandeez
Andrew Cassidy
authored andcommitted
Resolve hashicorp#293 and hashicorp#358 adding ipv6_address, ipv4_address, static_ips and static_mac options for podman tasks.
Podman API version checks whether to set the properties directly or whether to use the new PerNetworkOptions framework. ipv6_address and ipv4_address are provided for backwards compatibility, and for compatibility with docker. For Podman 4.0.0 these are merged into static_ips and sent as a PerNetorkOptions entry for the default network. Added API version check, static mac support, new array-based option for static IPs to match the podman API Trying moving the object to ContanerNetworkConfig
1 parent 7c74d43 commit 378a6ad

File tree

3 files changed

+107
-3
lines changed

3 files changed

+107
-3
lines changed

api/structs.go

+20
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,19 @@ type ContainerCgroupConfig struct {
326326
CgroupParent string `json:"cgroup_parent,omitempty"`
327327
}
328328

329+
// PerNetworkOptions allows you to set options per network the container is
330+
// attached to.
331+
type PerNetworkOptions struct {
332+
// Aliases contains a list of names which the dns server should resolve to this container. Should only be set when DNSEnabled is true on the Network. If aliases are set but there is no dns support for this network the network interface implementation should ignore this and NOT error. Optional.
333+
Aliases []string `json:"aliases,omitempty"`
334+
// InterfaceName for this container. Required in the backend. Optional in the frontend. Will be filled with ethX (where X is a integer) when empty.
335+
InterfaceName string `json:"interface_name,omitempty"`
336+
// StaticIPs for this container. Optional.
337+
StaticIPs []*net.IP `json:"static_ips,omitempty"`
338+
// StaticMac for this container. Optional.
339+
StaticMac *net.HardwareAddr `json:"static_mac,omitempty"`
340+
}
341+
329342
// ContainerNetworkConfig contains information on a container's network
330343
// configuration.
331344
type ContainerNetworkConfig struct {
@@ -407,6 +420,13 @@ type ContainerNetworkConfig struct {
407420
// Podman, and instead sourced from the image.
408421
// Conflicts with HostAdd.
409422
UseImageHosts bool `json:"use_image_hosts,omitempty"`
423+
// Map of networks names or ids that the container should join. You can
424+
// request additional settings for each network, you can set network
425+
// aliases, static ips, static mac address and the network interface name
426+
// for this container on the specific network. If the map is empty and the
427+
// bridge network mode is set the container will be joined to the default
428+
// network.
429+
Networks map[string]PerNetworkOptions `json:"networks,omitempty"`
410430
}
411431

412432
// ContainerResourceConfig contains information on container resource limits.

config.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,13 @@ var (
9292
hclspec.NewAttr("image_pull_timeout", "string", false),
9393
hclspec.NewLiteral(`"5m"`),
9494
),
95-
"init": hclspec.NewAttr("init", "bool", false),
96-
"init_path": hclspec.NewAttr("init_path", "string", false),
97-
"labels": hclspec.NewAttr("labels", "list(map(string))", false),
95+
"init": hclspec.NewAttr("init", "bool", false),
96+
"init_path": hclspec.NewAttr("init_path", "string", false),
97+
"ipv4_address": hclspec.NewAttr("ipv4_address", "string", false),
98+
"ipv6_address": hclspec.NewAttr("ipv6_address", "string", false),
99+
"static_ips": hclspec.NewAttr("static_ips", "list(string)", false),
100+
"static_macs": hclspec.NewAttr("static_macs", "list(string)", false),
101+
"labels": hclspec.NewAttr("labels", "list(map(string))", false),
98102
"logging": hclspec.NewBlock("logging", false, hclspec.NewObject(map[string]*hclspec.Spec{
99103
"driver": hclspec.NewAttr("driver", "string", false),
100104
"options": hclspec.NewAttr("options", "list(map(string))", false),
@@ -203,6 +207,10 @@ type TaskConfig struct {
203207
Hostname string `codec:"hostname"`
204208
Image string `codec:"image"`
205209
ImagePullTimeout string `codec:"image_pull_timeout"`
210+
IPv4Address string `codec:"ipv4_address"`
211+
IPv6Address string `codec:"ipv6_address"`
212+
StaticIPs []string `codec:"static_ips"`
213+
StaticMAC string `codec:"static_mac"`
206214
InitPath string `codec:"init_path"`
207215
Logging TaskLoggingConfig `codec:"logging"`
208216
Labels hclutils.MapStrStr `codec:"labels"`

driver.go

+76
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/containers/image/v5/pkg/shortnames"
2323
"github.com/containers/image/v5/types"
2424
"github.com/hashicorp/go-hclog"
25+
version2 "github.com/hashicorp/go-version"
2526
"github.com/hashicorp/nomad-driver-podman/api"
2627
"github.com/hashicorp/nomad-driver-podman/registry"
2728
"github.com/hashicorp/nomad-driver-podman/version"
@@ -688,6 +689,81 @@ func (d *Driver) StartTask(cfg *drivers.TaskConfig) (*drivers.TaskHandle, *drive
688689
}
689690
}
690691

692+
// Process static IP and MAC configuration. IPv4Address and IPv6Address are
693+
// provided for compatibility with Docker, but the podman API v4 exposes a
694+
// list of static addresses too. Add all three options to the API call for
695+
// the default network
696+
if driverConfig.StaticMAC != "" || driverConfig.IPv4Address != "" || driverConfig.IPv6Address != "" || len(driverConfig.StaticIPs) > 0 {
697+
apiVersion, _ := d.podman.Ping(d.ctx)
698+
versionValue, _ := version2.NewVersion(apiVersion)
699+
versionCheck, _ := version2.NewConstraint(">=4.0.0")
700+
701+
if versionCheck.Check(versionValue) {
702+
// Podman API v4 uses PerNetworkOptions. For now, we'll just use the
703+
// default network.
704+
705+
netOpts := api.PerNetworkOptions{}
706+
netOpts.StaticIPs = []*net.IP{}
707+
708+
if driverConfig.IPv4Address != "" {
709+
parsedIP := net.ParseIP(driverConfig.IPv4Address)
710+
if parsedIP != nil {
711+
netOpts.StaticIPs = append(netOpts.StaticIPs, &parsedIP)
712+
}
713+
}
714+
715+
if driverConfig.IPv6Address != "" {
716+
parsedIPv6 := net.ParseIP(driverConfig.IPv6Address)
717+
if parsedIPv6 != nil {
718+
netOpts.StaticIPs = append(netOpts.StaticIPs, &parsedIPv6)
719+
}
720+
}
721+
722+
if len(driverConfig.StaticIPs) > 0 {
723+
for _, ip := range driverConfig.StaticIPs {
724+
parsedIP := net.ParseIP(ip)
725+
if parsedIP != nil {
726+
netOpts.StaticIPs = append(netOpts.StaticIPs, &parsedIP)
727+
}
728+
}
729+
}
730+
731+
// Process Static MAC configuration
732+
if driverConfig.StaticMAC != "" {
733+
parsedMAC, err := net.ParseMAC(driverConfig.StaticMAC)
734+
if err == nil && parsedMAC != nil {
735+
netOpts.StaticMac = &parsedMAC
736+
}
737+
}
738+
739+
createOpts.Networks = map[string]api.PerNetworkOptions{"default": netOpts}
740+
} else {
741+
// Before version 4, there were StaticIP, StaticIPv6 and StaticMAC properties
742+
743+
if driverConfig.IPv4Address != "" {
744+
parsedIP := net.ParseIP(driverConfig.IPv4Address)
745+
if parsedIP != nil {
746+
createOpts.ContainerNetworkConfig.StaticIP = &parsedIP
747+
}
748+
}
749+
750+
if driverConfig.IPv6Address != "" {
751+
parsedIPv6 := net.ParseIP(driverConfig.IPv6Address)
752+
if parsedIPv6 != nil {
753+
createOpts.ContainerNetworkConfig.StaticIPv6 = &parsedIPv6
754+
}
755+
}
756+
757+
// Process Static MAC configuration
758+
if driverConfig.StaticMAC != "" {
759+
parsedMAC, err := net.ParseMAC(driverConfig.StaticMAC)
760+
if err == nil && parsedMAC != nil {
761+
createOpts.ContainerNetworkConfig.StaticMAC = &parsedMAC
762+
}
763+
}
764+
}
765+
}
766+
691767
// carefully add extra hosts (--add-host)
692768
if extraHostsErr := setExtraHosts(driverConfig.ExtraHosts, &createOpts); extraHostsErr != nil {
693769
return nil, nil, extraHostsErr

0 commit comments

Comments
 (0)