private void StartStagingInstance(StagingInstance instance, StagingStartMessageRequest pmessage)
        {
            StagingWorkspace workspace = new StagingWorkspace(instance.Properties.Directory);
            try
            {
                try
                {
                    instance.Lock.EnterWriteLock();

                    instance.Properties.UseDiskQuota = this.useDiskQuota;
                    instance.Properties.UploadThrottleBitsps = this.uploadThrottleBitsps;

                    UriBuilder streamingLog = new UriBuilder();
                    streamingLog.Host = this.ExternalHost;
                    streamingLog.Scheme = "http";
                    streamingLog.Path = string.Format("/staging_tasks/{0}/file_path", pmessage.TaskID);
                    streamingLog.Query = string.Format("path={0}&timestamp={1}", workspace.StagingLogSuffix, RubyCompatibility.DateTimeToEpochSeconds(DateTime.Now));

                    instance.Properties.StreamingLogUrl = DEAUtilities.GetHmacedUri(streamingLog.Uri.ToString(), this.directoryServerHmacKey, new string[] { "path", "timestamp" }).ToString();
                    instance.Workspace = workspace;
                    instance.Properties.TaskLog = workspace.StagingLogPath;
                }
                finally
                {
                    instance.Lock.ExitWriteLock();
                }

                instance.AfterSetup += new StagingInstance.StagingTaskEventHandler(this.AfterStagingSetup);

                Logger.Info("Started staging task {0}", instance.Properties.TaskId);
                try
                {
                    instance.SetupStagingEnvironment();
                }
                catch (Exception ex)
                {
                    Logger.Error("Error setting up staging environment: ", ex.ToString());
                    throw ex;
                }

                instance.UnpackDroplet();
                instance.PrepareStagingDirs();

                if (File.Exists(this.logyardUidPath))
                {
                    LogyardInstanceRequest logyardMsg = new LogyardInstanceRequest();
                    logyardMsg.AppGUID = pmessage.AppID;
                    logyardMsg.AppName = pmessage.StartMessage.Name;
                    logyardMsg.AppSpace = "";
                    logyardMsg.DockerId = instance.Properties.InstanceId;
                    logyardMsg.Index = -1;
                    logyardMsg.LogFiles = new Dictionary<string, string>() { { "staging", Path.Combine("staging", instance.Workspace.StagingLogSuffix) } };
                    logyardMsg.Type = "staging";
                    logyardMsg.RootPath = instance.Workspace.BaseDir;

                    string logyardId = File.ReadAllText(this.logyardUidPath).Trim();
                    this.deaReactor.SendLogyardNotification(logyardId, logyardMsg.SerializeToJson());
                }
                instance.CreatePrison();

                if (pmessage.Properties.Environment != null) {
                    Dictionary<string, string> stagingEnvVars = this.ParseEnvironmnetVariables(pmessage.Properties.Environment);
                    instance.Container.User.SetUserEnvironmentVariables(stagingEnvVars);
                }

                instance.GetBuildpack(pmessage, this.gitPath, this.buildpacksDir);
                this.stagingTaskRegistry.ScheduleSnapshotStagingState();

                try
                {
                    Logger.Info("Staging task {0}: Running compilation script", pmessage.TaskID);

                    this.stagingTaskRegistry.ScheduleSnapshotStagingState();
                    instance.CompileProcess = instance.Buildpack.StartCompile(instance.Container);

                    instance.Lock.EnterWriteLock();
                    instance.Properties.Start = DateTime.Now;
                }
                finally
                {
                    if (instance.Lock.IsWriteLockHeld)
                    {
                        instance.Lock.ExitWriteLock();
                    }
                }
            }
            catch (Exception ex)
            {
                instance.StagingException = ex;
                instance.Properties.Stopped = true;
                Logger.Error(ex.ToString());
            }
        }
        private void StartDropletInstance(DropletInstance instance, string sha1, string executableFile, string executableUri)
        {
            try
            {
                try
                {
                    instance.Lock.EnterWriteLock();

                    var containerRules = new CloudFoundry.WindowsPrison.PrisonConfiguration();

                    containerRules.PrisonHomeRootPath = instance.Properties.Directory;

                    containerRules.Rules |= CloudFoundry.WindowsPrison.RuleTypes.WindowStation;
                    containerRules.Rules |= CloudFoundry.WindowsPrison.RuleTypes.IISGroup;

                    containerRules.TotalPrivateMemoryLimitBytes = instance.Properties.MemoryQuotaBytes;
                    containerRules.PriorityClass = ProcessPriorityClass.BelowNormal;
                    containerRules.ActiveProcessesLimit = 10;

                    if (this.uploadThrottleBitsps > 0)
                    {
                        containerRules.Rules |= CloudFoundry.WindowsPrison.RuleTypes.Network;
                        containerRules.NetworkOutboundRateLimitBitsPerSecond = this.uploadThrottleBitsps;
                        containerRules.AppPortOutboundRateLimitBitsPerSecond = this.uploadThrottleBitsps;
                    }

                    containerRules.Rules |= CloudFoundry.WindowsPrison.RuleTypes.Httpsys;
                    containerRules.UrlPortAccess = instance.Properties.Port;

                    if (this.useDiskQuota)
                    {
                        containerRules.Rules |= CloudFoundry.WindowsPrison.RuleTypes.Disk;
                        containerRules.DiskQuotaBytes = instance.Properties.DiskQuotaBytes;
                    }

                    //var prisonInfo = new ProcessPrisonCreateInfo();

                    //prisonInfo.Id = instance.Properties.InstanceId;
                    //prisonInfo.TotalPrivateMemoryLimitBytes = instance.Properties.MemoryQuotaBytes;

                    //if (this.useDiskQuota)
                    //{
                    //    prisonInfo.DiskQuotaBytes = instance.Properties.DiskQuotaBytes;
                    //    prisonInfo.DiskQuotaPath = instance.Properties.Directory;
                    //}

                    //if (this.uploadThrottleBitsps > 0)
                    //{
                    //    prisonInfo.NetworkOutboundRateLimitBitsPerSecond = this.uploadThrottleBitsps;
                    //}

                    //prisonInfo.UrlPortAccess = instance.Properties.Port;

                    instance.Prison.Tag = "dea";
                    instance.Properties.ContainerId = instance.Prison.Id.ToString();

                    Logger.Info("Creating Process Prisson: {0}", instance.Properties.ContainerId);

                    instance.Prison.Lockdown(containerRules);

                    //instance.Prison.Create(prisonInfo);

                    Logger.Info("Opening firewall port {0} for instance {1}", instance.Properties.Port, instance.Properties.LoggingId);

                    FirewallTools.OpenPort(instance.Properties.Port, instance.Properties.InstanceId);

                    instance.Properties.WindowsUserName = instance.Prison.User.UserName;
                    instance.Properties.WindowsPassword = instance.Prison.User.Password;

                    //instance.Properties.WindowsPassword = instance.Prison.WindowsPassword;
                    //instance.Properties.WindowsUserName = instance.Prison.WindowsUsername;
                }
                finally
                {
                    instance.Lock.ExitWriteLock();
                }

                string tgzFile = Path.Combine(this.fileResources.StagedDir, sha1 + ".tgz");
                this.fileResources.PrepareAppDirectory(executableFile, executableUri, sha1, tgzFile, instance);
                Logger.Debug(Strings.Downloadcompleate);

                string starting = string.Format(CultureInfo.InvariantCulture, Strings.StartingUpInstanceOnPort, instance.Properties.LoggingId, instance.Properties.Port);

                Logger.Info(starting);

                Logger.Debug(Strings.Clients, this.monitoring.Clients);
                Logger.Debug(Strings.ReservedMemoryUsageMb, this.monitoring.MemoryReservedMbytes, this.monitoring.MaxMemoryMbytes);

                try
                {
                    instance.Lock.EnterWriteLock();

                    instance.Properties.EnvironmentVariables.Add(VcapWindowsUserVariable, instance.Properties.WindowsUserName);
                    instance.Properties.EnvironmentVariables.Add(VcapWindowsUserPasswordVariable, instance.Properties.WindowsPassword);

                    instance.Prison.User.SetUserEnvironmentVariables(instance.Properties.EnvironmentVariables);
                }
                finally
                {
                    instance.Lock.ExitWriteLock();
                }

                DateTime start = DateTime.Now;

                string startSciprtPath = this.CreateStartScript(instance);

                instance.Prison.Execute(null, startSciprtPath, Path.Combine(instance.Properties.Directory, "app"), false, null, null, null, null);

                Logger.Debug(Strings.TookXTimeToLoadConfigureAndStartDebugMessage, (DateTime.Now - start).TotalSeconds);

                try
                {
                    instance.Lock.EnterWriteLock();

                    if (!instance.Properties.StopProcessed)
                    {
                        this.droplets.ScheduleSnapshotAppState();
                    }
                }
                finally
                {
                    instance.Lock.ExitWriteLock();
                }

                if (File.Exists(this.logyardUidPath))
                {
                    LogyardInstanceRequest logyardMsg = new LogyardInstanceRequest();
                    logyardMsg.AppGUID = instance.Properties.DropletId;
                    logyardMsg.AppName = instance.Properties.Name;
                    logyardMsg.AppSpace = "";
                    logyardMsg.DockerId = instance.Properties.InstanceId;
                    logyardMsg.Index = -1;
                    Dictionary<string, string> logfiles = new Dictionary<string, string>();
                    logfiles["stdout"] = @"logs\stdout.log";
                    logfiles["stderr"] = @"logs\stderr.log";
                    logyardMsg.LogFiles = logfiles;
                    logyardMsg.Type = "app";
                    logyardMsg.RootPath = instance.Properties.Directory;

                    string logyardId = File.ReadAllText(this.logyardUidPath).Trim();
                    this.deaReactor.SendLogyardNotification(logyardId, logyardMsg.SerializeToJson());
                }
                this.DetectAppReady(instance);
            }
            catch (Exception ex)
            {
                Logger.Warning(Strings.FailedStagingAppDir, instance.Properties.Directory, instance.Properties.LoggingId, ex.ToString());
                try
                {
                    instance.Lock.EnterWriteLock();

                    instance.Properties.State = DropletInstanceState.Crashed;
                    instance.Properties.ExitReason = DropletExitReason.Crashed;
                    instance.Properties.StateTimestamp = DateTime.Now;

                    this.StopDroplet(instance);
                }
                finally
                {
                    instance.Lock.ExitWriteLock();
                }
            }
        }