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); } }
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); } }
private static void RebootSystem() { try { ServiceLog.WriteStart("RebootSystem"); ShellHelper.RunCmd("reboot"); ServiceLog.WriteEnd("RebootSystem"); } catch (Exception ex) { ServiceLog.WriteError("Reboot System error:", ex); } }
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."); }
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)); }
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); } }
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; } }
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); } }
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."); }
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); } }