Hi all, I have a solution (thanks to Bas):
"level1_ubuntu" data => '@(repos[ubuntu_16])'; "level1_debian" data => '@(repos[debian_12])'; "level2_list" data => '[ level1_ubuntu[hwraid], level1_debian[icinga] ]';
That works, but there are too many lines. Is there a better solution?
Too many lines?
You mean level1_<everydistrorelease>, level2_list <everylevel1_distro[KEY]>?
I kind of imagine that getindices() could help but it starts to look like a lot of programming in a state oriented DSL. Makes me think that it might be a better fit for something else outside CFEngine. Perhaps some pre-processing scripts to munge the data into the formats you need.
While you can do some of this in CFEngine, (and I am usually tempted to try quite hard because I find it entertaining, and also prize the value of not relying on anything external) it can become a yak shaving exercise that winds up having a higher maintenance burden.
While you can do some of this in CFEngine, (and I am usually tempted to try quite hard because I find it entertaining, and also prize the value of not relying on anything external) it can become a yak shaving exercise that winds up having a higher maintenance burden.
Oh, renamed variable fixed and re-sent.
Couldn't resist some fun Friday yak shaving … I think this did what you wanted.
Nearly what you had originally, just tweaked ever so slightly to move the bundle to example
and called it from __main__
.
bundle agent __main__ { methods: "example"; } bundle agent example { vars: any:: "repos" data => ' { "ubuntu_16": { "ubuntu": { "URIs": "http://cz.archive.ubuntu.com/ubuntu",
"Suites": [ "xenial", "xenial-backports", "xenial-proposed", "xenial-updates", "xenial-security" ] },
"ubuntu-security": { "URIs": "http://cz.archive.ubuntu.com/ubuntu", "Suites": [ "xenial-security" ] }, "hwraid": { "URIs": "https://hwraid.le-vert.net/debian", "Suites": [ "stretch" ] } }, "debian_12": { "debian": { "URIs": "http://deb.debian.org/debian",
"Suites": [ "bookworm", "bookworm-backports", "bookworm-proposed-updates", "bookworm-updates" ] },
"debian-security": { "URIs": "http://deb.debian.org/debian-security", "Suites": [ "bookworm-security" ] }, "icinga": { "URIs": "https://packages.icinga.com/debian", "Suites": [ "icinga-bookworm" ] } } } '; "l1_keys" slist => getindices( "repos" ); # this working
"level1_ubuntu" data => '@(repos[ubuntu_16])'; "level1_debian" data => '@(repos[debian_12])'; "level2_list" data => '[ level1_ubuntu[hwraid], level1_debian[icinga] ]'; }
# cf-agent --no-lock --show-evaluated-vars=default:example --file /tmp/example.cf Variable name Variable value Meta tags Comment default:example.l1_keys {"ubuntu_16","debian_12"} source=promise default:example.level1_debian {"debian":{"Suites":["bookworm","bookworm-backports","bookworm-proposed-updates","bookworm-updates"],"URIs":"http://deb.debian.org/debian"},"debian-security":{"Suites":["bookworm-security"],"URIs":"http://deb.debian.org/debian-security"},"icinga":{"Suites":["icinga-bookworm"],"URIs":"https://packages.icinga.com/debian"}} source=promise default:example.level1_ubuntu {"hwraid":{"Suites":["stretch"],"URIs":"https://hwraid.le-vert.net/debian"},"ubuntu":{"Suites":["xenial","xenial-backports","xenial-proposed","xenial-updates","xenial-security"],"URIs":"http://cz.archive.ubuntu.com/ubuntu"},"ubuntu-security":{"Suites":["xenial-security"],"URIs":"http://cz.archive.ubuntu.com/ubuntu"}} source=promise default:example.level2_list [{"Suites":["stretch"],"URIs":"https://hwraid.le-vert.net/debian"},{"Suites":["icinga-bookworm"],"URIs":"https://packages.icinga.com/debian"}] source=promise default:example.repos {"debian_12":{"debian":{"Suites":["bookworm","bookworm-backports","bookworm-proposed-updates","bookworm-updates"],"URIs":"http://deb.debian.org/debian"},"debian-security":{"Suites":["bookworm-security"],"URIs":"http://deb.debian.org/debian-security"},"icinga":{"Suites":["icinga-bookworm"],"URIs":"https://packages.icinga.com/debian"}},"ubuntu_16":{"hwraid":{"Suites":["stretch"],"URIs":"https://hwraid.le-vert.net/debian"},"ubuntu":{"Suites":["xenial","xenial-backports","xenial-proposed","xenial-updates","xenial-security"],"URIs":"http://cz.archive.ubuntu.com/ubuntu"},"ubuntu-security":{"Suites":["xenial-security"],"URIs":"http://cz.archive.ubuntu.com/ubuntu"}}} source=promise
A bit more dynamic …
Here instead of explicitly defining a variable for each level 1 key we did it dynamically by using a list derived from getindices()
.
bundle agent __main__ { methods: "example"; } bundle agent example { vars: any:: "repos" data => ' { "ubuntu_16": { "ubuntu": { "URIs": "http://cz.archive.ubuntu.com/ubuntu",
"Suites": [ "xenial", "xenial-backports", "xenial-proposed", "xenial-updates", "xenial-security" ] },
"ubuntu-security": { "URIs": "http://cz.archive.ubuntu.com/ubuntu", "Suites": [ "xenial-security" ] }, "hwraid": { "URIs": "https://hwraid.le-vert.net/debian", "Suites": [ "stretch" ] } }, "debian_12": { "debian": { "URIs": "http://deb.debian.org/debian",
"Suites": [ "bookworm", "bookworm-backports", "bookworm-proposed-updates", "bookworm-updates" ] },
"debian-security": { "URIs": "http://deb.debian.org/debian-security", "Suites": [ "bookworm-security" ] }, "icinga": { "URIs": "https://packages.icinga.com/debian", "Suites": [ "icinga-bookworm" ] } } } '; "l1_keys" slist => getindices( "repos" ); # this working # "level1_ubuntu" data => '@(repos[ubuntu_16])'; # "level1_debian" data => '@(repos[debian_12])'; # I know you had ubuntu and not the specific ubuntu but what about ubuntu_18 and 16 both being present? "level1_$(l1_keys)" data => '@(repos[$(l1_keys)])'; "level2_list" data => '[ level1_ubuntu_16[hwraid], level1_debian_12[icinga] ]'; }
# cf-agent --no-lock --show-evaluated-vars=default:example --file /tmp/example.cf Variable name Variable value Meta tags Comment default:example.l1_keys {"ubuntu_16","debian_12"} source=promise default:example.level1_debian_12 {"debian":{"Suites":["bookworm","bookworm-backports","bookworm-proposed-updates","bookworm-updates"],"URIs":"http://deb.debian.org/debian"},"debian-security":{"Suites":["bookworm-security"],"URIs":"http://deb.debian.org/debian-security"},"icinga":{"Suites":["icinga-bookworm"],"URIs":"https://packages.icinga.com/debian"}} source=promise default:example.level1_ubuntu_16 {"hwraid":{"Suites":["stretch"],"URIs":"https://hwraid.le-vert.net/debian"},"ubuntu":{"Suites":["xenial","xenial-backports","xenial-proposed","xenial-updates","xenial-security"],"URIs":"http://cz.archive.ubuntu.com/ubuntu"},"ubuntu-security":{"Suites":["xenial-security"],"URIs":"http://cz.archive.ubuntu.com/ubuntu"}} source=promise default:example.level2_list [{"Suites":["stretch"],"URIs":"https://hwraid.le-vert.net/debian"},{"Suites":["icinga-bookworm"],"URIs":"https://packages.icinga.com/debian"}] source=promise default:example.repos {"debian_12":{"debian":{"Suites":["bookworm","bookworm-backports","bookworm-proposed-updates","bookworm-updates"],"URIs":"http://deb.debian.org/debian"},"debian-security":{"Suites":["bookworm-security"],"URIs":"http://deb.debian.org/debian-security"},"icinga":{"Suites":["icinga-bookworm"],"URIs":"https://packages.icinga.com/debian"}},"ubuntu_16":{"hwraid":{"Suites":["stretch"],"URIs":"https://hwraid.le-vert.net/debian"},"ubuntu":{"Suites":["xenial","xenial-backports","xenial-proposed","xenial-updates","xenial-security"],"URIs":"http://cz.archive.ubuntu.com/ubuntu"},"ubuntu-security":{"Suites":["xenial-security"],"URIs":"http://cz.archive.ubuntu.com/ubuntu"}}} source=promise
Even more dynamic …
Here instead of explicitly listing out each variable name reference you used to expand into a data container array we first generated the string you would have used between [
and ]
.
I will leave it for others to judge but this is the sort of thing that would probably be very good to add as an acceptance test in cfengine core. Care to make a pull request?
bundle agent __main__ { methods: "example"; } bundle agent example { vars: any:: "repos" data => ' { "ubuntu_16": { "ubuntu": { "URIs": "http://cz.archive.ubuntu.com/ubuntu",
"Suites": [ "xenial", "xenial-backports", "xenial-proposed", "xenial-updates", "xenial-security" ] },
"ubuntu-security": { "URIs": "http://cz.archive.ubuntu.com/ubuntu", "Suites": [ "xenial-security" ] }, "hwraid": { "URIs": "https://hwraid.le-vert.net/debian", "Suites": [ "stretch" ] } }, "debian_12": { "debian": { "URIs": "http://deb.debian.org/debian",
"Suites": [ "bookworm", "bookworm-backports", "bookworm-proposed-updates", "bookworm-updates" ] },
"debian-security": { "URIs": "http://deb.debian.org/debian-security", "Suites": [ "bookworm-security" ] }, "icinga": { "URIs": "https://packages.icinga.com/debian", "Suites": [ "icinga-bookworm" ] } } } '; "l1_keys" slist => getindices( "repos" ); "l2_keys[$(l1_keys)]" slist => getindices( "repos[$(l1_keys)]" ); "l2_keys_combined" slist => getvalues( l2_keys ); # This combines them all so you have a list of all level2 keys # this working # "level1_ubuntu" data => '@(repos[ubuntu_16])'; # "level1_debian" data => '@(repos[debian_12])'; # I know you had ubuntu and not the specific ubuntu but what about # ubuntu_18 and 16 both being present? Then they would collide and last # one would win. So, I just use the distro verison specific key names "level1_$(l1_keys)" data => '@(repos[$(l1_keys)])', meta => { "level1_keys" }; # "level2_list" data => '[ level1_ubuntu_16[hwraid], level1_debian_12[icinga] ]'; # :/ # OK, so it wasn't a terrible amout of yak shaving. I probably only have enough to make slippers here. # I use an associatiave array to generate the variable names you used to define =level2_list= "YakShavingVarnames[$(l1_keys)]" string => "level1_$(l1_keys)[$(l2_keys[$(l1_keys)])]"; # I joined them togehter with =,= just like you did. "YakShavinString" string => join( ", ", getvalues( YakShavingVarnames ) ); # I expanded them so that it was just like y ou did "level2_list" data => data_expand('[ $(YakShavinString) ]'); }
# cf-agent --no-lock --show-evaluated-vars=default:example --file /tmp/example.cf Variable name Variable value Meta tags Comment default:example.YakShavinString level1_debian_12[icinga], level1_ubuntu_16[hwraid] source=promise default:example.YakShavingVarnames[debian_12] level1_debian_12[icinga] source=promise default:example.YakShavingVarnames[ubuntu_16] level1_ubuntu_16[hwraid] source=promise default:example.l1_keys {"ubuntu_16","debian_12"} source=promise default:example.l2_keys[debian_12] {"debian","debian-security","icinga"} source=promise default:example.l2_keys[ubuntu_16] {"ubuntu","ubuntu-security","hwraid"} source=promise default:example.l2_keys_combined {"debian","debian-security","icinga","ubuntu","ubuntu-security","hwraid"} source=promise default:example.level1_debian_12 {"debian":{"Suites":["bookworm","bookworm-backports","bookworm-proposed-updates","bookworm-updates"],"URIs":"http://deb.debian.org/debian"},"debian-security":{"Suites":["bookworm-security"],"URIs":"http://deb.debian.org/debian-security"},"icinga":{"Suites":["icinga-bookworm"],"URIs":"https://packages.icinga.com/debian"}} source=promise,level1_keys default:example.level1_ubuntu_16 {"hwraid":{"Suites":["stretch"],"URIs":"https://hwraid.le-vert.net/debian"},"ubuntu":{"Suites":["xenial","xenial-backports","xenial-proposed","xenial-updates","xenial-security"],"URIs":"http://cz.archive.ubuntu.com/ubuntu"},"ubuntu-security":{"Suites":["xenial-security"],"URIs":"http://cz.archive.ubuntu.com/ubuntu"}} source=promise,level1_keys default:example.level2_list [{"Suites":["icinga-bookworm"],"URIs":"https://packages.icinga.com/debian"},{"Suites":["stretch"],"URIs":"https://hwraid.le-vert.net/debian"}] source=promise default:example.repos {"debian_12":{"debian":{"Suites":["bookworm","bookworm-backports","bookworm-proposed-updates","bookworm-updates"],"URIs":"http://deb.debian.org/debian"},"debian-security":{"Suites":["bookworm-security"],"URIs":"http://deb.debian.org/debian-security"},"icinga":{"Suites":["icinga-bookworm"],"URIs":"https://packages.icinga.com/debian"}},"ubuntu_16":{"hwraid":{"Suites":["stretch"],"URIs":"https://hwraid.le-vert.net/debian"},"ubuntu":{"Suites":["xenial","xenial-backports","xenial-proposed","xenial-updates","xenial-security"],"URIs":"http://cz.archive.ubuntu.com/ubuntu"},"ubuntu-security":{"Suites":["xenial-security"],"URIs":"http://cz.archive.ubuntu.com/ubuntu"}}} source=promise