Ejemplo n.º 1
0
        private void UploadDroplet()
        {
            Uri uri = new Uri(this.Message.UploadURI);

            Logger.Debug("Staging task {0}: Uploading droplet {1} to {2}", this.TaskId, this.workspace.StagedDroplet, this.Message.UploadURI);
            DEAUtilities.HttpUploadFile(this.Message.UploadURI, new FileInfo(this.workspace.StagedDropletPath), "upload[droplet]", "application/octet-stream", uri.UserInfo);
        }
Ejemplo n.º 2
0
        public void GetBuildpack(StagingStartMessageRequest message, string gitPath, string buildpacksDir)
        {
            try
            {
                this.CreatePrison();
                if (message.Properties.Buildpack != null)
                {
                    Logger.Info("Staging task {0}: Downloading buildpack from {1}", this.Properties.TaskId, message.Properties.Buildpack);
                    Directory.CreateDirectory(Path.Combine(this.Workspace.TempDir, "buildpacks"));
                    string buildpackPath = Path.Combine(this.Workspace.TempDir, "buildpacks", Path.GetFileName(new Uri(message.Properties.Buildpack).LocalPath));
                    string command       = string.Format("\"{0}\" clone --quiet --recursive {1} {2}", gitPath, message.Properties.Buildpack, buildpackPath);
                    Logger.Debug(command);
                    int success = Command.ExecuteCommand(command, this.Workspace.TempDir);
                    if (success != 0)
                    {
                        throw new Exception(string.Format("Failed to git clone buildpack. Exit code: {0}", success));
                    }
                    this.Buildpack = new Buildpack(buildpackPath, Path.Combine(this.Workspace.StagedDir, "app"), this.Workspace.Cache, this.Workspace.StagingLogPath);

                    bool detected = this.Buildpack.Detect(this.Prison);
                    if (!detected)
                    {
                        throw new Exception("Buildpack does not support this application.");
                    }
                }
                else
                {
                    Logger.Info("Staging task {0}: Detecting buildpack", this.Properties.TaskId);
                    foreach (string dir in Directory.EnumerateDirectories(buildpacksDir))
                    {
                        DEAUtilities.DirectoryCopy(dir, Path.Combine(this.Workspace.TempDir, "buildpack"), true);
                        Buildpack bp      = new Buildpack(Path.Combine(this.Workspace.TempDir, "buildpack"), Path.Combine(this.Workspace.StagedDir, "app"), this.Workspace.Cache, this.Workspace.StagingLogPath);
                        bool      success = bp.Detect(this.Prison);
                        if (success)
                        {
                            this.Buildpack = bp;
                            break;
                        }
                        else
                        {
                            Directory.Delete(Path.Combine(this.Workspace.TempDir, "buildpack"), true);
                        }
                    }

                    if (this.Buildpack == null)
                    {
                        throw new Exception("Unable to detect a supported application type");
                    }
                    Logger.Info("Staging task {0}: Detected buildpack {1}", this.Properties.TaskId, this.Buildpack.Name);
                }
                this.Properties.DetectedBuildpack = this.Buildpack.Name;
            }
            finally
            {
                if (this.Prison.Created)
                {
                    this.Prison.Destroy();
                }
            }
        }
Ejemplo n.º 3
0
        private void PackBuildpackCache()
        {
            Directory.CreateDirectory(this.workspace.Cache);
            string tempFile = Path.ChangeExtension(this.workspace.StagedBuildpackCache, "tar");

            DEAUtilities.TarDirectory(this.workspace.Cache, tempFile);
            DEAUtilities.GzipFile(tempFile, this.workspace.StagedBuildpackCache);
            File.Delete(tempFile);
        }
Ejemplo n.º 4
0
        private void PackApp()
        {
            Logger.Debug("Staging task {0}: Packing droplet {1}", this.TaskId, this.workspace.StagedDroplet);
            string tempFile = Path.ChangeExtension(this.workspace.StagedDroplet, "tar");

            DEAUtilities.TarDirectory(this.workspace.StagedDir, tempFile);
            DEAUtilities.GzipFile(tempFile, this.workspace.StagedDroplet);
            File.Delete(tempFile);
        }
