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); }
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()); }
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()); }
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); }
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); }
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()); }
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()); }