Beispiel #1
0
 public static string[] GetKvpKeys(string pool)
 {
     try
     {
         List <string> lKeys  = new List <string>();
         byte[]        bKey   = new byte[KVP_MAX_KEY_SIZE];
         byte[]        bValue = new byte[KVP_MAX_VALUE_SIZE];
         byte[]        res;
         using (FileStream fs = File.Open(pool, FileMode.Open))
         {
             long remaining = fs.Length;
             while (remaining > 0)
             {
                 for (int i = 0; i < KVP_MAX_KEY_SIZE; i++)
                 {
                     bKey[i] = 0;
                 }
                 int read = fs.Read(bKey, 0, KVP_MAX_KEY_SIZE);
                 remaining -= read;
                 if (remaining <= 0)
                 {
                     break;
                 }
                 read       = fs.Read(bValue, 0, KVP_MAX_VALUE_SIZE);
                 remaining -= read;
                 int idx = -1;
                 res = bKey;
                 for (int i = 0; i < bKey.Length; i++)
                 {
                     if (bKey[i] == 0)
                     {
                         idx = i;
                         break;
                     }
                 }
                 if (idx != -1)
                 {
                     res = new byte[idx];
                     Array.Copy(bKey, 0, res, 0, idx);
                 }
                 string sKey = System.Text.Encoding.UTF8.GetString(res);
                 sKey = sKey.Replace("\0", "", StringComparison.Ordinal);
                 lKeys.Add(sKey);
             }
         }
         return(lKeys.ToArray());
     }
     catch (Exception ex)
     {
         ServiceLog.WriteError("GetKvpKeys error: ", ex);
         return(null);
     }
 }
Beispiel #2
0
        private static void DelayOnStart()
        {
            int startupDelay = 0;

            if (Int32.TryParse(ConfigurationManager.AppSettings["Service.StartupDelay"], out startupDelay) &&
                startupDelay > 0)
            {
                ServiceLog.WriteStart("Delay on service start-up");
                System.Threading.Thread.Sleep(startupDelay);
                ServiceLog.WriteEnd("Delay on service start-up");
            }
        }
Beispiel #3
0
 private static void EditKvpValue(string pool, int offset, byte[] data)
 {
     try
     {
         byte[] fBytes = File.ReadAllBytes(pool);
         Array.Copy(data, 0, fBytes, offset, data.Length);
         File.WriteAllBytes(pool, fBytes);
     }
     catch (Exception ex)
     {
         ServiceLog.WriteError("EditKvpValue error: ", ex);
     }
 }
Beispiel #4
0
 private static void RebootSystem()
 {
     try
     {
         ServiceLog.WriteStart("RebootSystem");
         ShellHelper.RunCmd("reboot");
         ServiceLog.WriteEnd("RebootSystem");
     }
     catch (Exception ex)
     {
         ServiceLog.WriteError("Reboot System error:", ex);
     }
 }
Beispiel #5
0
        private static void InstallService_Linux()
        {
            const string serviceName  = "solidcp.service";
            const string servicesPath = "/etc/systemd/system/";
            string       userName     = Environment.UserName;
            string       appPath      = AppDomain.CurrentDomain.BaseDirectory;

            ShellHelper.RunCmd("systemctl stop " + serviceName);
            ShellHelper.RunCmd("systemctl disable " + serviceName);

            List <string> config = new List <string>();

            config.Add("[Unit]");
            config.Add("Description=SolidCP LinuxVmConfig Service");
            config.Add("[Service]");
            config.Add("User="******"WorkingDirectory=" + appPath);
            config.Add("ExecStart=" + appPath + "SolidCP.LinuxVmConfig");
            config.Add("SuccessExitStatus=0");
            config.Add("TimeoutStopSec=infinity");
            config.Add("Restart=on-failure");
            config.Add("RestartSec=5");
            config.Add("[Install]");
            config.Add("WantedBy=multi-user.target");
            File.WriteAllLines(servicesPath + serviceName, config);

            ExecutionResult res = ShellHelper.RunCmd("systemctl daemon-reload");

            if (res.ResultCode == 1)
            {
                ServiceLog.WriteError("Service install error: " + res.ErrorMessage);
                return;
            }
            res = ShellHelper.RunCmd("systemctl enable " + serviceName);
            if (res.ResultCode == 1)
            {
                ServiceLog.WriteError("Service install error: " + res.ErrorMessage);
                return;
            }
            res = ShellHelper.RunCmd("systemctl start " + serviceName);
            if (res.ResultCode == 1)
            {
                ServiceLog.WriteError("Service install error: " + res.ErrorMessage);
                return;
            }
            ServiceLog.WriteInfo(serviceName + " successfully installed.");
        }
