Beispiel #1
0
        public static ActionResult Uninstall_excl_Config_DECAC(Session session)
        {
            // DO keep config
            //Selectively delete the var folder.
            // We move the 2 directories out of var, delete var, and move back
            session.Log("...Begin Uninstall_excl_Config_DECAC");
            PurgeDir(session, @"bin");
            // move parts from var into safety
            string safedir = @"c:\salt\_tmp_swap_space\";

            if (Directory.Exists(safedir))
            {
                Directory.Delete(safedir);
            }
            Directory.CreateDirectory(safedir);
            MinionConfigurationUtilities.movedir_fromAbs_toRel(session, @"c:\salt\var\cache\salt\minion\extmods", "extmods", true, safedir);
            MinionConfigurationUtilities.movedir_fromAbs_toRel(session, @"c:\salt\var\cache\salt\minion\files", "files", true, safedir);
            // purge var
            PurgeDir(session, @"var");
            // move back
            Directory.CreateDirectory(@"c:\salt\var\cache\salt\minion"); // Directory.Move cannot create dirs
            MinionConfigurationUtilities.movedir_fromAbs_toRel(session, @"c:\salt\var\cache\salt\minion\extmods", "extmods", false, safedir);
            MinionConfigurationUtilities.movedir_fromAbs_toRel(session, @"c:\salt\var\cache\salt\minion\files", "files", false, safedir);
            Directory.Delete(safedir);

            // log
            session.Log("...End Uninstall_excl_Config_DECAC");
            return(ActionResult.Success);
        }
Beispiel #2
0
        private static bool replace_Saltkey_in_previous_configuration_DECAC(Session session, string SaltKey, ref string CustomActionData_value)
        {
            // Read SaltKey properties and convert some from 1 to True or to False
            bool replaced = false;

            session.Log("...replace_Saltkey_in_previous_configuration_DECAC Key   " + SaltKey);
            CustomActionData_value = MinionConfigurationUtilities.get_property_DECAC(session, SaltKey);
            if (SaltKey == "zmq_filtering")
            {
                CustomActionData_value = (CustomActionData_value == "1") ? "True" : "False";
                session.Log("...changed zmq_filtering to " + CustomActionData_value);
            }
            if (SaltKey == "minion_id_caching")
            {
                CustomActionData_value = (CustomActionData_value == "1") ? "True" : "False";
                session.Log("...changed zmq_filtering to " + CustomActionData_value);
            }

            session.Message(InstallMessage.Progress, new Record(2, 1));
            // pattern description
            // ^        start of line
            //          anything after the colon is ignored and would be removed
            string pattern     = "^" + SaltKey + ":";
            string replacement = String.Format(SaltKey + ": {0}", CustomActionData_value);

            // Replace in all files
            replaced = replace_pattern_in_all_config_files_DECAC(session, pattern, replacement);

            session.Message(InstallMessage.Progress, new Record(2, 1));
            session.Log(@"...replace_Saltkey_in_previous_configuration_DECAC found or replaces " + replaced.ToString());
            return(replaced);
        }
        private static void apply_minion_config_DECAC(Session session, string minion_config)
        {
            // Precondition: parameter minion_config contains the content of the MINION_CONFI property and is not empty
            // Remove all other config
            session.Log("...apply_minion_config_DECAC BEGIN");
            string conffolder           = MinionConfigurationUtilities.get_property_DECAC(session, "conffolder");
            string minion_d_conf_folder = MinionConfigurationUtilities.get_property_DECAC(session, "minion_d_conf_folder");
            // Write conf/minion
            string lines = minion_config.Replace("^", Environment.NewLine);

            MinionConfigurationUtilities.Writeln_file(session, conffolder, "minion", lines);
            // Remove conf/minion_id
            string minion_id = Path.Combine(conffolder, "minion_id");

            session.Log("...searching " + minion_id);
            if (File.Exists(minion_id))
            {
                File.Delete(minion_id);
                session.Log("...deleted   " + minion_id);
            }
            // Remove conf/minion.d/*.conf
            session.Log("...searching *.conf in " + minion_d_conf_folder);
            if (Directory.Exists(minion_d_conf_folder))
            {
                var conf_files = System.IO.Directory.GetFiles(minion_d_conf_folder, "*.conf");
                foreach (var conf_file in conf_files)
                {
                    File.Delete(conf_file);
                    session.Log("...deleted   " + conf_file);
                }
            }
            session.Log(@"...apply_minion_config_DECAC END");
        }
