But i've been looking for a more performant pattern, since this one has to run knife for every item coming out of the search. I've tried running it in parallel in Powershell 7, and while it works most of the time, for more complex operations it's intermittent in VSCode ps console and in Jenkins.
I've seen knife exec before but it always looked like something for more obscure needs than this. It's more likely that i just don't understand it. The docs don't provide a complete explanation of how to use this API wrapper. @Tensibai, where does the n.save come from? Does that write the result of the script back up to the Chef Server?
More specifically, does this allow us to perform actions like run_list add or policy set in parallel, like we are able to do with knife winrm?
Sorry, the answer was a bit terse, knife exec just run ruby, with all chef classes available.
What it does here is searching for nodes, and on each node object it got, modify it's run list attribute, roughly what can happen in a chef run on a node.
When a node run is successful, the node object is saved back to the server, that's the call to node.save here.
could we use knife winrm to exec something locally on each node to do something, like update a run list or set policy? That would provide the parallelism.
knife winrm 'tags:<tag>' 'chef-client <some way to set run_list, policy, tags etc locally on that node>' -U <user> -P <pass>
You can write the desired runlist in a cookbook recipe and then chef-client -o the_cookbook, as -o override the runlist you'd have to redefine it totally, adding a reiipe would add it to what has been given to -o an non to the original runlist and overwrite the original
That may give a bit of overload to the chef-server if too much noded run at the same time that said.
Selfishly, i'm mostly interested in policy set - can that be done on the node, meaning with a knife winrm call that doesn't have to be piped into individual knife node policy set calls?
No idea how policy are saved on nodes as I'm not using them, I'd think they're defined in the runlist, but best idea is to try knife exec -E 'nodes.search("NOT tags:*").each { |n| puts "#{n.name} run list before is: #{n.run_list}" }' and see if the policy are in the runlist or not