Beispiel #6
0
        private static void Start()
        {
            //log
            ServiceLog.WriteApplicationStart();

            // delay (for sync with KVP exchange service)
            DelayOnStart();

            //init
            InitializeProvisioningModules();
            InitializeTimers();

            //run tasks
            while (true)
            {
                ProcessTasks();
                System.Threading.Thread.Sleep(pollInterval);
            }
        }
Beispiel #7
0
        private static void DeleteOldResults()
        {
            // get the list of input tasks
            string[] strTasks = KvpUtils.GetKvpKeys(InputKVP);
            if (strTasks == null)
            {
                return;
            }
            List <string> tasks = new List <string>();

            foreach (string strTask in strTasks)
            {
                if (!string.IsNullOrEmpty(strTask) && strTask.StartsWith(TaskPrefix) && strTask != CurrentTaskName)
                {
                    //save only SolidCP tasks
                    tasks.Add(strTask);
                }
            }

            // get the list of task results
            int deletedResults = 0;

            string[] strResults = KvpUtils.GetKvpKeys(OutputKVP);
            foreach (string strResult in strResults)
            {
                if (!string.IsNullOrEmpty(strResult) && strResult.StartsWith(TaskPrefix) && strResult != CurrentTaskName)
                {
                    // check if task result exists in the input tasks
                    if (!tasks.Contains(strResult))
                    {
                        KvpUtils.DeleteKvpKey(OutputKVP, strResult);
                        ServiceLog.WriteInfo(string.Format("Deleted activity result: {0}", strResult));
                        deletedResults++;
                    }
                }
            }

            if (deletedResults > 0)
            {
                ServiceLog.WriteEnd(string.Format("{0} result(s) deleted", deletedResults));
            }
        }
Beispiel #8
0
        private static void InitializeProvisioningModules()
        {
            ServiceLog.WriteStart("Loading provisioning modules...");
            provisioningModules = new Dictionary <string, string>();

            Configuration         config  = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            ModuleSettingsSection section = config.Sections["moduleSettings"] as ModuleSettingsSection;

            if (section != null)
            {
                foreach (string key in section.Modules.AllKeys)
                {
                    provisioningModules.Add(key, section.Modules[key].Value);
                }
            }
            else
            {
                ServiceLog.WriteError("Modules configuration section not found");
            }
            ServiceLog.WriteEnd(string.Format("{0} module(s) loaded", provisioningModules.Count));
        }
Beispiel #9
0
 private static void DeleteKvp(string pool, int offset)
 {
     try
     {
         int    delLength = KVP_MAX_KEY_SIZE + KVP_MAX_VALUE_SIZE;
         byte[] fBytes    = File.ReadAllBytes(pool);
         byte[] resArray  = new byte[fBytes.Length - delLength];
         if (offset > 0)
         {
             Array.Copy(fBytes, 0, resArray, 0, offset);
         }
         if (resArray.Length - offset > 0)
         {
             Array.Copy(fBytes, offset + delLength, resArray, offset, resArray.Length - offset);
         }
         File.WriteAllBytes(pool, resArray);
     }
     catch (Exception ex)
     {
         ServiceLog.WriteError("DeleteKvp error: ", ex);
     }
 }
Beispiel #10
0
        private static void InitializeTimers()
        {
            // idle timer
            idleTimer           = new Timer();
            idleTimer.AutoReset = false;
            double idleInterval;

            if (!Double.TryParse(ConfigurationManager.AppSettings["Service.ExitIdleInterval"], out idleInterval))
            {
                ServiceLog.WriteError("Invalid configuration parameter: Service.ExitIdleInterval");
                idleInterval = 600000;
            }
            idleTimer.Interval = idleInterval;
            idleTimer.Enabled  = false;
            idleTimer.Elapsed += new ElapsedEventHandler(OnIdleTimerElapsed);

            if (!Int32.TryParse(ConfigurationManager.AppSettings["Service.RegistryPollInterval"], out pollInterval))
            {
                ServiceLog.WriteError("Invalid configuration parameter: Service.RegistryPollInterval");
                pollInterval = 60000;
            }
        }