Beispiel #4
0
        static private void insert_value_after_comment_or_end_in_minionconfig_file(Session session, string key, string value)
        {
            string MINION_CONFIGFILE = MinionConfigurationUtilities.getConfigFileLocation_DECAC(session);

            string[] configLines_in        = File.ReadAllLines(MINION_CONFIGFILE);
            string[] configLines_out       = new string[configLines_in.Length + 1];
            int      configLines_out_index = 0;

            session.Log("...insert_value_after_comment_or_end  key  {0}", key);
            session.Log("...insert_value_after_comment_or_end  value  {0}", value);
            bool found = false;

            for (int i = 0; i < configLines_in.Length; i++)
            {
                configLines_out[configLines_out_index++] = configLines_in[i];
                if (!found && configLines_in[i].StartsWith("#" + key + ":"))
                {
                    found = true;
                    session.Log("...insert_value_after_comment_or_end..found the # in       {0}", configLines_in[i]);
                    configLines_out[configLines_out_index++] = key + ": " + value;
                }
            }
            if (!found)
            {
                session.Log("...insert_value_after_comment_or_end..end");
                configLines_out[configLines_out_index++] = key + ": " + value;
            }
            File.WriteAllLines(MINION_CONFIGFILE, configLines_out);
        }
Beispiel #5
0
 private static void save_custom_config_file_if_config_type_demands_DECAC(Session session)
 {
     if (session.CustomActionData["config_type"] == "Custom")
     {
         Backup_configuration_files_from_previous_installation(session);
         // lay down a custom config passed via the command line
         string content_of_custom_config_file = string.Join(Environment.NewLine, File.ReadAllLines(session.CustomActionData["minion_configfile"]));
         MinionConfigurationUtilities.Write_file(session, @"C:\salt\conf", "minion", content_of_custom_config_file);
     }
 }
Beispiel #6
0
        private static void Backup_configuration_files_from_previous_installation(Session session)
        {
            session.Log("...Backup_configuration_files_from_previous_installation");
            string timestamp_bak = "-" + DateTime.Now.ToString("yyyy-MM-ddTHH-mm-ss") + ".bak";

            session.Log("...timestamp_bak = " + timestamp_bak);
            MinionConfigurationUtilities.Move_file(session, @"C:\salt\conf\minion", timestamp_bak);
            MinionConfigurationUtilities.Move_file(session, @"C:\salt\conf\minion_id", timestamp_bak);
            MinionConfigurationUtilities.Move_dir(session, @"C:\salt\conf\minion.d", timestamp_bak);
        }
