示例#1
0
        public List <string> AllDeploymentsByActivation()
        {
            List <string> deployments = AllDeployments();
            int           count       = 0;

            deployments.Sort();
            deployments.OrderBy(d =>
            {
                DeploymentMetadata metadata = DeploymentMetadataFor(new DirectoryInfo(d).Name);
                float latestActivation      = 0;
                if (metadata.Activations.Count > 0)
                {
                    latestActivation = metadata.Activations.Last();
                }
                count++;
                if (latestActivation != 0)
                {
                    return(latestActivation);
                }
                else
                {
                    return(float.MaxValue - count);
                }
            });
            return(deployments);
        }
示例#2
0
        public string PostConfigure(string cartName, string templateGitUrl = null)
        {
            Logger.Debug("Running PostConfigure for '{0}' with cart '{1}' and git url '{2}'", this.Uuid, cartName, templateGitUrl);

            StringBuilder output    = new StringBuilder();
            Manifest      cartridge = this.Cartridge.GetCartridge(cartName);

            bool performInitialBuild = !Git.EmptyCloneSpec(templateGitUrl) && (cartridge.InstallBuildRequired || !string.IsNullOrEmpty(templateGitUrl)) && cartridge.Buildable;

            if (performInitialBuild)
            {
                Logger.Info("Performing initial build");
                try
                {
                    RunProcessInContainerContext(this.ContainerDir, "gear prereceive --init");
                    RunProcessInContainerContext(this.ContainerDir, "gear postreceive --init");
                }
                catch (Exception ex)
                {
                    // TODO: vladi: implement exception handling for initial build
                }
            }
            else if (cartridge.Deployable)
            {
                string             deploymentDatetime = LatestDeploymentDateTime();
                DeploymentMetadata deploymentMetadata = DeploymentMetadataFor(deploymentDatetime);
                if (deploymentMetadata.Activations.Count == 0)
                {
                    Prepare(new RubyHash()
                    {
                        { "deployment_datetime", deploymentDatetime }
                    });
                    deploymentMetadata.Load();
                    ApplicationRepository applicationRepository = new ApplicationRepository(this);
                    string gitRef         = "master";
                    string gitSha1        = applicationRepository.GetSha1(gitRef);
                    string deploymentsDir = Path.Combine(this.ContainerDir, "app-deployments");
                    SetRWPermissions(deploymentsDir);
                    // TODO: reset_permission_R(deployments_dir)

                    deploymentMetadata.RecordActivation();
                    deploymentMetadata.Save();

                    UpdateCurrentDeploymentDateTimeSymlink(deploymentDatetime);

                    FixHomeDir();
                }
            }

            output.AppendLine(this.Cartridge.PostConfigure(cartName));

            if (performInitialBuild)
            {
                // TODO: grep build log
            }

            return(output.ToString());
        }
示例#3
0
        public string Prepare(RubyHash options = null)
        {
            if (options == null)
            {
                options = new RubyHash();
            }
            StringBuilder output = new StringBuilder();

            output.AppendLine("Preparing build for deployment");
            if (!options.ContainsKey("deployment_datetime"))
            {
                throw new ArgumentException("deployment_datetime is required");
            }
            string deploymentDatetime       = options["deployment_datetime"].ToString();
            Dictionary <string, string> env = Environ.ForGear(this.ContainerDir);

            // TODO clean runtime dirs, extract archive

            this.Cartridge.DoActionHook("prepare", env, options);
            string deploymentId = CalculateDeploymentId();

            LinkDeploymentId(deploymentDatetime, deploymentId);

            try
            {
                SyncRuntimeRepoDirToDeployment(deploymentDatetime);
                SyncRuntimeDependenciesDirToDeployment(deploymentDatetime);
                SyncRuntimeBuildDependenciesDirToDeployment(deploymentDatetime);

                DeploymentMetadata deploymentMetadata = DeploymentMetadataFor(deploymentDatetime);
                deploymentMetadata.Id       = deploymentId;
                deploymentMetadata.Checksum = CalculateDeploymentChecksum(deploymentId);
                deploymentMetadata.Save();

                options["deployment_id"] = deploymentId;
                output.AppendLine("Deployment id is " + deploymentId);
            }
            catch (Exception e)
            {
                Logger.Error("Error preparing deployment. Options: {0} - {1} - {2}", JsonConvert.SerializeObject(options), e.Message, e.StackTrace);
                output.AppendLine("Error preparing deployment " + deploymentId);
                UnlinkDeploymentId(deploymentId);
            }

            return(output.ToString());
        }