Beispiel #11
0
 public static string GetKvpStringValue(string pool, string key)
 {
     try
     {
         string sValue = null;
         byte[] bKey   = new byte[KVP_MAX_KEY_SIZE];
         byte[] bValue = new byte[KVP_MAX_VALUE_SIZE];
         byte[] res;
         int    idx;
         using (FileStream fs = File.Open(pool, FileMode.Open))
         {
             long remaining = fs.Length;
             while (remaining > 0)
             {
                 for (int i = 0; i < KVP_MAX_KEY_SIZE; i++)
                 {
                     bKey[i] = 0;
                 }
                 for (int i = 0; i < KVP_MAX_VALUE_SIZE; i++)
                 {
                     bValue[i] = 0;
                 }
                 int read = fs.Read(bKey, 0, KVP_MAX_KEY_SIZE);
                 remaining -= read;
                 if (remaining <= 0)
                 {
                     break;
                 }
                 read       = fs.Read(bValue, 0, KVP_MAX_VALUE_SIZE);
                 remaining -= read;
                 res        = bKey;
                 idx        = -1;
                 for (int i = 0; i < bKey.Length; i++)
                 {
                     if (bKey[i] == 0)
                     {
                         idx = i;
                         break;
                     }
                 }
                 if (idx != -1)
                 {
                     res = new byte[idx];
                     Array.Copy(bKey, 0, res, 0, idx);
                 }
                 string sKey = System.Text.Encoding.UTF8.GetString(res);
                 sKey = sKey.Replace("\0", "", StringComparison.Ordinal);
                 if (sKey.Equals(key))
                 {
                     res = bValue;
                     idx = -1;
                     for (int i = 0; i < bValue.Length; i++)
                     {
                         if (bValue[i] == 0)
                         {
                             idx = i;
                             break;
                         }
                     }
                     if (idx != -1)
                     {
                         res = new byte[idx];
                         Array.Copy(bValue, 0, res, 0, idx);
                     }
                     sValue = System.Text.Encoding.UTF8.GetString(res);
                     sValue = sValue.Replace("\0", "", StringComparison.Ordinal);
                     break;
                 }
             }
         }
         return(sValue);
     }
     catch (Exception ex)
     {
         ServiceLog.WriteError("GetKvpStringValue error: ", ex);
         return(null);
     }
 }
Beispiel #12
0
        private static void InstallService_FreeBSD()
        {
            const string rcConf       = "/etc/rc.conf";
            const string compatLinux  = "/compat/linux";
            const string serviceName  = "solidcp";
            const string servicesPath = "/etc/rc.d/";
            string       userName     = Environment.UserName;
            string       appPath      = AppDomain.CurrentDomain.BaseDirectory;

            List <string> config = new List <string>();

            config.Add("#!/bin/sh");
            config.Add("");
            config.Add("# SolidCP LinuxVmConfig Service");
            config.Add("# PROVIDE: " + serviceName);
            config.Add("# REQUIRE: DAEMON networking");
            config.Add("# BEFORE:  LOGIN");
            config.Add("");
            config.Add(". /etc/rc.subr");
            config.Add("");
            config.Add("name=" + serviceName);
            config.Add("rcvar=" + serviceName + "_enable");
            config.Add(serviceName + "_user=\"" + userName + "\"");
            config.Add("command=\"" + appPath + "SolidCP.LinuxVmConfig" + "\"");
            config.Add("pidfile=\"/var/run/" + serviceName + ".pid\"");
            config.Add("");
            config.Add("start_cmd=\"" + serviceName + "_start\"");
            config.Add("stop_cmd=\"" + serviceName + "_stop\"");
            config.Add("status_cmd=\"" + serviceName + "_status\"");
            config.Add("");
            config.Add(serviceName + "_start() {");
            config.Add("   /usr/sbin/daemon -P ${pidfile} -r -f -u $" + serviceName + "_user $command");
            config.Add("}");
            config.Add("");
            config.Add(serviceName + "_stop() {");
            config.Add("   if [ -e \"${pidfile}\" ]; then");
            config.Add("      kill -s TERM `cat ${pidfile}`");
            config.Add("   else");
            config.Add("      echo \"SolidCP.VmConfig is not running\"");
            config.Add("   fi");
            config.Add("}");
            config.Add("");
            config.Add(serviceName + "_status() {");
            config.Add("   if [ -e \"${pidfile}\" ]; then");
            config.Add("      echo \"SolidCP.VmConfig is running as pid `cat ${pidfile}`\"");
            config.Add("   else");
            config.Add("      echo \"SolidCP.VmConfig is not running\"");
            config.Add("   fi");
            config.Add("}");
            config.Add("");
            config.Add("load_rc_config $name");
            config.Add("run_rc_command \"$1\"");

            File.WriteAllLines(servicesPath + serviceName, config);

            ShellHelper.RunCmd("chmod +x " + servicesPath + serviceName);
            ShellHelper.RunCmd("cp -p " + rcConf + " " + compatLinux + rcConf);
            int pos = TxtHelper.GetStrPos(compatLinux + rcConf, serviceName + "_enable", 0, -1);

            TxtHelper.ReplaceStr(compatLinux + rcConf, serviceName + "_enable=\"YES\"", pos);
            ShellHelper.RunCmd("cp -p " + compatLinux + rcConf + " " + rcConf);

            ExecutionResult res = ShellHelper.RunCmd("service " + serviceName + " start");

            if (res.ResultCode == 1)
            {
                ServiceLog.WriteError("Service install error: " + res.ErrorMessage);
                return;
            }
            ServiceLog.WriteInfo(serviceName + " service successfully installed.");
        }