Beispiel #7
0
        private static void save_config_DECAC(Session session)
        {
            session.Log(@"...save_config_DECAC");
            string kwargs_in_commata = MinionConfigurationUtilities.get_property_DECAC(session, "minion_config");

            if (kwargs_in_commata.Length > 0)
            {
                string lines = kwargs_in_commata.Replace("^", Environment.NewLine);
                MinionConfigurationUtilities.Writeln_file(session, @"C:\salt\conf", "minion", lines);
            }
        }
        private static bool replace_pattern_in_config_file_DECAC(Session session, string pattern, string replacement)
        {
            /*
             * config file means: conf/minion
             */
            bool   replaced_in_any_file = false;
            string MINION_CONFIGFILE    = MinionConfigurationUtilities.getConfigFileLocation_DECAC(session);

            replaced_in_any_file |= replace_in_file_DECAC(session, MINION_CONFIGFILE, pattern, replacement);

            return(replaced_in_any_file);
        }
        public static ActionResult del_NSIS_DECAC(Session session)
        {
            // Leaves the Config

            /*
             * If NSIS is installed:
             *   remove salt-minion service,
             *   remove registry
             *   remove files, except /salt/conf and /salt/var
             *
             *   Instead of the above, TODO use uninst.exe and preserve the 2 directories (by moving them into safety first?)
             *   This would be cleaner code
             *      uninst /S  does leave the installdir while    uninst /s /DeleteInstallDir  delete the installdir, both silentyl
             */
            session.Log("...BEGIN del_NSIS_DECAC");
            session.Log("...VERSION MinionConfigurationExtensionCA 1");
            RegistryKey reg = Registry.LocalMachine;
            // ?When this is under    SOFTWARE\WoW6432Node
            string Salt_uninstall_regpath64 = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Salt Minion";
            string Salt_uninstall_regpath32 = @"SOFTWARE\WoW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Salt Minion";
            var    SaltRegSubkey64          = reg.OpenSubKey(Salt_uninstall_regpath64);
            var    SaltRegSubkey32          = reg.OpenSubKey(Salt_uninstall_regpath32);

            bool NSIS_is_installed64 = (SaltRegSubkey64 != null) && SaltRegSubkey64.GetValue("UninstallString").ToString().Equals(@"c:\salt\uninst.exe", StringComparison.OrdinalIgnoreCase);
            bool NSIS_is_installed32 = (SaltRegSubkey32 != null) && SaltRegSubkey32.GetValue("UninstallString").ToString().Equals(@"c:\salt\uninst.exe", StringComparison.OrdinalIgnoreCase);

            session.Log("delete_NSIS_files:: NSIS_is_installed64 = " + NSIS_is_installed64);
            session.Log("delete_NSIS_files:: NSIS_is_installed32 = " + NSIS_is_installed32);
            if (NSIS_is_installed64 || NSIS_is_installed32)
            {
                session.Log("delete_NSIS_files:: Going to stop service salt-minion ...");
                MinionConfigurationUtilities.shellout(session, "sc stop salt-minion");
                session.Log("delete_NSIS_files:: Going to delete service salt-minion ...");
                MinionConfigurationUtilities.shellout(session, "sc delete salt-minion"); // shellout waits, but does sc? Does this work?

                session.Log("delete_NSIS_files:: Going to delete ARP registry64 entry for salt-minion ...");
                try { reg.DeleteSubKeyTree(Salt_uninstall_regpath64); } catch (Exception ex) { MinionConfigurationUtilities.just_ExceptionLog("", session, ex); }
                session.Log("delete_NSIS_files:: Going to delete ARP registry32 entry for salt-minion ...");
                try { reg.DeleteSubKeyTree(Salt_uninstall_regpath32); } catch (Exception ex) { MinionConfigurationUtilities.just_ExceptionLog("", session, ex); }

                session.Log("delete_NSIS_files:: Going to delete files ...");
                try { Directory.Delete(@"c:\salt\bin", true); } catch (Exception ex) { MinionConfigurationUtilities.just_ExceptionLog("", session, ex); }
                try { File.Delete(@"c:\salt\uninst.exe"); } catch (Exception ex) { MinionConfigurationUtilities.just_ExceptionLog("", session, ex); }
                try { File.Delete(@"c:\salt\nssm.exe"); } catch (Exception ex) { MinionConfigurationUtilities.just_ExceptionLog("", session, ex); }
                try { foreach (FileInfo fi in new DirectoryInfo(@"c:\salt").GetFiles("salt*.*"))
                      {
                          fi.Delete();
                      }
                } catch (Exception) {; }
            }
            session.Log("...END del_NSIS_DECAC");
            return(ActionResult.Success);
        }
Beispiel #10
0
        static private void append_to_config_DECAC(Session session, string key, string value)
        {
            string MINION_CONFIGDIR = MinionConfigurationUtilities.getConfigdDirectoryLocation_DECAC(session);

            if (session.CustomActionData["config_type"] == "New")
            {
                //CONFIG_TYPE New creates a minion.d/*.conf file
                MinionConfigurationUtilities.Writeln_file(session, MINION_CONFIGDIR, key + ".conf", key + ": " + value);
            }
            else
            {
                // Shane: CONFIG_TYPES 1-3 change only the MINION_CONFIGFILE, not the minion.d/*.conf files, because the admin knows what he is doing.
                insert_value_after_comment_or_end_in_minionconfig_file(session, key, value);
            }
        }
