コード例 #1
0
        public static ApplicationContainer GetFromUuid(string containerUuid, Hourglass hourglass = null)
        {
            EtcUser etcUser   = GetPasswdFor(containerUuid);
            string  nameSpace = null;
            Dictionary <string, string> env = Environ.Load(Path.Combine(LinuxFiles.Cygpath(etcUser.Dir, true), ".env"));

            if (!string.IsNullOrEmpty(env["OPENSHIFT_GEAR_DNS"]))
            {
                nameSpace = Regex.Replace(Regex.Replace("testing-uhu.openshift.local", @"\..*$", ""), @"^.*\-", "");
            }

            if (string.IsNullOrEmpty(env["OPENSHIFT_APP_UUID"]))
            {
                //Maybe we should improve the exceptions we throw.
                throw new Exception("OPENSHIFT_APP_UUID is missing!");
            }
            if (string.IsNullOrEmpty(env["OPENSHIFT_APP_NAME"]))
            {
                throw new Exception("OPENSHIFT_APP_NAME is missing!");
            }
            if (string.IsNullOrEmpty(env["OPENSHIFT_GEAR_NAME"]))
            {
                throw new Exception("OPENSHIFT_GEAR_NAME is missing!");
            }

            ApplicationContainer applicationContainer = new ApplicationContainer(env["OPENSHIFT_APP_UUID"], containerUuid, etcUser,
                                                                                 env["OPENSHIFT_APP_NAME"], env["OPENSHIFT_GEAR_NAME"], nameSpace, null, null, hourglass);

            return(applicationContainer);
        }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
 private void CheckUsers()
 {
     VerboseMessage(string.Format("checking {0} user accounts", users.Length));
     foreach (EtcUser user in users)
     {
         if (!Directory.Exists(LinuxFiles.Cygpath(user.Dir, true)))
         {
             DoFail(string.Format("user {0} does not have a home directory {1}", user.Name, user.Dir));
         }
     }
 }
コード例 #4
0
        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);
        }
コード例 #5
0
        public void Create()
        {
            Guid prisonGuid = Guid.Parse(container.Uuid.PadLeft(32, '0'));

            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;
            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);
        }
コード例 #6
0
        private string PopulateGearRepo(string cartName, 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(Guid.Parse(this.container.Uuid.PadLeft(32, '0')));

            // TODO (vladi): make sure there isn't a more elegant way to deal with SQL Server Instances
            if (cartName == "mssql")
            {
                CreateSQLServerInstanceDatabases(cartName, prison);
            }

            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);
        }
コード例 #7
0
        private static void FixHomeDir(string userHomeDir, string username, string gearUuid)
        {
            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);
            }
        }
コード例 #8
0
        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);
        }
コード例 #9
0
ファイル: NodeTest.cs プロジェクト: yonglehou/openshift.net
        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);
        }
コード例 #10
0
        public void Create()
        {
            Guid prisonGuid = Guid.Parse(container.Uuid.PadLeft(32, '0'));

            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.CellType |= Prison.RuleType.Filesystem;
            prisonRules.CellType |= Prison.RuleType.MsSqlInstance;

            prisonRules.CPUPercentageLimit   = Convert.ToInt64(Node.ResourceLimits["cpu_quota"]);
            prisonRules.ActiveProcessesLimit = Convert.ToInt32(Node.ResourceLimits["max_processes"]);
            prisonRules.PriorityClass        = ProcessPriorityClass.BelowNormal;

            // 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;
            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"));

            ProcessResult result = ProcessExtensions.RunCommandAndGetOutput(ProcessExtensions.Get64BitPowershell(), string.Format(
                                                                                @"-ExecutionPolicy Bypass -InputFormat None -noninteractive -file {0} -targetDirectory {2} -user {1} -windowsUser {5} -userHomeDir {3} -userShell {4}",
                                                                                configureScript,
                                                                                container.Uuid,
                                                                                NodeConfig.Values["SSHD_BASE_DIR"],
                                                                                container.ContainerDir,
                                                                                NodeConfig.Values["GEAR_SHELL"],
                                                                                Environment.UserName));

            if (result.ExitCode != 0)
            {
                throw new Exception(string.Format("Error setting up sshd for gear {0} - rc={1}; out={2}; err={3}", container.Uuid, result.ExitCode, result.StdOut, result.StdErr));
            }

            this.container.InitializeHomedir(this.container.BaseDir, this.container.ContainerDir);

            container.AddEnvVar("PRISON_PORT", prisonRules.UrlPortAccess.ToString());

            LinuxFiles.TakeOwnershipOfGearHome(this.container.ContainerDir, prison.User.Username);
        }
コード例 #11
0
        private static void Extract(string method, string source, string target)
        {
            // use intermediate temp directory to reset cygwin directories ACLs
            string tempPath = target + ".temp";

            Directory.CreateDirectory(tempPath);
            Path.Combine(NodeConfig.Values["SSHD_BASE_DIR"], @"bin\tar.exe");
            Logger.Debug("Extracting {0} to {2} using {1} method", source, method, target);
            switch (method)
            {
            case "zip":
            {
                ZipFile.ExtractToDirectory(source, tempPath);
                break;
            }

            case "tgz":
            {
                ProcessResult result = ProcessExtensions.RunCommandAndGetOutput(Path.Combine(NodeConfig.Values["SSHD_BASE_DIR"], @"bin\tar.exe"), string.Format("-C {0} -zxpf {1}", LinuxFiles.Cygpath(tempPath), LinuxFiles.Cygpath(source)));
                Logger.Debug(result.StdOut + result.StdErr);
                break;
            }

            case "tar":
            {
                ProcessResult result = ProcessExtensions.RunCommandAndGetOutput(Path.Combine(NodeConfig.Values["SSHD_BASE_DIR"], @"bin\tar.exe"), string.Format("-C {0} -xpf {1}", LinuxFiles.Cygpath(tempPath), LinuxFiles.Cygpath(source)));
                Logger.Debug(result.StdOut + result.StdErr);
                break;
            }

            default:
            {
                throw new Exception(string.Format("Packaging method {0} not yet supported.", method));
            }
            }

            DirectoryUtil.DirectoryCopy(tempPath, target, true);
            Directory.Delete(tempPath, true);

            string[] files = Directory.GetFileSystemEntries(target);
            if (files.Length == 1)
            {
                Logger.Debug(string.Join(",", files));
                // A directory of one file is not legal move everyone up a level (github zip's are this way)
                string to_delete = files[0] + ".to_delete";
                Directory.Move(files[0], to_delete);
                DirectoryUtil.DirectoryCopy(to_delete, target, true);
                Directory.Delete(to_delete);
            }
        }