Beispiel #13
0
        private static void ProcessTasks()
        {
            // delete old results
            DeleteOldResults();

            //process all tasks
            while (true)
            {
                //load completed tasks results
                string[] strResults = KvpUtils.GetKvpKeys(OutputKVP);
                if (strResults == null)
                {
                    break;
                }
                List <string> results = new List <string>();
                foreach (string strResult in strResults)
                {
                    if (!string.IsNullOrEmpty(strResult) && strResult.StartsWith(TaskPrefix) && strResult != CurrentTaskName)
                    {
                        //save only SolidCP tasks
                        results.Add(strResult);
                    }
                }

                // sorted list of tasks - will be sorted by the TaskID (time in ticks)
                SortedList <long, string> tasks = new SortedList <long, string>();

                //load task definitions from input registry key
                string[] strTasks = KvpUtils.GetKvpKeys(InputKVP);
                foreach (string strTask in strTasks)
                {
                    if (results.Contains(strTask))
                    {
                        continue; // skip completed tasks
                    }
                    if (!string.IsNullOrEmpty(strTask) && strTask.StartsWith(TaskPrefix))
                    {
                        // extract Task ID parameter
                        int idx = strTask.LastIndexOf('-');
                        if (idx == -1)
                        {
                            continue;
                        }

                        string strTaskId = strTask.Substring(idx + 1);
                        long   taskId    = 0;
                        try
                        {
                            taskId = Int64.Parse(strTaskId);
                        }
                        catch
                        {
                            continue; // wrong task format
                        }

                        //save only SolidCP tasks
                        if (!tasks.ContainsKey(taskId))
                        {
                            tasks.Add(taskId, strTask);
                        }
                    }
                }
                if (tasks.Count == 0)
                {
                    if (rebootRequired)
                    {
                        ServiceLog.WriteInfo("Reboot required");
                        RebootSystem();
                        return;
                    }

                    StartIdleTimer(); //stops service if idle
                                      //no tasks - exit!
                    return;
                }
                else
                {
                    //stop idle timer as we need to process tasks
                    StopIdleTimer();
                }

                ExecutionContext context = null;
                foreach (long tid in tasks.Keys)
                {
                    //find first correct task
                    string taskDefinition = tasks[tid];
                    string taskParameters = KvpUtils.GetKvpStringValue(InputKVP, taskDefinition);
                    if (taskDefinition.LastIndexOf("-") == -1 || taskDefinition.LastIndexOf('-') == taskDefinition.Length - 1)
                    {
                        ServiceLog.WriteError(string.Format("Task was deleted from queue as its definition is invalid : {0}", taskDefinition));
                        //go to next task
                        continue;
                    }
                    string taskName = taskDefinition.Substring(0, taskDefinition.LastIndexOf("-")).Substring(TaskPrefix.Length);
                    string taskId   = taskDefinition.Substring(taskDefinition.LastIndexOf('-') + 1);

                    if (!provisioningModules.ContainsKey(taskName))
                    {
                        ServiceLog.WriteError(string.Format("Task was deleted from queue as its definition was not found : {0}", taskName));
                        //go to next task
                        continue;
                    }
                    //prepare execution context for correct task
                    context              = new ExecutionContext();
                    context.ActivityID   = taskId;
                    context.ActivityName = taskName;
                    ParseParameters(context.Parameters, taskParameters);
                    context.ActivityDefinition = taskDefinition;
                    break;
                }
                if (context != null)
                {
                    string          type  = provisioningModules[context.ActivityName];
                    ExecutionResult res   = null;
                    DateTime        start = DateTime.Now;

                    try
                    {
                        //load module and run task
                        ServiceLog.WriteStart(string.Format("Starting '{0}' module...", context.ActivityName));
                        context.Progress = 0;
                        switch (context.ActivityName)
                        {
                        case "ChangeComputerName":
                            res = ChangeComputerName.Run(ref context);
                            break;

                        case "ChangeAdministratorPassword":
                            res = ChangeAdministratorPassword.Run(ref context);
                            break;

                        case "SetupNetworkAdapter":
                            res = SetupNetworkAdapter.Run(ref context);
                            break;
                        }
                        context.Progress = 100;
                        ServiceLog.WriteEnd(string.Format("'{0}' module finished.", context.ActivityName));
                    }
                    catch (Exception ex)
                    {
                        ServiceLog.WriteError("Unhandled exception:", ex);
                        res              = new ExecutionResult();
                        res.ResultCode   = -1;
                        res.ErrorMessage = string.Format("Unhandled exception : {0}", ex);
                    }
                    DateTime end = DateTime.Now;
                    SaveExecutionResult(context.ActivityDefinition, res, start, end);

                    if (res.RebootRequired)
                    {
                        rebootRequired = true;
                    }
                }
                System.Threading.Thread.Sleep(1000);
            }
        }