示例#4
0
        public List <RubyHash> CalculateDeployments()
        {
            List <RubyHash> deployments = new List <RubyHash>();

            foreach (string d in AllDeployments())
            {
                string             deploymentDateTime = new DirectoryInfo(d).Name;
                DeploymentMetadata deploymentMetadata = DeploymentMetadataFor(deploymentDateTime);
                deployments.Add(new RubyHash()
                {
                    { "id", deploymentMetadata.Id },
                    { "ref", deploymentMetadata.GitRef },
                    { "sha1", deploymentMetadata.GitSha },
                    { "force_clean_build", deploymentMetadata.ForceCleanBuild },
                    { "hot_deploy", deploymentMetadata.HotDeploy },
                    { "created_at", RubyCompatibility.DateTimeToEpochSeconds(DateTime.Parse(deploymentDateTime)) },
                    { "activations", deploymentMetadata.Activations }
                });
            }

            return(deployments);
        }
示例#5
0
        private RubyHash ActivateLocalGear(dynamic options)
        {
            string deploymentId = options["deployment_id"];

            Logger.Debug("Activating local gear with deployment id {0}", deploymentId);

            RubyHash result = new RubyHash();

            result["status"]        = RESULT_FAILURE;
            result["gear_uuid"]     = this.Uuid;
            result["deployment_id"] = deploymentId;
            result["messages"]      = new List <string>();
            result["errors"]        = new List <string>();

            if (!DeploymentExists(deploymentId))
            {
                Logger.Warning("No deployment with id {0} found on gear", deploymentId);
                result["errors"].Add(string.Format("No deployment with id {0} found on gear", deploymentId));
                return(result);
            }

            try
            {
                string deploymentDateTime = GetDeploymentDateTimeForDeploymentId(deploymentId);
                string deploymentDir      = Path.Combine(this.ContainerDir, "app-deployments", deploymentDateTime);

                Dictionary <string, string> gearEnv = Environ.ForGear(this.ContainerDir);

                string output = string.Empty;

                Logger.Debug("Current deployment state for deployment {0} is {1}", deploymentId, this.State.Value());

                if (Runtime.State.STARTED.EqualsString(State.Value()))
                {
                    options["exclude_web_proxy"] = true;
                    output = StopGear(options);
                    result["messages"].Add(output);
                }

                SyncDeploymentRepoDirToRuntime(deploymentDateTime);
                SyncDeploymentDependenciesDirToRuntime(deploymentDateTime);
                SyncDeploymentBuildDependenciesDirToRuntime(deploymentDateTime);

                UpdateCurrentDeploymentDateTimeSymlink(deploymentDateTime);

                Manifest primaryCartridge = this.Cartridge.GetPrimaryCartridge();

                this.Cartridge.DoControl("update-configuration", primaryCartridge);

                result["messages"].Add("Starting application " + ApplicationName);

                Dictionary <string, object> opts = new Dictionary <string, object>();
                opts["secondary_only"] = true;
                opts["user_initiated"] = true;
                opts["hot_deploy"]     = options["hot_deploy"];

                output = StartGear(opts);
                result["messages"].Add(output);

                this.State.Value(Runtime.State.DEPLOYING);

                opts = new Dictionary <string, object>();
                opts["pre_action_hooks_enabled"] = false;
                opts["prefix_action_hooks"]      = false;
                output = this.Cartridge.DoControl("deploy", primaryCartridge, opts);
                result["messages"].Add(output);

                opts = new Dictionary <string, object>();
                opts["primary_only"]   = true;
                opts["user_initiated"] = true;
                opts["hot_deploy"]     = options["hot_deploy"];
                output = StartGear(opts);
                result["messages"].Add(output);

                opts = new Dictionary <string, object>();
                opts["pre_action_hooks_enabled"] = false;
                opts["prefix_action_hooks"]      = false;
                output = this.Cartridge.DoControl("post-deploy", primaryCartridge, opts);
                result["messages"].Add(output);

                if (options.ContainsKey("post_install"))
                {
                    string primaryCartEnvDir = Path.Combine(this.ContainerDir, primaryCartridge.Dir, "env");
                    Dictionary <string, string> primaryCartEnv = Environ.Load(primaryCartEnvDir);
                    string ident = (from kvp in primaryCartEnv
                                    where Regex.Match(kvp.Key, "^OPENSHIFT_.*_IDENT").Success
                                    select kvp.Value).FirstOrDefault();
                    string version = Manifest.ParseIdent(ident)[2];
                    this.Cartridge.PostInstall(primaryCartridge, version);
                }

                DeploymentMetadata deploymentMetadata = DeploymentMetadataFor(deploymentDateTime);
                deploymentMetadata.RecordActivation();
                deploymentMetadata.Save();

                if (options.ContainsKey("report_deployments") && gearEnv["OPENSHIFT_APP_DNS"] == gearEnv["OPENSHIFT_GEAR_DNS"])
                {
                    ReportDeployments(gearEnv);
                }

                result["status"] = RESULT_SUCCESS;
            }
            catch (Exception e)
            {
                result["status"] = RESULT_FAILURE;
                result["errors"].Add(string.Format("Error activating gear: {0}", e.ToString()));
            }

            return(result);
        }