Ejemplo n.º 5
0
        private void Stage()
        {
            string appDir  = Path.Combine(this.workspace.StagedDir, "app");
            string logsDir = Path.Combine(this.workspace.StagedDir, "logs");
            string tmpDir  = Path.Combine(this.workspace.StagedDir, "tmp");

            Directory.CreateDirectory(appDir);
            Directory.CreateDirectory(logsDir);
            Directory.CreateDirectory(tmpDir);
            DEAUtilities.DirectoryCopy(this.workspace.UnstagedDir, appDir, true);
            Buildpack buildpack = null;

            if (this.Message.Properties.Buildpack != null)
            {
                Logger.Info("Staging task {0}: Downloading buildpack from {1}", this.TaskId, this.Message.Properties.Buildpack);
                Directory.CreateDirectory(Path.Combine(this.workspace.TempDir, "buildpacks"));
                string buildpackPath = Path.Combine(this.workspace.TempDir, "buildpacks", Path.GetFileName(new Uri(this.Message.Properties.Buildpack).LocalPath));
                string command       = string.Format("\"{0}\" clone --recursive {1} {2}", this.gitExe, this.Message.Properties.Buildpack, buildpackPath);
                int    success       = Command.ExecuteCommand(command);
                if (success != 0)
                {
                    throw new Exception("Failed to git clone buildpack");
                }
                buildpack = new Buildpack(buildpackPath, appDir, this.workspace.Cache, this.workspace.StagingLogPath);
                bool detected = buildpack.Detect(this.prison);
                if (!detected)
                {
                    throw new Exception("Buildpack does not support this application");
                }
            }
            else
            {
                Logger.Info("Staging task {0}: Detecting buildpack", this.TaskId);
                foreach (string dir in Directory.EnumerateDirectories(this.buildpacksDir))
                {
                    Buildpack bp      = new Buildpack(dir, appDir, this.workspace.Cache, this.workspace.StagingLogPath);
                    bool      success = bp.Detect(this.prison);
                    if (success)
                    {
                        buildpack = bp;
                        break;
                    }
                }

                if (buildpack == null)
                {
                    throw new Exception("Unable to detect a supported application type");
                }
                Logger.Info("Staging task {0}: Detected buildpack {1}", this.TaskId, buildpack.Name);
            }

            Logger.Info("Staging task {0}: Running compilation script", this.TaskId);
            buildpack.Compile(this.prison, this.stagingTimeout);

            Logger.Info("Staging task {0}: Saving buildpackInfo", this.TaskId);
            StagingInfo.SaveBuildpackInfo(Path.Combine(this.workspace.StagedDir, StagingWorkspace.StagingInfo), buildpack.Name, GetStartCommand(buildpack));
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ApplicationBits"/> class.
 /// </summary>
 public ApplicationBits()
 {
     // Setup the Zlib here to avoid errors when extracting for the first time under an impersonated user
     DEAUtilities.SetupZlib();
     this.Stacks = new HashSet <string>();
     if (!this.DisableDirCleanup)
     {
         TimerHelper.RecurringCall(CleanCacheIntervalMilliseconds, delegate { this.CleanCacheDirectory(); });
     }
 }
Ejemplo n.º 7
0
        public void PrepareStagingDirs()
        {
            string appDir  = Path.Combine(this.Workspace.StagedDir, "app");
            string logsDir = Path.Combine(this.Workspace.StagedDir, "logs");
            string tmpDir  = Path.Combine(this.Workspace.StagedDir, "tmp");

            Directory.CreateDirectory(appDir);
            Directory.CreateDirectory(logsDir);
            Directory.CreateDirectory(tmpDir);
            DEAUtilities.DirectoryCopy(this.Workspace.UnstagedDir, appDir, true);
        }
Ejemplo n.º 8
0
 private void UnpackBuildpackCache()
 {
     Directory.CreateDirectory(this.workspace.Cache);
     if (File.Exists(this.workspace.DownloadBuildpackCachePath))
     {
         Logger.Debug("Staging task {0}: Unpacking buildpack cache {1}", this.TaskId, this.workspace.DownloadBuildpackCachePath);
         DEAUtilities.UnzipFile(this.workspace.Cache, this.workspace.DownloadBuildpackCachePath);       // Unzip
         string tarFileName = Directory.GetFiles(this.workspace.DownloadBuildpackCachePath, "*.tar")[0];
         DEAUtilities.UnzipFile(this.workspace.Cache, Path.Combine(this.workspace.Cache, tarFileName)); // Untar
         File.Delete(Path.Combine(this.workspace.Cache, tarFileName));
     }
 }
Ejemplo n.º 9
0
        private void SaveBuildpackCache()
        {
            try
            {
                PackBuildpackCache();
            }
            catch
            {
                Logger.Debug("Staging task {0}: Cannot pack buildpack cache", this.TaskId);
                return;
            }
            File.Copy(this.workspace.StagedBuildpackCache, this.workspace.StagedBuildpackCachePath);
            Uri uri = new Uri(this.Message.BuildpackCacheUploadURI);

            Logger.Debug("Staging task {0}: Uploading buildpack cache {1} to {2}", this.TaskId, this.workspace.StagedBuildpackCachePath, this.Message.BuildpackCacheUploadURI);
            DEAUtilities.HttpUploadFile(this.Message.BuildpackCacheUploadURI, new FileInfo(this.workspace.StagedBuildpackCachePath), "upload[droplet]", "application/octet-stream", uri.UserInfo);
        }
Ejemplo n.º 10
0
        private void Cleanup()
        {
            if (this.prison.Created)
            {
                try
                {
                    Logger.Info("Destroying prison for staging instance {0}", this.TaskId);
                    this.prison.Destroy();
                }
                catch (Exception ex)
                {
                    Logger.Warning("Unable to cleanup application {0}. Exception: {1}", this.TaskId, ex.ToString());
                }
            }

            Logger.Debug("Cleaning up directory {0}", this.workspace.BaseDir);
            DEAUtilities.RemoveReadOnlyAttribute(this.workspace.BaseDir);
            Directory.Delete(this.workspace.BaseDir, true);
        }
Ejemplo n.º 11
0
 public void UnpackDroplet()
 {
     Directory.CreateDirectory(this.Workspace.UnstagedDir);
     if (File.Exists(this.Workspace.DownloadDropletPath))
     {
         DEAUtilities.UnzipFile(this.Workspace.UnstagedDir, this.Workspace.DownloadDropletPath);
     }
     else
     {
         throw new Exception(string.Format("Could not find file {0}", this.Workspace.DownloadDropletPath));
     }
     Directory.CreateDirectory(this.Workspace.Cache);
     if (File.Exists(this.Workspace.DownloadBuildpackCachePath))
     {
         Logger.Debug("Staging task {0}: Unpacking buildpack cache {1}", this.Properties.TaskId, this.Workspace.DownloadBuildpackCachePath);
         DEAUtilities.UnzipFile(this.Workspace.Cache, this.Workspace.DownloadBuildpackCachePath);       // Unzip
         string tarFileName = Directory.GetFiles(this.Workspace.DownloadBuildpackCachePath, "*.tar")[0];
         DEAUtilities.UnzipFile(this.Workspace.Cache, Path.Combine(this.Workspace.Cache, tarFileName)); // Untar
         File.Delete(Path.Combine(this.Workspace.Cache, tarFileName));
     }
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Prepares the app directory.
        /// </summary>
        /// <param name="bitsFile">The bits file.</param>
        /// <param name="bitsUri">The bits URI.</param>
        /// <param name="hash">The sha1.</param>
        /// <param name="tarZipFile">The TGZ file.</param>
        /// <param name="instance">The instance.</param>
        public void PrepareAppDirectory(string bitsFile, string bitsUri, string hash, string tarZipFile, DropletInstance instance)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            // What we do here, in order of preference..
            // 1. Check our own staged directory.
            // 2. Check shared directory from CloudController that could be mounted (bits_file)
            // 3. Pull from http if needed.
            string instanceDir = instance.Properties.Directory;

            lock (this.stagerLock)
            {
                // check before downloading
                if (instance.Properties.StopProcessed)
                {
                    return;
                }

                if (File.Exists(tarZipFile))
                {
                    Logger.Debug(Strings.FoundStagedBitsInLocalCache);
                }
                else
                {
                    // If we have a shared volume from the CloudController we can see the bits directly, just link into our staged version.
                    DateTime start = DateTime.Now;
                    if (File.Exists(bitsFile))
                    {
                        Logger.Debug(Strings.SharingCloudControllerStagingDirectory);
                        File.Copy(bitsFile, tarZipFile);
                        Logger.Debug(Strings.TookXSecondsToCopyFromShared, DateTime.Now - start);
                    }
                    else
                    {
                        Uri downloadUri = new Uri(bitsUri);

                        Logger.Debug(Strings.Needtodownloadappbitsfrom, downloadUri);

                        this.DownloadAppBits(downloadUri, hash, tarZipFile);

                        Logger.Debug(Strings.TookXSecondsToDownloadAndWrite, DateTime.Now - start);
                    }
                }

                // check before extracting
                if (instance.Properties.StopProcessed)
                {
                    return;
                }

                DateTime startStageing = DateTime.Now;

                // Explode the app into its directory and optionally bind its local runtime.
                Directory.CreateDirectory(instance.Properties.Directory);

                DirectoryInfo     deploymentDirInfo     = new DirectoryInfo(instance.Properties.Directory);
                DirectorySecurity deploymentDirSecurity = deploymentDirInfo.GetAccessControl();

                // Owner is important to account for disk quota
                deploymentDirSecurity.SetOwner(new NTAccount(instance.Properties.WindowsUserName));
                deploymentDirSecurity.SetAccessRule(
                    new FileSystemAccessRule(
                        instance.Properties.WindowsUserName,
                        FileSystemRights.Write | FileSystemRights.Read | FileSystemRights.Delete | FileSystemRights.Modify | FileSystemRights.FullControl,
                        InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
                        PropagationFlags.None | PropagationFlags.InheritOnly,
                        AccessControlType.Allow));

                // Taking ownership of a file has to be executed with restore privilege elevated privilages
                using (new ProcessPrivileges.PrivilegeEnabler(Process.GetCurrentProcess(), ProcessPrivileges.Privilege.Restore))
                {
                    deploymentDirInfo.SetAccessControl(deploymentDirSecurity);
                }

                // Impersonate user to cascade the owernship to every file
                // Neccessary for windows disk quota
                using (new UserImpersonator(instance.Properties.WindowsUserName, ".", instance.Properties.WindowsPassword, true))
                {
                    DEAUtilities.UnzipFile(instanceDir, tarZipFile);                             // Unzip
                    string tarFileName = Directory.GetFiles(instanceDir, "*.tar")[0];
                    DEAUtilities.UnzipFile(instanceDir, Path.Combine(instanceDir, tarFileName)); // Untar
                    File.Delete(Path.Combine(instanceDir, tarFileName));
                }

                Logger.Debug(Strings.TookXSecondsToStageTheApp, DateTime.Now - startStageing);
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Stages the app directory.
        /// </summary>
        /// <param name="bitsFile">The bits file.</param>
        /// <param name="bitsUri">The bits URI.</param>
        /// <param name="hash">The sha1.</param>
        /// <param name="tarZipFile">The TGZ file.</param>
        /// <param name="instance">The instance.</param>
        public void StageAppDirectory(string bitsFile, Uri bitsUri, string hash, string tarZipFile, DropletInstance instance)
        {
            if (instance == null)
            {
                throw new ArgumentNullException("instance");
            }

            // What we do here, in order of preference..
            // 1. Check our own staged directory.
            // 2. Check shared directory from CloudController that could be mounted (bits_file)
            // 3. Pull from http if needed.
            string instanceDir = instance.Properties.Directory;

            lock (this.stagerLock)
            {
                // check before downloading
                if (instance.Properties.StopProcessed)
                {
                    return;
                }

                if (File.Exists(tarZipFile))
                {
                    Logger.Debug(Strings.FoundStagedBitsInLocalCache);
                }
                else
                {
                    // If we have a shared volume from the CloudController we can see the bits directly, just link into our staged version.
                    DateTime start = DateTime.Now;
                    if (!this.ForceHttpFileSharing && File.Exists(bitsFile))
                    {
                        Logger.Debug(Strings.SharingCloudControllerStagingDirectory);
                        File.Copy(bitsFile, tarZipFile);
                        Logger.Debug(Strings.TookXSecondsToCopyFromShared, DateTime.Now - start);
                    }
                    else
                    {
                        Logger.Debug(Strings.Needtodownloadappbitsfrom, bitsUri);

                        this.DownloadAppBits(bitsUri, hash, tarZipFile);

                        Logger.Debug(Strings.TookXSecondsToDownloadAndWrite, DateTime.Now - start);
                    }
                }

                // check before extracting
                if (instance.Properties.StopProcessed)
                {
                    return;
                }

                DateTime startStageing = DateTime.Now;

                // Explode the app into its directory and optionally bind its local runtime.
                Directory.CreateDirectory(instanceDir);

                string tarFileName = Path.GetFileName(tarZipFile);
                tarFileName = Path.ChangeExtension(tarFileName, ".tar");

                DEAUtilities.UnzipFile(instanceDir, tarZipFile);                             // Unzip
                DEAUtilities.UnzipFile(instanceDir, Path.Combine(instanceDir, tarFileName)); // Untar
                File.Delete(Path.Combine(instanceDir, tarFileName));

                Logger.Debug(Strings.TookXSecondsToStageTheApp, DateTime.Now - startStageing);
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Setups the runtimes.
        /// </summary>
        public void SetupRuntimes()
        {
            if (this.Runtimes == null || this.Runtimes.Count == 0)
            {
                Logger.Fatal(Strings.CannotDetermineApplicationRuntimes);
                throw new InvalidOperationException(Strings.CannotDetermineApplicationRuntimes);
            }

            Logger.Info(Strings.Checkingruntimes);

            foreach (KeyValuePair <string, DeaRuntime> kvp in this.Runtimes)
            {
                string     name    = kvp.Key;
                DeaRuntime runtime = kvp.Value;

                // Only enable when we succeed
                runtime.Enabled = false;

                // Check that we can get a version from the executable
                string version_flag = string.IsNullOrEmpty(runtime.VersionArgument) ? "-v" : runtime.VersionArgument;

                string expanded_exec = DEAUtilities.RunCommandAndGetOutputAndErrors("where", runtime.Executable).Trim();

                expanded_exec = expanded_exec.Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries)[0];

                if (!File.Exists(expanded_exec))
                {
                    Logger.Info(Strings.FailedExecutableNot, name, runtime.Executable, Directory.GetCurrentDirectory(), expanded_exec);
                    continue;
                }

                // java prints to stderr, so munch them both..
                string version_check = DEAUtilities.RunCommandAndGetOutputAndErrors(
                    expanded_exec,
                    string.Format(CultureInfo.InvariantCulture, "{0} {1}", expanded_exec, version_flag)).Trim();

                runtime.Executable = expanded_exec;

                if (string.IsNullOrEmpty(runtime.Version))
                {
                    continue;
                }

                // Check the version for a match
                if (new Regex(runtime.Version).IsMatch(version_check))
                {
                    // Additional checks should return true
                    if (!string.IsNullOrEmpty(runtime.AdditionalChecks))
                    {
                        string additional_check = DEAUtilities.RunCommandAndGetOutputAndErrors(
                            runtime.Executable,
                            string.Format(CultureInfo.InvariantCulture, "{0}", runtime.AdditionalChecks));
                        if (!new Regex("true").IsMatch(additional_check))
                        {
                            Logger.Info(Strings.FailedAdditionalChecks, name);
                        }
                    }

                    runtime.Enabled = true;
                    Logger.Info(Strings.RuntimeOk, name);
                }
                else
                {
                    Logger.Info(Strings.FailedVersionMismatch, name, version_check);
                }
            }
        }
Ejemplo n.º 15
0
 private void UnpackApp()
 {
     Directory.CreateDirectory(this.workspace.UnstagedDir);
     DEAUtilities.UnzipFile(this.workspace.UnstagedDir, this.workspace.DownloadDropletPath);
 }
Ejemplo n.º 16
0
 public void Cleanup()
 {
     DEAUtilities.RemoveReadOnlyAttribute(this.Workspace.BaseDir);
     Directory.Delete(this.Workspace.BaseDir, true);
 }