choria-io / puppet-choria

Module to install and manage Choria
Apache License 2.0
27 stars 33 forks source link

Improve windows support #145

Open ripienaar opened 4 years ago

ripienaar commented 4 years ago
abaddononion commented 4 years ago

We successfully got this up and running in our enterprise with some help from R.I.P. and Smortex. Here are the issues we encountered along the way:

  1. In the buildspec.yml file, under the "64bit_windows" heading, there's a "pre" section defined that overrides the "pre" section from the "defaults" heading. This doesn't include the rm commands from the "defaults" "pre" section, and seems to create an issue where you get double agents, causing the service to crash on startup.

  2. The WSX file (not sure if that's even been merged) has a line that says <Directory Id="ProgramFilesFolder" Name="PFiles"> This should read "ProgramFiles64Folder" instead. Otherwise on some systems it winds up installing to "Program Files (x86)", which doesn't match the hiera data.

  3. The "puppet config print" method for determining the ssldir doesn't seem to work on Windows... this could probably be repaired, but it's also sufficient to add this key to data/os/windows.yaml in the puppet-choria Forge module: plugin.choria.ssldir: "C:/ProgramData/PuppetLabs/puppet/etc/ssl"

  4. The agent shim is broken under Windows, because Windows cannot execute a .rb file. This is probably the hardest thing to work around. I had to add a .bat file to wrap the command, and then make changes to the Puppet Forge Choria module to be able to use the .bat instead of the .rb. I'll detail those here.

    4A. I created a .bat file template as such:

@echo off
SETLOCAL

"<%= @rubypath %>" -S -- "<%= @agent_shim %>" --config "<%= @shim_config %>" %*

4B. Currently, I have an external module populating those variables (this would obviously be done in a different way when added to the proper module):

        $rubypath = lookup("choria::rubypath")
        $choria_server_config = lookup("choria::server_config")
        $agent_shim = regsubst($choria_server_config["plugin.choria.agent_provider.mcorpc.agent_shim"], '.bat$', '.rb')
        $shim_config = $choria_server_config["plugin.choria.agent_provider.mcorpc.config"]

        file {
          "${mcollective::bindir}\\choria_mcollective_agent_compat.bat":
            content => template("lsi_mcollective/choria_mcollective_agent_compat.bat.erb"),
            mode => "777";
        }

4C. I changed the default value of plugin.choria.agent_provider.mcorpc.agent_shim to "C:/Program Files/choria/bin/choria_mcollective_agent_compat.bat" in data/os/windows.yaml in the choria Forge module.

4D. I made the following changes to manifests/config.pp in the choria Forge module:

diff --git a/manifests/config.pp b/manifests/config.pp
index 2db39f8..411e727 100644
--- a/manifests/config.pp
+++ b/manifests/config.pp
@@ -41,11 +41,26 @@ class choria::config {
   }

   if "plugin.choria.agent_provider.mcorpc.agent_shim" in $choria::server_config  and "plugin.choria.agent_provider.mcorpc.config" in $choria::server_config {
-    file{$choria::server_config["plugin.choria.agent_provider.mcorpc.agent_shim"]:
-      owner   => $choria::config_user,
-      group   => $choria::config_group,
-      mode    => "0755",
-      content => epp("choria/choria_mcollective_agent_compat.rb.epp")
+    case $::operatingsystem {
+      "windows": {
+        # In Windows, we know the config has to point to a .bat file, but that .bat file will use the .rb file that we lay down here.
+        $shim_rb = regsubst($choria::server_config["plugin.choria.agent_provider.mcorpc.agent_shim"], '.bat$', '.rb')
+
+        file{$shim_rb:
+          owner   => $choria::config_user,
+          group   => $choria::config_group,
+          mode    => "0755",
+          content => epp("choria/choria_mcollective_agent_compat.rb.epp")
+        }
+      }
+      default: {
+        file{$choria::server_config["plugin.choria.agent_provider.mcorpc.agent_shim"]:
+          owner   => $choria::config_user,
+          group   => $choria::config_group,
+          mode    => "0755",
+          content => epp("choria/choria_mcollective_agent_compat.rb.epp")
+        }
+      }
     }
   }
  1. Once all of this is done, the MSI creates a service that still cannot start. For my purposes I worked around this with NSSM: https://forge.puppet.com/ktreese/nssm
ripienaar commented 4 years ago

I added the wix based POC into go-choria, you can now build it on a linux machine with docker:

% PACKAGES=windows_64 rake build

which should eventually get you a msi, no doubt we have much to fix and for now it adds just the binary no bat files etc, but its a place to start.

ripienaar commented 4 years ago

@abaddononion @smortex if you PACKAGES=windows_64 rake build on master you'll get a exe that may or may not have all the crap needed to be a windows service.

Additionally when run as a service on windows it should log to windows event log

If you tell me how to add this thing as a service to a windows machine i could test it, but not really sure. Code appears to be roughly the right shape...

ripienaar commented 4 years ago

Huge example wix installer doing many things we might want https://helgeklein.com/blog/2014/09/real-world-example-wix-msi-application-installer/