示例#6
0
        public string Activate(RubyHash options = null)
        {
            Logger.Debug("Activating gear {0}", this.Uuid);

            if (options == null)
            {
                options = new RubyHash();
            }

            bool useOutput = options.ContainsKey("out") && options["out"];

            StringBuilder output = new StringBuilder();
            dynamic       result = new Dictionary <string, object>();

            if (useOutput)
            {
                output.Append("Activating deployment");
            }

            if (!options.ContainsKey("deployment_id"))
            {
                throw new Exception("deployment_id must be supplied");
            }
            string             deploymentId       = options["deployment_id"];
            string             deploymentDateTime = GetDeploymentDateTimeForDeploymentId(deploymentId);
            DeploymentMetadata deploymentMetadata = DeploymentMetadataFor(deploymentDateTime);

            options["hot_deploy"] = deploymentMetadata.HotDeploy;
            if (options.ContainsKey("post_install") || options.ContainsKey("restore"))
            {
                options["hot_deploy"] = false;
            }

            List <RubyHash> parallelResults = WithGearRotation(options, (GearRotationCallback) delegate(object targetGear, Dictionary <string, string> localGearEnv, RubyHash opts)
            {
                string targetGearUuid;
                if (targetGear is string)
                {
                    targetGearUuid = targetGear.ToString();
                }
                else
                {
                    targetGearUuid = ((Model.GearRegistry.Entry)targetGear).Uuid;
                }
                if (targetGearUuid == this.Uuid)
                {
                    return(ActivateLocalGear(options));
                }
                else
                {
                    return(ActivateRemoteGear((GearRegistry.Entry)targetGear, localGearEnv, options));
                }
            });

            List <string> activatedGearUuids = new List <string>();

            if ((options.ContainsKey("all") && options["all"]) || (options.ContainsKey("gears") && options["gears"]))
            {
                result["status"]       = RESULT_SUCCESS;
                result["gear_results"] = new Dictionary <string, object>();

                foreach (RubyHash gearResult in parallelResults)
                {
                    string gearUuid = gearResult["gear_uuid"];
                    activatedGearUuids.Add(gearUuid);

                    result["gear_results"][gearUuid] = gearResult;

                    if (gearResult["status"] != RESULT_SUCCESS)
                    {
                        result["status"] = RESULT_FAILURE;
                    }
                }
            }
            else
            {
                activatedGearUuids.Add(this.Uuid);
                result = parallelResults[0];
            }

            output.Append(JsonConvert.SerializeObject(result));

            return(output.ToString());
        }
示例#7
0
        private string Build(RubyHash options)
        {
            this.State.Value(Runtime.State.BUILDING);
            string             deploymentDateTime = options["deployment_datetime"] != null ? options["deployment_datetime"] : LatestDeploymentDateTime();
            DeploymentMetadata deploymentMetadata = DeploymentMetadataFor(deploymentDateTime);

            if (!options.ContainsKey("deployment_datetime"))
            {
                // this will execute if coming from a CI builder, since it doesn't
                // specify :deployment_datetime in the options hash
                throw new NotImplementedException();
            }

            StringBuilder buffer = new StringBuilder();

            if (deploymentMetadata.ForceCleanBuild)
            {
                buffer.AppendLine("Force clean build enabled - cleaning dependencies");

                CleanRuntimeDirs(new RubyHash()
                {
                    { "dependencies", true }, { "build_dependencies", true }
                });

                this.Cartridge.EachCartridge(delegate(Manifest cartridge) {
                    this.Cartridge.CreateDependencyDirectories(cartridge);
                });
            }

            buffer.AppendLine(string.Format("Building git ref {0}, commit {1}", deploymentMetadata.GitRef, deploymentMetadata.GitSha));

            Dictionary <string, string> env = Environ.ForGear(this.ContainerDir);
            int deploymentsToKeep           = DeploymentsToKeep(env);

            try
            {
                Manifest primaryCartridge = this.Cartridge.GetPrimaryCartridge();
                buffer.AppendLine(this.Cartridge.DoControl("update-configuration", primaryCartridge, new RubyHash()
                {
                    { "pre_action_hooks_enabled", false }, { "post_action_hooks_enabled", false }
                }));
                buffer.AppendLine(this.Cartridge.DoControl("pre-build", primaryCartridge, new RubyHash()
                {
                    { "pre_action_hooks_enabled", false }, { "post_action_hooks_enabled", false }
                }));
                buffer.AppendLine(this.Cartridge.DoControl("build", primaryCartridge, new RubyHash()
                {
                    { "pre_action_hooks_enabled", false }, { "post_action_hooks_enabled", false }
                }));
            }
            catch (Exception ex)
            {
                buffer.AppendLine("Encountered a failure during build: " + ex.ToString());
                if (deploymentsToKeep > 1)
                {
                    buffer.AppendLine("Restarting application");
                    buffer.AppendLine(StartGear(new RubyHash()
                    {
                        { "user_initiated", true }, { "hot_deploy", deploymentMetadata.HotDeploy }
                    }));
                }
                throw ex;
            }

            return(buffer.ToString());
        }