private void FixHomeDir() { string userHomeDir = this.ContainerDir; string username = null; string gearUuid = this.Uuid; if (Environment.UserName.StartsWith(Prison.PrisonUser.GlobalPrefix)) { username = Environment.UserName; } else { username = Prison.Prison.LoadPrisonAndAttach(PrisonIdConverter.Generate(this.Uuid)).User.Username; } if (!string.IsNullOrEmpty(userHomeDir)) { LinuxFiles.TakeOwnershipOfGearHome(userHomeDir, username); Logger.Debug("Fixing symlinks for gear {0}", gearUuid); try { LinuxFiles.FixSymlinks(Path.Combine(userHomeDir, "app-deployments")); } catch (Exception ex) { Logger.Error("There was an error while trying to fix symlinks for gear {0}: {1} - {2}", gearUuid, ex.Message, ex.StackTrace); } } else { Logger.Warning("Not taking ownership or fixing symlinks for gear {0}. Could not locate its home directory.", gearUuid); } }
public ReturnStatus Execute() { ReturnStatus status = new ReturnStatus(); try { Dictionary <string, string> envVars = new Dictionary <string, string>(); //string homeDir = Environment.GetEnvironmentVariable("HOME"); string homeDir = Path.Combine(@"C:\openshift\gears", Uuid); UserShellTrap.SetupGearEnv(envVars, homeDir); string userHomeDir = envVars.ContainsKey("OPENSHIFT_HOMEDIR") && Directory.Exists(envVars["OPENSHIFT_HOMEDIR"]) ? envVars["OPENSHIFT_HOMEDIR"] : string.Empty; var prison = Prison.Prison.LoadPrisonAndAttach(PrisonIdConverter.Generate(Uuid)); UserShellTrap.FixHomeDir(userHomeDir, prison.User.Username, Uuid); if (Directory.Exists(Path.Combine(homeDir, "mssql"))) { string[] instancefolderinfo = Directory.GetDirectories(Path.Combine(homeDir, "mssql", "bin")).First().Split('.'); instancefolderinfo[0] = instancefolderinfo[0].Substring(instancefolderinfo[0].LastIndexOf('\\') + 1); Logger.Info("Reconfiguring registry after move with parameters {0},{1} for user {2}", instancefolderinfo[0], instancefolderinfo[1], prison.User.Username); switch (instancefolderinfo[0]) { case "MSSQL11": { Prison.MsSqlInstanceTool.ConfigureMsSqlInstanceRegistry(prison, instancefolderinfo[0], "MSSQLSERVER2012"); break; } case "MSSQL10_50": { Prison.MsSqlInstanceTool.ConfigureMsSqlInstanceRegistry(prison, instancefolderinfo[0], "MSSQLSERVER"); break; } default: { throw new Exception("Unsupported MSSQL version!"); } } foreach (string file in Directory.GetFiles(Path.Combine(homeDir, "mssql", "bin", instancefolderinfo[0] + "." + instancefolderinfo[1], "mssql", "DATA"))) { FileSecurity fSecurity = File.GetAccessControl(file); fSecurity.AddAccessRule(new FileSystemAccessRule(prison.User.Username, FileSystemRights.FullControl , AccessControlType.Allow)); File.SetAccessControl(file, fSecurity); } } status.ExitCode = 0; } catch (Exception ex) { Logger.Error("Error running oo-admin-restore-acls command: {0} - {1}", ex.Message, ex.StackTrace); status.Output = ex.ToString(); status.ExitCode = 1; } return(status); }
private string PopulateGearRepo(string cartName, string softwareVersion, string templateGitUrl) { ApplicationRepository repo = new ApplicationRepository(this.container); if (string.IsNullOrEmpty(templateGitUrl)) { repo.PopulateFromCartridge(cartName); } else { repo.PopulateFromUrl(cartName, templateGitUrl); } if (repo.Exists()) { repo.Archive(Path.Combine(this.container.ContainerDir, "app-root", "runtime", "repo"), "master"); } var prison = Prison.Prison.LoadPrisonNoAttach(PrisonIdConverter.Generate(this.container.Uuid)); // TODO (vladi): make sure there isn't a more elegant way to deal with SQL Server Instances if (cartName == "mssql" && softwareVersion == "2008") { Uhuru.Prison.MsSqlInstanceTool.ConfigureMsSqlInstanceRegistry(prison, "MSSQL10_50", "MSSQLSERVER"); CreateSQLServerInstanceDatabases(cartName, prison, "MSSQL10_50", "MSSQLSERVER"); ChangeConfigControl(cartName, softwareVersion, "MSSQL10_50"); } else if (cartName == "mssql" && softwareVersion == "2012") { Uhuru.Prison.MsSqlInstanceTool.ConfigureMsSqlInstanceRegistry(prison, "MSSQL11", "MSSQLSERVER2012"); CreateSQLServerInstanceDatabases(cartName, prison, "MSSQL11", "MSSQLSERVER2012"); ChangeConfigControl(cartName, softwareVersion, "MSSQL11"); } Logger.Debug("Setting permisions to home dir gear {0}, prison user {1}", this.container.Uuid, prison.User.Username); LinuxFiles.TakeOwnershipOfGearHome(this.container.ContainerDir, prison.User.Username); string gitDir = Path.Combine(this.container.ContainerDir, "git", "template", ".git"); Logger.Debug("Setting permisions to git dir {0}, prison user {1}", gitDir, prison.User.Username); if (Directory.Exists(gitDir)) { LinuxFiles.TakeOwnership(gitDir, prison.User.Username); } Logger.Debug("Setting permisions to git dir {0}, prison user {1}", repo.RepositoryPath, prison.User.Username); LinuxFiles.TakeOwnership(repo.RepositoryPath, prison.User.Username); return(string.Empty); }
public void KillAll(int termDelaySec) { var prison = Prison.Prison.LoadPrisonAndAttach(PrisonIdConverter.Generate(this.container.Uuid)); Logger.Debug("Stopping prison for gear {0}", this.container.Uuid); var start = DateTime.Now; while (prison.JobObject.ActiveProcesses > 0 && (DateTime.Now - start).TotalSeconds < termDelaySec) { Thread.Sleep(200); } prison.ForceStop(); }
public string Destroy() { StringBuilder output = new StringBuilder(); output.AppendLine(this.container.KillProcs()); output.AppendLine(RemoveSshdUser()); var prison = Prison.Prison.LoadPrisonAndAttach(PrisonIdConverter.Generate(this.container.Uuid)); Logger.Debug("Destroying prison for gear {0}", this.container.Uuid); prison.Destroy(); Directory.Delete(this.container.ContainerDir, true); return(output.ToString()); }
private void CreateCartridgeDirectory(Manifest cartridge, string softwareVersion) { string target = Path.Combine(this.container.ContainerDir, cartridge.Dir); CartridgeRepository.InstantiateCartridge(cartridge, target); string ident = Manifest.BuildIdent(cartridge.CartridgeVendor, cartridge.Name, softwareVersion, cartridge.CartridgeVersion); Dictionary <string, string> envs = new Dictionary <string, string>(); envs[string.Format("{0}_DIR", cartridge.ShortName)] = target + Path.DirectorySeparatorChar; envs[string.Format("{0}_IDENT", cartridge.ShortName)] = ident; WriteEnvironmentVariables(Path.Combine(target, "env"), envs); envs = new Dictionary <string, string>(); if (!string.IsNullOrEmpty(this.container.Namespace)) { envs["namespace"] = this.container.Namespace; } Dictionary <string, string> currentGearEnv = Environ.ForGear(this.container.ContainerDir); if (!currentGearEnv.ContainsKey("OPENSHIFT_PRIMARY_CARTRIDGE_DIR")) { envs["PRIMARY_CARTRIDGE_DIR"] = target + Path.DirectorySeparatorChar; } if (envs.Count > 0) { WriteEnvironmentVariables(Path.Combine(this.container.ContainerDir, ".env"), envs); } var prison = Prison.Prison.LoadPrisonNoAttach(PrisonIdConverter.Generate(this.container.Uuid)); Logger.Debug("Setting permisions to dir {0}, prison user {1}", target, prison.User.Username); LinuxFiles.TakeOwnership(target, prison.User.Username); Logger.Info("Created cartridge directory {0}/{1}", container.Uuid, cartridge.Dir); }
public void Create() { Guid prisonGuid = PrisonIdConverter.Generate(container.Uuid); Logger.Debug("Creating prison with guid: {0}", prisonGuid); Uhuru.Prison.Prison prison = new Uhuru.Prison.Prison(prisonGuid); prison.Tag = "oo"; Uhuru.Prison.PrisonRules prisonRules = new Uhuru.Prison.PrisonRules(); prisonRules.CellType = Prison.RuleType.None; prisonRules.CellType |= Prison.RuleType.Memory; prisonRules.CellType |= Prison.RuleType.CPU; prisonRules.CellType |= Prison.RuleType.WindowStation; prisonRules.CellType |= Prison.RuleType.Httpsys; prisonRules.CellType |= Prison.RuleType.IISGroup; prisonRules.CPUPercentageLimit = Convert.ToInt64(Node.ResourceLimits["cpu_quota"]); prisonRules.ActiveProcessesLimit = Convert.ToInt32(Node.ResourceLimits["max_processes"]); prisonRules.PriorityClass = ProcessPriorityClass.Normal; // TODO: vladi: make sure these limits are ok being the same prisonRules.NetworkOutboundRateLimitBitsPerSecond = Convert.ToInt64(Node.ResourceLimits["max_upload_bandwidth"]); prisonRules.AppPortOutboundRateLimitBitsPerSecond = Convert.ToInt64(Node.ResourceLimits["max_upload_bandwidth"]); prisonRules.TotalPrivateMemoryLimitBytes = Convert.ToInt64(Node.ResourceLimits["max_memory"]) * 1024 * 1024; prisonRules.DiskQuotaBytes = Convert.ToInt64(Node.ResourceLimits["quota_blocks"]) * 1024; prisonRules.PrisonHomePath = container.ContainerDir; //NodeConfig.Values["PORTS_PER_USER"] should be used DistrictConfig.Values["first_uid"] if available in the configuration try { try { prisonRules.UrlPortAccess = Network.GetAvailablePort(container.uid, NodeConfig.Values["GEAR_BASE_DIR"], Int32.Parse(NodeConfig.Values["PORTS_PER_USER"]), Int32.Parse(DistrictConfig.Values["first_uid"]), Int32.Parse(NodeConfig.Values["STARTING_PORT"])); } catch { prisonRules.UrlPortAccess = Network.GetAvailablePort(container.uid, NodeConfig.Values["GEAR_BASE_DIR"], Int32.Parse(NodeConfig.Values["PORTS_PER_USER"]), 0, Int32.Parse(NodeConfig.Values["STARTING_PORT"])); } } catch (Exception ex) { Logger.Debug("GetAvailablePort could not be called with all arguments: {0}", ex.Message.ToString()); prisonRules.UrlPortAccess = Network.GetAvailablePort(container.uid, NodeConfig.Values["GEAR_BASE_DIR"]); } //prisonRules.UrlPortAccess = Network.GetUniquePredictablePort(@"c:\openshift\ports"); Logger.Debug("Assigning port {0} to gear {1}", prisonRules.UrlPortAccess, container.Uuid); prison.Lockdown(prisonRules); // Configure SSHD for the new prison user string binLocation = Path.GetDirectoryName(this.GetType().Assembly.Location); string configureScript = Path.GetFullPath(Path.Combine(binLocation, @"powershell\Tools\sshd\configure-sshd.ps1")); Sshd.ConfigureSshd(NodeConfig.Values["SSHD_BASE_DIR"], container.Uuid, Environment.UserName, container.ContainerDir, NodeConfig.Values["GEAR_SHELL"]); this.container.InitializeHomedir(this.container.BaseDir, this.container.ContainerDir); container.AddEnvVar("PRISON_PORT", prisonRules.UrlPortAccess.ToString()); LinuxFiles.TakeOwnershipOfGearHome(this.container.ContainerDir, prison.User.Username); }
public void Test_ApplicationContainer() { bool testresults = true; try { using (ShimsContext.Create()) { ShimApplicationContainer container = new ShimApplicationContainer(TestHelper.CreateAppContainer()); container.CreateString = new FakesDelegates.Func <string, string>((string a) => { ShimContainerPlugin containerPlugin = new ShimContainerPlugin(new ContainerPlugin(container.Instance)); containerPlugin.Create = new FakesDelegates.Action(() => { Guid prisonGuid = PrisonIdConverter.Generate(container.Instance.Uuid); Logger.Debug("Creating prison with guid: {0}", prisonGuid); ShimPrison prison = new ShimPrison(new Uhuru.Prison.Prison(prisonGuid)); prison.Instance.Tag = "oo"; Uhuru.Prison.PrisonRules prisonRules = new Uhuru.Prison.PrisonRules(); prisonRules.CellType = Prison.RuleType.None; prisonRules.CellType |= Prison.RuleType.Memory; prisonRules.CellType |= Prison.RuleType.CPU; prisonRules.CellType |= Prison.RuleType.WindowStation; prisonRules.CellType |= Prison.RuleType.Httpsys; prisonRules.CellType |= Prison.RuleType.IISGroup; prisonRules.CPUPercentageLimit = Convert.ToInt64(Node.ResourceLimits["cpu_quota"]); prisonRules.ActiveProcessesLimit = Convert.ToInt32(Node.ResourceLimits["max_processes"]); prisonRules.PriorityClass = ProcessPriorityClass.Normal; // TODO: vladi: make sure these limits are ok being the same prisonRules.NetworkOutboundRateLimitBitsPerSecond = Convert.ToInt64(Node.ResourceLimits["max_upload_bandwidth"]); prisonRules.AppPortOutboundRateLimitBitsPerSecond = Convert.ToInt64(Node.ResourceLimits["max_upload_bandwidth"]); prisonRules.TotalPrivateMemoryLimitBytes = Convert.ToInt64(Node.ResourceLimits["max_memory"]) * 1024 * 1024; prisonRules.DiskQuotaBytes = Convert.ToInt64(Node.ResourceLimits["quota_blocks"]) * 1024; prisonRules.PrisonHomePath = container.Instance.ContainerDir; //NodeConfig.Values["PORTS_PER_USER"] should be used DistrictConfig.Values["first_uid"] if available in the configuration try { try { prisonRules.UrlPortAccess = Network.GetAvailablePort(container.Instance.uid, NodeConfig.Values["GEAR_BASE_DIR"], Int32.Parse(NodeConfig.Values["PORTS_PER_USER"]), Int32.Parse(DistrictConfig.Values["first_uid"]), Int32.Parse(NodeConfig.Values["STARTING_PORT"])); } catch { prisonRules.UrlPortAccess = Network.GetAvailablePort(container.Instance.uid, NodeConfig.Values["GEAR_BASE_DIR"], Int32.Parse(NodeConfig.Values["PORTS_PER_USER"]), 0, Int32.Parse(NodeConfig.Values["STARTING_PORT"])); } } catch (Exception ex) { Logger.Debug("GetAvailablePort could not be called with all arguments: {0}", ex.Message.ToString()); prisonRules.UrlPortAccess = Network.GetAvailablePort(container.Instance.uid, NodeConfig.Values["GEAR_BASE_DIR"]); } //prisonRules.UrlPortAccess = Network.GetUniquePredictablePort(@"c:\openshift\ports"); Logger.Debug("Assigning port {0} to gear {1}", prisonRules.UrlPortAccess, container.Instance.Uuid); prison.LockdownPrisonRules = new FakesDelegates.Action <Prison.PrisonRules>((Uhuru.Prison.PrisonRules rules) => { }); prison.Instance.Lockdown(prisonRules); // Configure SSHD for the new prison user string binLocation = Path.GetDirectoryName(this.GetType().Assembly.Location); string configureScript = Path.GetFullPath(Path.Combine(binLocation, @"powershell\Tools\sshd\configure-sshd.ps1")); Sshd.ConfigureSshd(NodeConfig.Values["SSHD_BASE_DIR"], container.Instance.Uuid, Environment.UserName, container.Instance.ContainerDir, NodeConfig.Values["GEAR_SHELL"]); container.Instance.InitializeHomedir(container.Instance.BaseDir, container.Instance.ContainerDir); container.Instance.AddEnvVar("PRISON_PORT", prisonRules.UrlPortAccess.ToString()); LinuxFiles.TakeOwnershipOfGearHome(container.Instance.ContainerDir, Environment.UserName); }); containerPlugin.Instance.Create(); return(string.Empty); }); container.Instance.Create(); if (container.Instance.StopLock == true) { testresults = false; } Uhuru.Openshift.Runtime.Model.GearRegistry reg = container.Instance.GearRegist; ShimApplicationContainer test2 = new ShimApplicationContainer(ApplicationContainer.GetFromUuid(container.Instance.Uuid)); if (test2.Instance == null) { testresults = false; } AuthorizedKeysFile file = new AuthorizedKeysFile(container.Instance); if (file == null) { testresults = false; } List <SshKey> keys = new List <SshKey>(); SshKey key = new SshKey(); key.Comment = "testComment"; key.Key = "TestKey"; keys.Add(key); file.ReplaceKeys(keys); container.Instance.AddSshKey("myKey", string.Empty, "CommentTest"); container.Instance.AddSshKeys(keys); Dictionary <string, string> TestDict = new Dictionary <string, string>(); TestDict.Add("test", "testvalue"); List <string> UserVarTest = new List <string>() { "Hello", "World" }; container.Instance.AddUserVar(TestDict, UserVarTest); container.Instance.AddEnvVar("testKey", "testValue"); container.Instance.AddEnvVar("testKey1", "testValue", true); if (container.Instance.AllDeploymentsByActivation().Count == 0) { testresults = false; } //TO DO:Investigate this //RubyHash options = new RubyHash(); //options["deployment_id"] = "1"; //container.Instance.Activate(options); } } catch { testresults = false; } Assert.AreEqual(true, testresults); }
public static int StartShell(string args) { string assemblyLocation = Path.GetDirectoryName(typeof(UserShellTrap).Assembly.Location); Dictionary <string, string> envVars = new Dictionary <string, string>(); foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) { if (PassEnvs.Contains(de.Key)) { envVars[de.Key.ToString()] = de.Value.ToString(); } } string homeDir = Environment.GetEnvironmentVariable("HOME"); SetupGearEnv(envVars, homeDir); envVars["CYGWIN"] = "nodosfilewarning winsymlinks:native"; envVars["TEMP"] = Path.Combine(envVars["OPENSHIFT_HOMEDIR"], ".tmp"); envVars["TMP"] = envVars["TEMP"]; string arguments = string.Empty; if (args.StartsWith("\"")) { arguments = Regex.Replace(args, @"\A""[^""]+""\s", ""); } else { arguments = Regex.Replace(args, @"\A[^\s]+", ""); } string bashBin = Path.Combine(NodeConfig.Values["SSHD_BASE_DIR"], @"bin\bash.exe"); string gearUuid = envVars.ContainsKey("OPENSHIFT_GEAR_UUID") ? envVars["OPENSHIFT_GEAR_UUID"] : string.Empty; int exitCode = 0; if (Environment.UserName.StartsWith(Prison.PrisonUser.GlobalPrefix)) { ProcessStartInfo shellStartInfo = new ProcessStartInfo(); // System.Diagnostics.Process will merge the specified envs with the current existing ones foreach (string key in envVars.Keys) { shellStartInfo.EnvironmentVariables[key] = envVars[key]; } shellStartInfo.FileName = bashBin; shellStartInfo.Arguments = string.Format(@"--norc --login --noprofile {0}", arguments); shellStartInfo.UseShellExecute = false; Logger.Debug("Started trapped bash for gear {0}", gearUuid); Process shell = Process.Start(shellStartInfo); shell.WaitForExit(); exitCode = shell.ExitCode; Logger.Debug("Process '{0}' exited with code '{1}'", shell.Id, shell.ExitCode); } else { string userHomeDir = envVars.ContainsKey("OPENSHIFT_HOMEDIR") && Directory.Exists(envVars["OPENSHIFT_HOMEDIR"]) ? envVars["OPENSHIFT_HOMEDIR"] : string.Empty; var prison = Prison.Prison.LoadPrisonAndAttach(PrisonIdConverter.Generate(gearUuid)); FixHomeDir(userHomeDir, prison.User.Username, gearUuid); Logger.Debug("Starting trapped bash for gear {0}", gearUuid); var process = prison.Execute(bashBin, string.Format("--norc --login --noprofile {0}", arguments), false, envVars); process.WaitForExit(); exitCode = process.ExitCode; Logger.Debug("Process '{0}' exited with code '{1}'", process.Id, exitCode); } return(exitCode); }