Beispiel #11
0
        private static void save_id_function_DECAC(Session session)
        {
            session.Log(@"...save_id_function_DECAC");
            string minion_id_function = MinionConfigurationUtilities.get_property_DECAC(session, "minion_id_function");

            if (minion_id_function.Length > 0)
            {
                string filepath    = @"c:\salt\var\cache\salt\minion\extmods\modules";
                string filename    = @"id_function.py";
                string filecontent = @"import socket
def id_function():
    return " + minion_id_function;
                MinionConfigurationUtilities.Writeln_file(session, filepath, filename, filecontent);
            }
        }
Beispiel #12
0
        private static void PurgeDir(Session session, string dir_below_salt_root)
        {
            String abs_dir  = @"c:\salt\" + dir_below_salt_root; //TODO use root_dir
            String root_dir = "";

            root_dir = session.CustomActionData["root_dir"];

            if (Directory.Exists(abs_dir))
            {
                session.Log("PurgeDir:: about to Directory.delete " + abs_dir);
                Directory.Delete(abs_dir, true);
                session.Log("PurgeDir:: ...OK");
            }
            else
            {
                session.Log("PurgeDir:: no Directory " + abs_dir);
            }

            // quirk for https://github.com/markuskramerIgitt/salt-windows-msi/issues/33  Exception: Access to the path 'minion.pem' is denied . Read only!
            MinionConfigurationUtilities.shellout(session, @"rmdir /s /q " + abs_dir);
        }
        private static void save_custom_config_file_if_config_type_demands_DECAC(Session session)
        {
            session.Log("...save_custom_config_file_if_config_type_demands_DECAC");
            string custom_config1      = session.CustomActionData["custom_config"];
            string custom_config_final = "";

            if (!(session.CustomActionData["config_type"] == "Custom" && custom_config1.Length > 0))
            {
                return;
            }
            if (File.Exists(custom_config1))
            {
                session.Log("...found custom_config1 " + custom_config1);
                custom_config_final = custom_config1;
            }
            else
            {
                // try relative path
                string directory_of_the_msi = session.CustomActionData["sourcedir"];
                string custom_config2       = Path.Combine(directory_of_the_msi, custom_config1);
                if (File.Exists(custom_config2))
                {
                    session.Log("...found custom_config2 " + custom_config2);
                    custom_config_final = custom_config2;
                }
                else
                {
                    session.Log("...no custom_config1 " + custom_config1);
                    session.Log("...no custom_config2 " + custom_config2);
                    return;
                }
            }
            Backup_configuration_files_from_previous_installation(session);
            // lay down a custom config passed via the command line
            string content_of_custom_config_file = string.Join(Environment.NewLine, File.ReadAllLines(custom_config_final));

            MinionConfigurationUtilities.Write_file(session, @"C:\salt\conf", "minion", content_of_custom_config_file);
        }
        public static ActionResult WriteConfig_DECAC(Session session)
        {
            /*
             * This function must leave the config files according to the CONFIG_TYPE's 1-3
             * This function is deferred (_DECAC)
             * This function runs after the msi has created the c:\salt\conf\minion file, which is a comment-only text.
             * If there was a previous install, there could be many config files.
             * The previous install c:\salt\conf\minion file could contain non-comments.
             * One of the non-comments could be master.
             * It could be that this installer has a different master.
             *
             */
            // Must have this signature or cannot uninstall not even write to the log
            session.Log("...BEGIN WriteConfig_DECAC");
            session.Log("...VERSION MinionConfigurationExtensionCA 1");
            string minion_config = MinionConfigurationUtilities.get_property_DECAC(session, "minion_config");

            if (minion_config.Length > 0)
            {
                apply_minion_config_DECAC(session, minion_config);
            }
            else
            {
                string master = "";
                string id     = "";
                if (!replace_Saltkey_in_previous_configuration_DECAC(session, "master", ref master))
                {
                    append_to_config_DECAC(session, "master", master);
                }
                if (!replace_Saltkey_in_previous_configuration_DECAC(session, "id", ref id))
                {
                    append_to_config_DECAC(session, "id", id);
                }
                save_custom_config_file_if_config_type_demands_DECAC(session);
            }
            session.Log("...END WriteConfig_DECAC");
            return(ActionResult.Success);
        }
