chef-systemd icon indicating copy to clipboard operation
chef-systemd copied to clipboard

systemd_network resource does not allow multiple addresses

Open schrd opened this issue 7 years ago • 3 comments

A network unit file can specify multiple static addresses for an interface. Even mixing of IPv4 and IPv6 addresses is possible. A working example would look like

[Match]
Name = en* eth*

[Network]
DHCP = no
Address = 192.168.121.4/24
Address = 192.168.121.2/24

If I specify a systemd_network resource such as

systemd_network 'static' do
  match_name 'en* eth*'
  network_address ['192.168.121.4/24', '192.168.121.2/24']
end

produces an invalid file which systemd-networkd rejects:

[Match]
Name = en* eth*

[Network]
DHCP = no
Address = 192.168.121.4/24 192.168.121.2/24

To me it looks like SystemdCookbook::Mixin::PropertyHashConversion::InstanceMethods#option_value is causing the issue.

The systemd_unit resource correctly converts arrays to multiple entries:

u = systemd_unit 'test.service' do
  content({
    Unit: {
      Description: ['Foo', 'bar']
    }
  })
end

file "/tmp/test.ini" do
  content u.to_ini
end

produces

[Unit]
Description = Foo
Description = bar

schrd avatar Aug 10 '18 09:08 schrd

thanks for the report @schrd :)

some variation of this comes up every once in a while and i'm still not super sure what a workable solution looks like... option_value is definitely designed to convert arrays into space-separated strings, because that's how systemd handles array-type arguments (e.g. Before=, After=, which take lists of units). for now, i think using the precursor property will let you inject an extra address field.

in the past, the way we've worked around the limitation has been to use drop-in resources or the precursor property when needing to provide the same directive more than once.

i'm open to any backwards-compatible suggestions!

nathwill avatar Aug 12 '18 00:08 nathwill

@nathwill what do you think about using classes to differentiate between the two ways of handling arrays? See #138

schrd avatar Aug 13 '18 11:08 schrd

@schrd I also ran into this issue while trying to assign multiple vlans on one interface. After playing around a little with different solutions i went for the "ruby is anarchy" one and defined it like this:

systemd_network 'eth0' do
  match_name 'eth0'
  network_vlan "eth0.2\nVLAN = eth0.8"
end

IMHO this is ugly, but still better than defining a switchcase for each possible argument to differentiate between the different styles that are accepted by systemd configs. Maybe this should rather be fixed in systemd.

jklare avatar Sep 06 '18 10:09 jklare