protected PSArgument[] CreateDeploymentCreateParameters() { string serviceName = string.Empty; DeploymentSlot deploymentSlot = new DeploymentSlot(); DeploymentCreateParameters parameters = new DeploymentCreateParameters(); return(ConvertFromObjectsToArguments(new string[] { "ServiceName", "DeploymentSlot", "Parameters" }, new object[] { serviceName, deploymentSlot, parameters })); }
protected void ExecuteDeploymentCreateMethod(object[] invokeMethodInputParameters) { string serviceName = (string)ParseParameter(invokeMethodInputParameters[0]); DeploymentSlot deploymentSlot = (DeploymentSlot)ParseParameter(invokeMethodInputParameters[1]); DeploymentCreateParameters parameters = (DeploymentCreateParameters)ParseParameter(invokeMethodInputParameters[2]); var result = DeploymentClient.Create(serviceName, deploymentSlot, parameters); WriteObject(result); }
private void CreateDeployment(string serviceName, DeploymentSlot slot, DeploymentCreateParameters createParameters) { var service = Services.First(s => s.Name == serviceName); service.AddDeployment(d => { d.Name = createParameters.Name; d.Slot = slot; }); }
/// <summary> /// Deploys a service. /// </summary> /// <remarks> /// Note that the service specification must already have been created. /// </remarks> /// <param name="serviceName">Name of the service.</param> /// <param name="deploymentName">Name of this deployment.</param> /// <param name="deploymentSlot">Environment for this deployment (e.g. Production or Staging).</param> /// <param name="configuration">Deployment configuration information (i.e. .cscfg file contents).</param> /// <param name="packageBlob">URI for blob containing package (i.e. .cspkg) file contents.</param> /// <param name="startImmediately">Whether to start the deployment immediately after it is created.</param> public void DeployService( string serviceName, string deploymentName, DeploymentSlot deploymentSlot, string configuration, Uri packageBlob, bool startImmediately = true) { // Required: Configuration, Label, Name, PackageUri. // Optional: ExtendedProperties, ExtensionConfiguration, StartDeployment, TreatWarningsAsError. DeploymentCreateParameters parameters = new DeploymentCreateParameters(); parameters.Configuration = configuration; // Contents of .cscfg file. parameters.Label = serviceName; // Name for hosted service. Does not need to match serviceName. parameters.Name = deploymentName; // Unique name for this particular deployment. parameters.PackageUri = packageBlob; // URI for blob containing .cspkg file. parameters.StartDeployment = startImmediately; // Whether to start the deployment immediately after it is created. this.computeManager.Deployments.Create(serviceName, deploymentSlot, parameters); }
private void CreateDeployment(PublishContext context) { var deploymentParams = new DeploymentCreateParameters { PackageUri = UploadPackage(context), Configuration = General.GetConfiguration(context.ConfigPath), Label = context.ServiceName, Name = context.DeploymentName, StartDeployment = true }; WriteVerboseWithTimestamp(Resources.PublishStartingMessage); ServiceCertificateListResponse uploadedCertificates = ComputeClient.ServiceCertificates.List(context.ServiceName); AddCertificates(uploadedCertificates, context); ComputeClient.Deployments.Create(context.ServiceName, GetSlot(context.ServiceSettings.Slot), deploymentParams); }
/// <summary> /// Create hosted service deployment /// </summary> /// <param name="hostedServiceName"></param> /// <param name="input"></param> /// <param name="deploymentSlot"></param> /// <returns></returns> public DeploymentGetResponse CreateDeployment(string hostedServiceName, DeploymentCreateParameters input, DeploymentSlot deploymentSlot = DeploymentSlot.Production) { TestEasyLog.Instance.Info(string.Format("Creating Deployment... Name: '{0}', Label: '{1}'", input.Name, input.Label)); ComputeManagementClient.Deployments.CreateAsync(hostedServiceName, deploymentSlot, input, new CancellationToken()).Wait(); var result = GetDeployment(hostedServiceName, input.Name); Dependencies.TestResourcesCollector.Remember( AzureResourceType.Deployment, result.Name, new DeploymentInfo { Deployment = result, HostedService = hostedServiceName }); return(result); }
public static async Task DeployAsync(string source, SubscriptionListOperationResponse.Subscription subscription, HostedServiceListResponse.HostedService service, StorageAccount storage, DeploymentSlot slot, UpgradePreference upgradePreference, string pathToCspkg, string pathToCscfg, string pathToDiagExtensionConfig, StorageAccount diagStorage, string deploymentLabel, bool cleanupUnusedExtensions, bool forceWhenUpgrading) { Logger.InfoFormat("[" + source + "] " + "Preparing for deployment of {0}...", service.ServiceName); var credentials = GetCredentials(source, subscription); var computeClient = new ComputeManagementClient(credentials); var storageClient = new StorageManagementClient(credentials); // Load csdef var csCfg = File.ReadAllText(pathToCscfg); // Load diag config var diagConfig = pathToDiagExtensionConfig != null?File.ReadAllText(pathToDiagExtensionConfig) : null; // Upgrade cspkg to storage Logger.InfoFormat("[" + source + "] " + "Fetching key for storage account {0}...", storage.Name); var keys = await storageClient.StorageAccounts.GetKeysAsync(storage.Name); var csa = new CloudStorageAccount(new StorageCredentials(storage.Name, keys.PrimaryKey), true); var blobClient = csa.CreateCloudBlobClient(); var containerRef = blobClient.GetContainerReference("acd-deployments"); if (!await containerRef.ExistsAsync()) { Logger.InfoFormat("[" + source + "] " + "Creating container {0}...", containerRef.Name); await containerRef.CreateIfNotExistsAsync(); } var filename = service.ServiceName + "-" + slot.ToString() + ".cspkg"; var blobRef = containerRef.GetBlockBlobReference(filename); Logger.InfoFormat("[" + source + "] " + "Uploading package to {0}...", blobRef.Uri); await blobRef.UploadFromFileAsync(pathToCspkg, FileMode.Open); // Private diagnostics config string diagStorageName = null, diagStorageKey = null; if (diagStorage == null) { Logger.InfoFormat("[" + source + "] " + "Using storage account credentials from .cscfg for diagnostics..."); Regex regex = new Regex("Diagnostics.ConnectionString.*?DefaultEndpointsProtocol.*?AccountName=(.+?);.*?AccountKey=([a-zA-Z0-9/+=]+)", RegexOptions.Singleline); Match m = regex.Match(csCfg); if (m.Success) { diagStorageName = m.Groups[1].Value; diagStorageKey = m.Groups[2].Value; Logger.InfoFormat("[" + source + "] " + "Extracted storage account {0} from .cscfg for diagnostics...", diagStorageName); } else { throw new ApplicationException("Couldn't extract Diagnostics ConnectionString from .cscfg"); } } else { Logger.InfoFormat("[" + source + "] " + "Using storage account {0} for diagnostics...", diagStorage.Name); if (storage.Name == diagStorage.Name) { diagStorageName = diagStorage.Name; diagStorageKey = keys.PrimaryKey; } else { Logger.InfoFormat("[" + source + "] " + "Fetching keys for storage account {0}...", diagStorage.Name); var diagKeys = await storageClient.StorageAccounts.GetKeysAsync(diagStorage.Name); diagStorageName = diagStorage.Name; diagStorageKey = diagKeys.PrimaryKey; } } var privateDiagConfig = string.Format(@"<PrivateConfig xmlns=""http://schemas.microsoft.com/ServiceHosting/2010/10/DiagnosticsConfiguration""> <StorageAccount name=""{0}"" key=""{1}"" /> </PrivateConfig>", diagStorageName, diagStorageKey); // Get diagnostics extension template Logger.InfoFormat("[" + source + "] " + "Retrieving available extensions..."); var availableExtensions = await computeClient.HostedServices.ListAvailableExtensionsAsync(); var availableDiagnosticsExtension = availableExtensions.Where(d => d.Type == "PaaSDiagnostics").First(); // Cleanup of existing extensions if (cleanupUnusedExtensions) { await CleanupExistingExtensions(source, subscription, service, computeClient, availableDiagnosticsExtension); } else { Logger.InfoFormat("[" + source + "] " + "Skip cleaning unused extensions as configured"); } // Extensions config var extensionConfiguration = new ExtensionConfiguration(); // Create the extension with new configuration if (diagConfig != null) { var diagnosticsId = "acd-diagnostics-" + Guid.NewGuid().ToString("N"); Logger.InfoFormat("[" + source + "] " + "Adding new diagnostics extension {0}...", diagnosticsId); var createExtensionOperation = await computeClient.HostedServices.BeginAddingExtensionAsync(service.ServiceName, new HostedServiceAddExtensionParameters() { ProviderNamespace = availableDiagnosticsExtension.ProviderNameSpace, Type = availableDiagnosticsExtension.Type, Id = diagnosticsId, Version = availableDiagnosticsExtension.Version, PublicConfiguration = diagConfig, PrivateConfiguration = privateDiagConfig }); await WaitForOperationAsync(source, subscription, computeClient, createExtensionOperation.RequestId); // Extension configuration extensionConfiguration.AllRoles.Add(new ExtensionConfiguration.Extension { Id = diagnosticsId }); } // Create deployment parameters var deployParams = new DeploymentCreateParameters { StartDeployment = true, Name = Guid.NewGuid().ToString("N"), Configuration = csCfg, PackageUri = blobRef.Uri, Label = deploymentLabel ?? DateTime.UtcNow.ToString("u") + " " + Environment.UserName, ExtensionConfiguration = extensionConfiguration }; var upgradeParams = new DeploymentUpgradeParameters { Configuration = csCfg, PackageUri = blobRef.Uri, Label = deploymentLabel ?? DateTime.UtcNow.ToString("u") + " " + Environment.UserName, ExtensionConfiguration = extensionConfiguration, Mode = upgradePreference == UpgradePreference.UpgradeSimultaneously ? DeploymentUpgradeMode.Simultaneous : DeploymentUpgradeMode.Auto, Force = forceWhenUpgrading }; Logger.InfoFormat("[" + source + "] " + "Label for deployment: {0}", deployParams.Label); switch (upgradePreference) { case UpgradePreference.DeleteAndCreateDeploymentInitiallyStopped: case UpgradePreference.DeleteAndCreateDeployment: { // In the case of initially stopped, set StartDeployment to false (we default to 'true' above) if (upgradePreference == UpgradePreference.DeleteAndCreateDeploymentInitiallyStopped) { deployParams.StartDeployment = false; } // Is there a deployment in this slot? Logger.InfoFormat("[" + source + "] " + "Fetching detailed service information..."); var detailedService = await computeClient.HostedServices.GetDetailedAsync(service.ServiceName); var currentDeployment = detailedService.Deployments.Where(s => s.DeploymentSlot == slot).FirstOrDefault(); if (currentDeployment != null) { // Yes, there is. Save the deployment name for the recreate. This is to increase compatibility with // cloud service monitoring tools. deployParams.Name = currentDeployment.Name; // Delete it. Logger.InfoFormat("[" + source + "] " + "Deployment in {0} slot exists, deleting...", slot); var deleteOperation = await computeClient.Deployments.BeginDeletingBySlotAsync(service.ServiceName, slot); await WaitForOperationAsync(source, subscription, computeClient, deleteOperation.RequestId); } // Create a new deployment in this slot Logger.InfoFormat("[" + source + "] " + "Creating deployment in {0} slot...", slot); var createOperation = await computeClient.Deployments.BeginCreatingAsync(service.ServiceName, slot, deployParams); await WaitForOperationAsync(source, subscription, computeClient, createOperation.RequestId); } break; case UpgradePreference.UpgradeWithUpdateDomains: case UpgradePreference.UpgradeSimultaneously: { // Is there a deployment in this slot? Logger.InfoFormat("[" + source + "] " + "Fetching detailed service information..."); var detailedService = await computeClient.HostedServices.GetDetailedAsync(service.ServiceName); var currentDeployment = detailedService.Deployments.Where(s => s.DeploymentSlot == slot).FirstOrDefault(); if (currentDeployment != null) { // Yes, there is. Upgrade it. Logger.InfoFormat("[" + source + "] " + "Deployment in {0} slot exists, upgrading...", slot); var upgradeOperation = await computeClient.Deployments.BeginUpgradingBySlotAsync(service.ServiceName, slot, upgradeParams); await WaitForOperationAsync(source, subscription, computeClient, upgradeOperation.RequestId); } else { // No, there isn't. Create. Logger.InfoFormat("[" + source + "] " + "No deployment in {0} slot yet, creating...", slot); var createOperation = await computeClient.Deployments.BeginCreatingAsync(service.ServiceName, slot, deployParams); await WaitForOperationAsync(source, subscription, computeClient, createOperation.RequestId); } } break; } Logger.InfoFormat("[" + source + "] " + "Deployment succesful"); }
public virtual void NewPaaSDeploymentProcess() { bool removePackage = false; AssertNoPersistenVmRoleExistsInDeployment(DeploymentSlotType.Production); AssertNoPersistenVmRoleExistsInDeployment(DeploymentSlotType.Staging); var storageName = CurrentSubscription.CurrentStorageAccountName; Uri packageUrl; if (this.Package.StartsWith(Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase) || this.Package.StartsWith(Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase)) { packageUrl = new Uri(this.Package); } else { var progress = new ProgressRecord(0, Resources.WaitForUploadingPackage, Resources.UploadingPackage); WriteProgress(progress); removePackage = true; packageUrl = this.RetryCall(s => AzureBlob.UploadPackageToBlob( this.StorageClient, storageName, this.Package, null)); } ExtensionConfiguration extConfig = null; if (ExtensionConfiguration != null) { string errorConfigInput = null; if (!ExtensionManager.Validate(ExtensionConfiguration, out errorConfigInput)) { throw new Exception(string.Format(Resources.ServiceExtensionCannotApplyExtensionsInSameType, errorConfigInput)); } foreach (ExtensionConfigurationInput context in ExtensionConfiguration) { if (context != null && context.X509Certificate != null) { ExecuteClientActionNewSM( null, string.Format(Resources.ServiceExtensionUploadingCertificate, CommandRuntime, context.X509Certificate.Thumbprint), () => this.ComputeClient.ServiceCertificates.Create(this.ServiceName, CertUtilsNewSM.Create(context.X509Certificate))); } } var slotType = (DeploymentSlot)Enum.Parse(typeof(DeploymentSlot), this.Slot, true); DeploymentGetResponse d = null; InvokeInOperationContext(() => { try { d = this.ComputeClient.Deployments.GetBySlot(this.ServiceName, slotType); } catch (CloudException ex) { if (ex.Response.StatusCode != HttpStatusCode.NotFound && IsVerbose() == false) { this.WriteExceptionDetails(ex); } } }); ExtensionManager extensionMgr = new ExtensionManager(this, ServiceName); extConfig = extensionMgr.Set(d, ExtensionConfiguration, this.Slot); } var deploymentInput = new DeploymentCreateParameters { PackageUri = packageUrl, Configuration = GeneralUtilities.GetConfiguration(this.Configuration), ExtensionConfiguration = extConfig, Label = this.Label, Name = this.Name, StartDeployment = !this.DoNotStart.IsPresent, TreatWarningsAsError = this.TreatWarningsAsError.IsPresent, }; InvokeInOperationContext(() => { try { var progress = new ProgressRecord(0, Resources.WaitForUploadingPackage, Resources.CreatingNewDeployment); WriteProgress(progress); ExecuteClientActionNewSM( deploymentInput, CommandRuntime.ToString(), () => this.ComputeClient.Deployments.Create( this.ServiceName, (DeploymentSlot)Enum.Parse(typeof(DeploymentSlot), this.Slot, true), deploymentInput)); if (removePackage == true) { this.RetryCall(s => AzureBlob.DeletePackageFromBlob( this.StorageClient, storageName, packageUrl)); } } catch (CloudException ex) { this.WriteExceptionDetails(ex); } }); }
private async Task DeployCloudServiceAsync( ComputeManagementClient computeClient, CloudBlobContainer container, string serviceName, string packagePath, string configurationPath, string diagnosticsConfigurationPath, DeploymentSlot targetSlot) { ThreadAdapter.QueueObject(new BuildEvent(BuildEventType.Information, BuildEventImportance.Medium, $"[{serviceName}] Checking the existence of an existing deployment")); var deployment = await computeClient.GetAzureDeyploymentAsync(serviceName, targetSlot); if (ForceDelete && deployment != null) { ThreadAdapter.QueueObject(new BuildEvent(BuildEventType.Information, BuildEventImportance.Medium, $"[{serviceName}] ForceDelete is true and found an existing deployment: Deleting it.")); await computeClient.Deployments.DeleteBySlotAsync(serviceName, targetSlot); deployment = null; } var blob = container.GetBlockBlobReference(DateTime.Now.ToString("yyyyMMdd_HHmmss_") + Path.GetFileName(packagePath)); ThreadAdapter.QueueObject(new BuildEvent(BuildEventType.Information, BuildEventImportance.Medium, $"[{serviceName}] Uploading the cloud service package to storage account {StorageAccountName} in the {StorageContainer} container.")); await blob.UploadFromFileAsync(packagePath, FileMode.Open); if (diagnosticsConfigurationPath != null) { ThreadAdapter.QueueObject(new BuildEvent(BuildEventType.Information, BuildEventImportance.Medium, $"[{serviceName}] Checking the Cloud Service for the PaaS Diagnostics extension -> Creating it if it doesn't exist.")); var diagnosticsConfiguration = File.ReadAllText(diagnosticsConfigurationPath); var diagnosticsCreated = await computeClient.AddDiagnosticsExtensionIfNotExistsAsync(serviceName, diagnosticsConfiguration); if (!diagnosticsCreated) { diagnosticsConfigurationPath = null; } } if (deployment == null) { ThreadAdapter.QueueObject(new BuildEvent(BuildEventType.Information, BuildEventImportance.Medium, $"[{serviceName}] Found no previous deployments -> Creating a new deployment into {targetSlot.GetEnumDescription()}.")); var createParams = new DeploymentCreateParameters { Label = serviceName, Name = $"{serviceName}{targetSlot.GetEnumDescription()}", PackageUri = blob.Uri, Configuration = File.ReadAllText(configurationPath), StartDeployment = true }; if (diagnosticsConfigurationPath != null) { createParams.ExtensionConfiguration = new ExtensionConfiguration { AllRoles = new[] { new ExtensionConfiguration.Extension { Id = FlexConfiguration.FlexDiagnosticsExtensionId } } }; } await computeClient.Deployments.CreateAsync(serviceName, targetSlot, createParams); } else { ThreadAdapter.QueueObject(new BuildEvent(BuildEventType.Information, BuildEventImportance.Medium, $"[{serviceName}] Found a previous deployment -> Updating the current deployment in {targetSlot.GetEnumDescription()}.")); await computeClient.Deployments.UpgradeBySlotAsync( serviceName, targetSlot, new DeploymentUpgradeParameters { Label = serviceName, PackageUri = blob.Uri, Configuration = File.ReadAllText(configurationPath) }); } if (VipSwap) { ThreadAdapter.QueueObject(new BuildEvent(BuildEventType.Information, BuildEventImportance.Medium, $"[{serviceName}] Swapping the deployments.")); await computeClient.Deployments.SwapAsync( serviceName, new DeploymentSwapParameters { SourceDeployment = $"{serviceName}{targetSlot.GetEnumDescription()}" }); if (DeleteStaging) { ThreadAdapter.QueueObject(new BuildEvent(BuildEventType.Information, BuildEventImportance.Medium, $"[{serviceName}] Deleting the staging deployment after the swap.")); await computeClient.Deployments.DeleteBySlotAsync(serviceName, DeploymentSlot.Staging); } } ThreadAdapter.QueueObject(new BuildEvent(BuildEventType.Information, BuildEventImportance.Medium, $"[{serviceName}] Deployment complete.")); }
/// <summary> /// Create or update hosted service deployment /// </summary> /// <param name="hostedServiceName"></param> /// <param name="input"></param> /// <param name="deploymentSlot"></param> /// <returns></returns> public DeploymentGetResponse CreateOrUpdateDeployment(string hostedServiceName, DeploymentCreateParameters input, DeploymentSlot deploymentSlot = DeploymentSlot.Production) { return(GetDeployment(hostedServiceName, input.Name) ?? CreateDeployment(hostedServiceName, input, deploymentSlot)); }