Beispiel #15
0
        private static bool replace_pattern_in_all_config_files_DECAC(Session session, string pattern, string replacement)
        {
            /*
             * "All config" files means:
             *   conf/minion
             *   conf/minion.d/*.conf           (only for New)
             *
             * MAYBE this function could input a dictionary of key/value pairs, because it reopens all config files over and over.
             *
             */
            bool   replaced_in_any_file = false;
            string MINION_CONFIGFILE    = MinionConfigurationUtilities.getConfigFileLocation_DECAC(session);
            string MINION_CONFIGDIR     = MinionConfigurationUtilities.getConfigdDirectoryLocation_DECAC(session);

            replaced_in_any_file |= replace_in_file_DECAC(session, MINION_CONFIGFILE, pattern, replacement);

            // Shane wants that the installer changes only the MINION_CONFIGFILE, not the minion.d/*.conf files
            if (session.CustomActionData["config_type"] == "New")
            {
                // Go into the minion.d/ folder
                if (Directory.Exists(MINION_CONFIGDIR))
                {
                    var conf_files = System.IO.Directory.GetFiles(MINION_CONFIGDIR, "*.conf");
                    foreach (var conf_file in conf_files)
                    {
                        // skip _schedule.conf
                        if (conf_file.EndsWith("_schedule.conf"))
                        {
                            continue;
                        }
                        replaced_in_any_file |= replace_in_file_DECAC(session, conf_file, pattern, replacement);
                    }
                }
            }
            return(replaced_in_any_file);
        }
        static private void append_to_config_DECAC(Session session, string key, string value)
        {
            string MINION_CONFIGDIR = MinionConfigurationUtilities.getConfigdDirectoryLocation_DECAC(session);

            insert_value_after_comment_or_end_in_minionconfig_file(session, key, value);
        }
