From 9968dc6139eaf46f86bf789957db1fb3b6e9e22f Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Thu, 21 Apr 2016 15:05:40 +0200 Subject: [PATCH 01/10] Move config_device into puppet manifest --- manifests/device.pp | 8 +++++++- templates/config_device-changes.yaml.erb | 13 ------------- 2 files changed, 7 insertions(+), 14 deletions(-) delete mode 100644 templates/config_device-changes.yaml.erb diff --git a/manifests/device.pp b/manifests/device.pp index 638b316..5e4dcda 100644 --- a/manifests/device.pp +++ b/manifests/device.pp @@ -20,7 +20,13 @@ $instance_config_xml_path = "${home_path}/config.xml" if $ensure == 'present' { - $changes = parseyaml( template('syncthing/config_device-changes.yaml.erb') ) + $changes = [ + "set device[#attribute/id='${id}']/#attribute/id ${id}", + "set device[#attribute/id='${id}']/#attribute/name ${device_name}", + "set device[#attribute/id='${id}']/#attribute/compression ${compression}", + "set device[#attribute/id='${id}']/#attribute/introducer ${introducer}", + "set device[#attribute/id='${id}']/#attribute/introducer ${introducer}", + ] } else { $changes = "rm device[#attribute/id='${id}']" } diff --git a/templates/config_device-changes.yaml.erb b/templates/config_device-changes.yaml.erb deleted file mode 100644 index ac28a0d..0000000 --- a/templates/config_device-changes.yaml.erb +++ /dev/null @@ -1,13 +0,0 @@ ---- - - 'set device[#attribute/id="<%= @id %>"]/#attribute/id <%= @id %>' - - 'set device[#attribute/id="<%= @id %>"]/#attribute/name <%= @device_name %>' - - 'set device[#attribute/id="<%= @id %>"]/#attribute/compression <%- if @compression -%>true<%- else -%>false<%- end -%>' - - 'set device[#attribute/id="<%= @id %>"]/#attribute/introducer <%- if @introducer -%>true<%- else -%>false<%- end -%>' - - 'set device[#attribute/id="<%= @id %>"]/address/#text <%= @address %>' -<%- @options.each do |key, value| - if value -%> - - 'set device[#attribute/id="<%= @id %>"]/<%= key %>/#text <%= value %>' - <%- else -%> - - 'rm device[#attribute/id="<%= @id %>"]/<%= key %>' -<%- end - end -%> \ No newline at end of file From 55b8ea2848d63c59532e01f39604b5d1cfb51fa3 Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Sun, 24 Apr 2016 16:09:18 +0200 Subject: [PATCH 02/10] Set augeas parameters globally in device.pp --- manifests/device.pp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/manifests/device.pp b/manifests/device.pp index 5e4dcda..338d60b 100644 --- a/manifests/device.pp +++ b/manifests/device.pp @@ -19,6 +19,19 @@ $instance_config_xml_path = "${home_path}/config.xml" + Augeas { + incl => $instance_config_xml_path, + lens => 'Xml.lns', + context => "/files${instance_config_xml_path}/configuration", + notify => [ + Service['syncthing'], + ], + + require => [ + Exec["create syncthing instance ${home_path}"], + ], + } + if $ensure == 'present' { $changes = [ "set device[#attribute/id='${id}']/#attribute/id ${id}", @@ -32,17 +45,6 @@ } augeas { "configure instance ${home_path} device ${id}": - incl => $instance_config_xml_path, - lens => 'Xml.lns', - context => "/files${instance_config_xml_path}/configuration", changes => $changes, - - notify => [ - Service['syncthing'], - ], - - require => [ - Exec["create syncthing instance ${home_path}"], - ], } } From 1e2b4bd2ef1be30ef95c500ad3c036bc8ac2c8b0 Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Sun, 24 Apr 2016 16:30:51 +0200 Subject: [PATCH 03/10] Improve logic of adding and removing devices --- manifests/device.pp | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/manifests/device.pp b/manifests/device.pp index 338d60b..ebcc5f9 100644 --- a/manifests/device.pp +++ b/manifests/device.pp @@ -33,18 +33,39 @@ } if $ensure == 'present' { - $changes = [ - "set device[#attribute/id='${id}']/#attribute/id ${id}", - "set device[#attribute/id='${id}']/#attribute/name ${device_name}", - "set device[#attribute/id='${id}']/#attribute/compression ${compression}", - "set device[#attribute/id='${id}']/#attribute/introducer ${introducer}", - "set device[#attribute/id='${id}']/#attribute/introducer ${introducer}", - ] + + augeas { "update device ${id} in instance ${home_path}": + changes => [ + "set device[#attribute/id='${id}']/#attribute/name ${device_name}", + "set device[#attribute/id='${id}']/#attribute/compression ${compression}", + "set device[#attribute/id='${id}']/#attribute/introducer ${introducer}", + ], + onlyif => "match device[#attribute/id='${id}'] size > 0", + } + + augeas { "create device ${id} in instance ${home_path}": + changes => [ + "ins #text after device[last()]", + "set device[last()]/following-sibling::#text[1] ' '", + "ins device after device[last()]/following-sibling::#text[1]", + "set device[last()]/#attribute/id ${id}", + "set device[#attribute/id='${id}']/#attribute/name ${device_name}", + "set device[#attribute/id='${id}']/#attribute/compression ${compression}", + "set device[#attribute/id='${id}']/#attribute/introducer ${introducer}", + ], + onlyif => "match device[#attribute/id='${id}'] size == 0", + } + } else { - $changes = "rm device[#attribute/id='${id}']" - } - augeas { "configure instance ${home_path} device ${id}": - changes => $changes, + augeas { "remove device ${id} in instance ${home_path}": + changes => [ + "rm device[#attribute/id='${id}']/preceding-sibling::#text[1]", + "rm device[#attribute/id='${id}']", + ], + onlyif => "match device[#attribute/id='${id}'] size > 0", + } + } + } From 286c6b40ee875586952b3eee9af964192bced1e2 Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Fri, 22 Apr 2016 10:04:16 +0200 Subject: [PATCH 04/10] Validate compression argument --- manifests/device.pp | 2 ++ manifests/params.pp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/manifests/device.pp b/manifests/device.pp index ebcc5f9..75a017d 100644 --- a/manifests/device.pp +++ b/manifests/device.pp @@ -17,6 +17,8 @@ fail('You must include the syncthing base class before using any syncthing defined resources') } + validate_re($compression, '^(metadata|always|never)$') + $instance_config_xml_path = "${home_path}/config.xml" Augeas { diff --git a/manifests/params.pp b/manifests/params.pp index 5c7a884..40ca829 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -31,7 +31,7 @@ $instance_options = {} - $device_compression = false + $device_compression = 'metadata' $device_introducer = false $device_options = {} } From 918155e57f69d17226f176656abca31e207f2705 Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Fri, 22 Apr 2016 14:55:22 +0200 Subject: [PATCH 05/10] Add missing device address config --- manifests/address.pp | 95 ++++++++++++++++++++++++++++++++++++++++++++ manifests/device.pp | 8 ++++ 2 files changed, 103 insertions(+) create mode 100644 manifests/address.pp diff --git a/manifests/address.pp b/manifests/address.pp new file mode 100644 index 0000000..51401dc --- /dev/null +++ b/manifests/address.pp @@ -0,0 +1,95 @@ +# Resource: syncthing::address +# +# This resource adds address entry to specified device in config.xml +define syncthing::address +( + $home_path, + $device_id, + $address, + + $ensure = 'present', +) +{ + if ! defined(Class['syncthing']) { + fail('You must include the syncthing base class before using any syncthing defined resources') + } + + $instance_config_xml_path = "${home_path}/config.xml" + + Augeas { + incl => $instance_config_xml_path, + lens => 'Xml.lns', + context => "/files${instance_config_xml_path}/configuration", + notify => [ + Service['syncthing'], + ], + + require => [ + Class['syncthing'], + ], + } + + if $ensure == 'present' { + + # Add first element with top padding + augeas { "create address ${address} for device ${device_id} in instance ${home_path}": + changes => [ + "set device[#attribute/id='${device_id}']/#text[1] '\n '", + "ins address after device[#attribute/id='${device_id}']/#text[last()]", + "set device[#attribute/id='${device_id}']/address[last()]/#text '${address}'", + "ins #text after device[#attribute/id='${device_id}']/address[last()]", + "set device[#attribute/id='${device_id}']/address[last()]/following-sibling::#text[1] '\n '", + ], + onlyif => "match device[#attribute/id='${device_id}']/address size == 0", + } + + # Add additional element + augeas { "create additional address ${address} for device ${device_id} in instance ${home_path}": + changes => [ + "ins address after device[#attribute/id='${device_id}']/address[last()]", + "set device[#attribute/id='${device_id}']/address[last()]/#text '${address}'", + "ins #text before device[#attribute/id='${device_id}']/address[last()]", + "set device[#attribute/id='${device_id}']/address[last()]/preceding-sibling::#text[1] ' '", + ], + onlyif => "match device[#attribute/id='${device_id}']/address[#text='${address}'] size == 0", + require => Augeas["create address ${address} for device ${device_id} in instance ${home_path}"], + } + + # Set up proper bottom padding + augeas { "create bottom padding for address ${address} for device ${device_id} in instance ${home_path}": + changes => [ + "set device[#attribute/id='${device_id}']/#text[last()] ' '", + ], + onlyif => "match device[#attribute/id='${device_id}']/address size > 0", + require => Augeas["create additional address ${address} for device ${device_id} in instance ${home_path}"], + } + + } else { + + # Remove element + augeas { "remove address ${address} for device ${device_id} in instance ${home_path}": + changes => [ + "rm device[#attribute/id='${device_id}']/address[#text='${address}']/following-sibling::#text[1]", + "rm device[#attribute/id='${device_id}']/address[#text='${address}']", + ], + } + + # Remove all paddings if there is no more address element + augeas { "remove padding for device ${device_id} in instance ${home_path}": + changes => "rm device[#attribute/id='${device_id}']/#text", + onlyif => "match device[#attribute/id='${device_id}']/address size == 0", + require => Augeas["create bottom padding for address ${address} for device ${device_id} in instance ${home_path}"], + } + + # Set up prosper bottom padding after removing element + augeas { "create bottom padding for address ${address} for device ${device_id} in instance ${home_path}": + changes => [ + "set device[#attribute/id='${device_id}']/#text[last()] ' '", + ], + onlyif => "match device[#attribute/id='${device_id}']/address size > 0", + require => Augeas["remove address ${address} for device ${device_id} in instance ${home_path}"], + } + + } + +} diff --git a/manifests/device.pp b/manifests/device.pp index 75a017d..649eabf 100644 --- a/manifests/device.pp +++ b/manifests/device.pp @@ -56,6 +56,7 @@ "set device[#attribute/id='${id}']/#attribute/introducer ${introducer}", ], onlyif => "match device[#attribute/id='${id}'] size == 0", + before => Syncthing::Address["${id}:${address}"], } } else { @@ -70,4 +71,11 @@ } + ::syncthing::address{ "${id}:${address}": + home_path => $home_path, + device_id => $id, + address => $address, + ensure => $ensure, + } + } From 2e449cc2e3f06cc3f5f2e6bc435ffcac7f52cf70 Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Mon, 25 Apr 2016 10:31:35 +0200 Subject: [PATCH 06/10] Validate introducer argument --- manifests/device.pp | 1 + 1 file changed, 1 insertion(+) diff --git a/manifests/device.pp b/manifests/device.pp index 649eabf..cb121fa 100644 --- a/manifests/device.pp +++ b/manifests/device.pp @@ -18,6 +18,7 @@ } validate_re($compression, '^(metadata|always|never)$') + validate_bool($introducer) $instance_config_xml_path = "${home_path}/config.xml" From ac50f591678fa6e2b0285d9f841d49746c7fdbbd Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Tue, 24 May 2016 11:57:05 +0200 Subject: [PATCH 07/10] Add syncthing::element resource This class is universal resource to add elements to XML tree with proper aligment. Currently, it does not support many depths. --- manifests/element.pp | 101 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 manifests/element.pp diff --git a/manifests/element.pp b/manifests/element.pp new file mode 100644 index 0000000..b6c1542 --- /dev/null +++ b/manifests/element.pp @@ -0,0 +1,101 @@ +# Resource: syncthing::element +# +# This is private class, which is used to add elements to XML file +define syncthing::element +( + $home_path, + $element, + $parent_element, + $parent_id, + $value, + + $ensure = 'present', +) +{ + + # Private class checking + assert_private("Use of private class ${name} by ${caller_module_name}") + + # Hacky indent definition + $indent_1 = ' ' + $indent_2 = ' ' + + $instance_config_xml_path = "${home_path}/config.xml" + + Augeas { + incl => $instance_config_xml_path, + lens => 'Xml.lns', + context => "/files${instance_config_xml_path}/configuration", + # notify => [ + # Service['syncthing'], + #], + + require => [ + Exec["create syncthing instance ${home_path}"], + ], + } + + if $ensure == 'present' { + + # Add first element with top padding + augeas { "create ${element} ${value} for ${parent_element} ${parent_id} in instance ${home_path}": + changes => [ + "set ${parent_element}[#attribute/id='${parent_id}']/#text[1] '\n${indent_2}'", + "ins ${element} after ${parent_element}[#attribute/id='${parent_id}']/#text[last()]", + "set ${parent_element}[#attribute/id='${parent_id}']/${element}[last()]/#text '${value}'", + "ins #text after ${parent_element}[#attribute/id='${parent_id}']/${element}[last()]", + "set ${parent_element}[#attribute/id='${parent_id}']/${element}[last()]/following-sibling::#text[1] '\n${indent_2}'", + ], + onlyif => "match ${parent_element}[#attribute/id='${parent_id}']/*[label() != '#attribute'] size == 0", + } + + # Add additional element + augeas { "create additional ${element} ${value} for ${parent_element} ${parent_id} in instance ${home_path}": + changes => [ + "ins ${element} after ${parent_element}[#attribute/id='${parent_id}']/#text[last()]/preceding-sibling::*[1]", + "set ${parent_element}[#attribute/id='${parent_id}']/${element}[last()]/#text '${value}'", + "ins #text before ${parent_element}[#attribute/id='${parent_id}']/${element}[last()]", + "set ${parent_element}[#attribute/id='${parent_id}']/${element}[last()]/preceding-sibling::#text[1] '${indent_2}'", + ], + onlyif => "match ${parent_element}[#attribute/id='${parent_id}']/${element}[#text='${value}'] size == 0", + require => Augeas["create ${element} ${value} for ${parent_element} ${parent_id} in instance ${home_path}"], + } + + # Set up proper bottom padding + augeas { "create bottom padding for ${element} ${value} for ${parent_element} ${parent_id} in instance ${home_path}": + changes => [ + "set ${parent_element}[#attribute/id='${parent_id}']/#text[last()] '${indent_1}'", + ], + onlyif => "match ${parent_element}[#attribute/id='${parent_id}']/*[label() != '#attribute'] size > 0", + require => Augeas["create additional ${element} ${value} for ${parent_element} ${parent_id} in instance ${home_path}"], + } + + } else { + + # Remove element + augeas { "remove ${element} ${value} for ${parent_element} ${parent_id} in instance ${home_path}": + changes => [ + "rm ${parent_element}[#attribute/id='${parent_id}']/${element}[#text='${value}']/following-sibling::#text[1]", + "rm ${parent_element}[#attribute/id='${parent_id}']/${element}[#text='${value}']", + ], + } + + # Remove all paddings if there is no more elements + augeas { "remove padding for ${parent_element} ${parent_id} in instance ${home_path}": + changes => "rm ${parent_element}[#attribute/id='${parent_id}']/#text", + onlyif => "match ${parent_element}[#attribute/id='${parent_id}']/*[label() != '#attribute'] size == 1", + require => Augeas["create bottom padding for ${element} ${value} for ${parent_element} ${parent_id} in instance ${home_path}"], + } + + # Set up prosper bottom padding after removing element + augeas { "create bottom padding for ${element} ${value} for ${parent_element} ${parent_id} in instance ${home_path}": + changes => [ + "set ${parent_element}[#attribute/id='${parent_id}']/#text[last()] '${indent_1}'", + ], + onlyif => "match ${parent_element}[#attribute/id='${parent_id}']/*[label() != '#attribute'] size > 0", + require => Augeas["remove ${element} ${value} for ${parent_element} ${parent_id} in instance ${home_path}"], + } + + } + +} From 52498305a7e736ad5c009019b1d193407eef17aa Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Tue, 24 May 2016 12:01:06 +0200 Subject: [PATCH 08/10] address: use syncthing::element to manage entries --- manifests/address.pp | 84 ++++---------------------------------------- 1 file changed, 7 insertions(+), 77 deletions(-) diff --git a/manifests/address.pp b/manifests/address.pp index 51401dc..ee1e49e 100644 --- a/manifests/address.pp +++ b/manifests/address.pp @@ -14,82 +14,12 @@ fail('You must include the syncthing base class before using any syncthing defined resources') } - $instance_config_xml_path = "${home_path}/config.xml" - - Augeas { - incl => $instance_config_xml_path, - lens => 'Xml.lns', - context => "/files${instance_config_xml_path}/configuration", - notify => [ - Service['syncthing'], - ], - - require => [ - Class['syncthing'], - ], + syncthing::element{ "set device ${device_id} address ${address} in instance ${home_path}": + ensure => $ensure, + home_path => $home_path, + element => 'address', + value => $address, + parent_element => 'device', + parent_id => $device_id, } - - if $ensure == 'present' { - - # Add first element with top padding - augeas { "create address ${address} for device ${device_id} in instance ${home_path}": - changes => [ - "set device[#attribute/id='${device_id}']/#text[1] '\n '", - "ins address after device[#attribute/id='${device_id}']/#text[last()]", - "set device[#attribute/id='${device_id}']/address[last()]/#text '${address}'", - "ins #text after device[#attribute/id='${device_id}']/address[last()]", - "set device[#attribute/id='${device_id}']/address[last()]/following-sibling::#text[1] '\n '", - ], - onlyif => "match device[#attribute/id='${device_id}']/address size == 0", - } - - # Add additional element - augeas { "create additional address ${address} for device ${device_id} in instance ${home_path}": - changes => [ - "ins address after device[#attribute/id='${device_id}']/address[last()]", - "set device[#attribute/id='${device_id}']/address[last()]/#text '${address}'", - "ins #text before device[#attribute/id='${device_id}']/address[last()]", - "set device[#attribute/id='${device_id}']/address[last()]/preceding-sibling::#text[1] ' '", - ], - onlyif => "match device[#attribute/id='${device_id}']/address[#text='${address}'] size == 0", - require => Augeas["create address ${address} for device ${device_id} in instance ${home_path}"], - } - - # Set up proper bottom padding - augeas { "create bottom padding for address ${address} for device ${device_id} in instance ${home_path}": - changes => [ - "set device[#attribute/id='${device_id}']/#text[last()] ' '", - ], - onlyif => "match device[#attribute/id='${device_id}']/address size > 0", - require => Augeas["create additional address ${address} for device ${device_id} in instance ${home_path}"], - } - - } else { - - # Remove element - augeas { "remove address ${address} for device ${device_id} in instance ${home_path}": - changes => [ - "rm device[#attribute/id='${device_id}']/address[#text='${address}']/following-sibling::#text[1]", - "rm device[#attribute/id='${device_id}']/address[#text='${address}']", - ], - } - - # Remove all paddings if there is no more address element - augeas { "remove padding for device ${device_id} in instance ${home_path}": - changes => "rm device[#attribute/id='${device_id}']/#text", - onlyif => "match device[#attribute/id='${device_id}']/address size == 0", - require => Augeas["create bottom padding for address ${address} for device ${device_id} in instance ${home_path}"], - } - - # Set up prosper bottom padding after removing element - augeas { "create bottom padding for address ${address} for device ${device_id} in instance ${home_path}": - changes => [ - "set device[#attribute/id='${device_id}']/#text[last()] ' '", - ], - onlyif => "match device[#attribute/id='${device_id}']/address size > 0", - require => Augeas["remove address ${address} for device ${device_id} in instance ${home_path}"], - } - - } - } From d81f7bec6bf0e76f5b10f2fa270b6b3879449c63 Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Tue, 24 May 2016 12:08:33 +0200 Subject: [PATCH 09/10] device: reuse missing options parameter with deprecation warning --- manifests/device.pp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/manifests/device.pp b/manifests/device.pp index cb121fa..c3a5091 100644 --- a/manifests/device.pp +++ b/manifests/device.pp @@ -20,6 +20,10 @@ validate_re($compression, '^(metadata|always|never)$') validate_bool($introducer) + unless empty($options) { + warning('DEPRECATION: $options parameter support will be removed in future release. Please use syncthing::address class instead.') + } + $instance_config_xml_path = "${home_path}/config.xml" Augeas { @@ -60,6 +64,20 @@ before => Syncthing::Address["${id}:${address}"], } + $options.each | $option, $value | { + ::syncthing::element { "set device ${id} option ${option} in instance ${home_path}": + home_path => $home_path, + parent_element => 'device', + parent_id => $id, + element => $option, + value => $value, + require => [ + Augeas["update device ${id} in instance ${home_path}"], + Augeas["create device ${id} in instance ${home_path}"], + ], + } + } + } else { augeas { "remove device ${id} in instance ${home_path}": From 520007ea6993da8bc9f9e9f2d60860f997bca605 Mon Sep 17 00:00:00 2001 From: Mateusz Gozdek Date: Tue, 24 May 2016 12:09:08 +0200 Subject: [PATCH 10/10] device: allow to specify multiple addresses --- manifests/device.pp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/manifests/device.pp b/manifests/device.pp index c3a5091..3349dff 100644 --- a/manifests/device.pp +++ b/manifests/device.pp @@ -61,10 +61,9 @@ "set device[#attribute/id='${id}']/#attribute/introducer ${introducer}", ], onlyif => "match device[#attribute/id='${id}'] size == 0", - before => Syncthing::Address["${id}:${address}"], } - $options.each | $option, $value | { + each($options) | $option, $value | { ::syncthing::element { "set device ${id} option ${option} in instance ${home_path}": home_path => $home_path, parent_element => 'device', @@ -77,7 +76,15 @@ ], } } - + any2array($address).each | $addr | { + ::syncthing::address{ "set device ${id} address ${addr} in instance ${home_path}": + home_path => $home_path, + device_id => $id, + address => $addr, + ensure => $ensure, + require => Augeas["create device ${id} in instance ${home_path}"], + } + } } else { augeas { "remove device ${id} in instance ${home_path}": @@ -90,11 +97,4 @@ } - ::syncthing::address{ "${id}:${address}": - home_path => $home_path, - device_id => $id, - address => $address, - ensure => $ensure, - } - }