Beispiel #17
0
        public static ActionResult ReadConfig_IMCAC(Session session)
        {
            /*
             * When installatioin starts,there might be a previous installation.
             * From the previous installation, we read only two properties, that we present in the installer:
             *  - master
             *  - id
             *
             *  This function reads these two properties from
             *   - the 2 msi properties:
             *     - MASTER
             *     - MINION_ID
             *   - files from a provious installations:
             *     - the number of file the function searches depend on CONFIGURATION_TYPE
             *   - dependend on CONFIGURATION_TYPE, default values can be:
             *     - master = "salt"
             *     - id = %hostname%
             *
             *
             *  This function writes its results in the 2 msi properties:
             *   - MASTER
             *   - MINION_ID
             *
             *   A GUI installation will show these msi properties because this function is called before the GUI.
             *
             */
            session.Log("...Begin ReadConfig_IMCAC");
            String master_from_previous_installation = "";
            String id_from_previous_installation     = "";

            // Read master and id from MINION_CONFIGFILE
            read_master_and_id_from_file_IMCAC(session, session["MINION_CONFIGFILE"], ref master_from_previous_installation, ref id_from_previous_installation);
            // Read master and id from minion.d/*.conf
            string MINION_CONFIGDIR = MinionConfigurationUtilities.getConfigdDirectoryLocation_IMCAC(session);

            if (Directory.Exists(MINION_CONFIGDIR))
            {
                var conf_files = System.IO.Directory.GetFiles(MINION_CONFIGDIR, "*.conf");
                foreach (var conf_file in conf_files)
                {
                    if (conf_file.Equals("_schedule.conf"))
                    {
                        continue;
                    }                                                                // skip _schedule.conf
                    read_master_and_id_from_file_IMCAC(session, conf_file, ref master_from_previous_installation, ref id_from_previous_installation);
                }
            }

            if (Directory.Exists(session["INSTALLFOLDER"]))
            {
                // Log how many files there are in INSTALLFOLDER
                var count_files = Directory.GetFiles(session["INSTALLFOLDER"], "*", SearchOption.AllDirectories).Length;
                session.Log("...counted " + count_files.ToString() + " files in INSTALLFOLDER = " + session["INSTALLFOLDER"]);
            }
            else
            {
                // Log there is no INSTALLFOLDER
                session.Log("...no directory INSTALLFOLDER = " + session["INSTALLFOLDER"]);
            }

            session.Log("...CONFIG_TYPE msi property  =" + session["CONFIG_TYPE"]);
            session.Log("...MASTER      msi property  =" + session["MASTER"]);
            session.Log("...MINION_ID   msi property  =" + session["MINION_ID"]);

            if (session["CONFIG_TYPE"] == "Default")
            {
                /* Overwrite the existing config if present with the default config for salt.
                 */

                if (session["MASTER"] == "")
                {
                    session["MASTER"] = "salt";
                    session.Log("...MASTER set to salt because it was unset and CONFIG_TYPE=Default");
                }
                if (session["MINION_ID"] == "")
                {
                    session["MINION_ID"] = Environment.MachineName;
                    session.Log("...MINION_ID set to hostname because it was unset and CONFIG_TYPE=Default");
                }

                // Would be more logical in WriteConfig, but here is easier and no harm
                Backup_configuration_files_from_previous_installation(session);
            }
            else
            {
                /* If the msi property has value #, this is our convention for "unset"
                 * This means the user has not set the value on commandline (GUI comes later)
                 * If the msi property has value different from # "unset", the user has set the master
                 * msi propery has precedence over kept config
                 * Only if msi propery is unset, set value of previous installation
                 */

                /////////////////master
                if (session["MASTER"] == "")
                {
                    session.Log("...MASTER       kept config   =" + master_from_previous_installation);
                    if (master_from_previous_installation != "")
                    {
                        session["MASTER"] = master_from_previous_installation;
                        session.Log("...MASTER set to kept config");
                    }
                    else
                    {
                        session["MASTER"] = "salt";
                        session.Log("...MASTER set to salt because it was unset and no kept config");
                    }
                }

                ///////////////// minion id
                if (session["MINION_ID"] == "")
                {
                    session.Log("...MINION_ID   kept config   =" + id_from_previous_installation);
                    if (id_from_previous_installation != "")
                    {
                        session.Log("...MINION_ID set to kept config ");
                        session["MINION_ID"] = id_from_previous_installation;
                    }
                    else
                    {
                        session["MINION_ID"] = Environment.MachineName;
                        session.Log("...MINION_ID set to hostname because it was unset and no previous installation and CONFIG_TYPE!=Default");
                    }
                }
            }

            // Would be more logical in WriteConfig, but here is easier and no harm because there is no public master key in the installer.
            // Save the salt-master public key
            var  master_public_key_path     = @"C:\salt\conf\pki\minion"; // TODO more flexible
            var  master_public_key_filename = master_public_key_path + "\\" + @"minion_master.pub";
            bool MASTER_KEY_set             = session["MASTER_KEY"] != "";

            session.Log("...master key earlier config file exists = " + File.Exists(master_public_key_filename));
            session.Log("...master key msi property given         = " + MASTER_KEY_set);
            if (MASTER_KEY_set)
            {
                String master_key_lines = "";   // Newline after 64 characters
                int    count_characters = 0;
                foreach (char character in session["MASTER_KEY"])
                {
                    master_key_lines += character;
                    count_characters += 1;
                    if (count_characters % 64 == 0)
                    {
                        master_key_lines += Environment.NewLine;
                    }
                }
                string new_master_pub_key =
                    "-----BEGIN PUBLIC KEY-----" + Environment.NewLine +
                    master_key_lines + Environment.NewLine +
                    "-----END PUBLIC KEY-----";
                Directory.CreateDirectory(master_public_key_path);
                File.WriteAllText(master_public_key_filename, new_master_pub_key);
            }
            session.Log("...End ReadConfig_IMCAC");
            return(ActionResult.Success);
        }