/// <summary> /// Builds the project and deploys it to Google Kubernetes Engine. /// </summary> /// <param name="project">The project to build and deploy.</param> /// <param name="options">Options for deploying and building.</param> public async Task DeployProjectToGkeAsync(IParsedProject project, Options options) { try { await GcpOutputWindow.ClearAsync(); await GcpOutputWindow.ActivateAsync(); await GcpOutputWindow.OutputLineAsync(string.Format(Resources.GkePublishDeployingToGkeMessage, project.Name)); TimeSpan deploymentDuration; Result result; using (await StatusbarService.FreezeAsync()) using (await StatusbarService.ShowDeployAnimationAsync()) using (IDisposableProgress progress = await StatusbarService.ShowProgressBarAsync(Resources.GkePublishDeploymentStatusMessage)) using (await ShellUtils.SetShellUIBusyAsync()) { DateTime deploymentStartTime = DateTime.Now; string imageTag = await BuildImageAsync(project, options, progress); if (imageTag != null) { result = await PublishImageToGkeAsync(imageTag, options, progress); } else { result = Result.FailedResult; } deploymentDuration = DateTime.Now - deploymentStartTime; } OutputResultData(project, options, result); if (options.OpenWebsite && result.ServiceExposed && result.ServicePublicIpAddress != null) { BrowserService.OpenBrowser($"http://{result.ServicePublicIpAddress}"); } if (result.Failed) { await StatusbarService.SetTextAsync(Resources.PublishFailureStatusMessage); EventsReporterWrapper.ReportEvent(GkeDeployedEvent.Create(CommandStatus.Failure)); } else { await StatusbarService.SetTextAsync(Resources.PublishSuccessStatusMessage); EventsReporterWrapper.ReportEvent( GkeDeployedEvent.Create(CommandStatus.Success, deploymentDuration)); } } catch (Exception) { await GcpOutputWindow.OutputLineAsync( string.Format(Resources.GkePublishDeploymentFailureMessage, project.Name)); await StatusbarService.SetTextAsync(Resources.PublishFailureStatusMessage); EventsReporterWrapper.ReportEvent(GkeDeployedEvent.Create(CommandStatus.Failure)); } }
/// <summary> /// Start the publish operation. /// </summary> public override async void Publish() { if (!ValidateInput()) { Debug.WriteLine("Invalid input cancelled the operation."); return; } var project = _publishDialog.Project; try { ShellUtils.SaveAllFiles(); var verifyGCloudTask = GCloudWrapperUtils.VerifyGCloudDependencies("kubectl"); _publishDialog.TrackTask(verifyGCloudTask); if (!await verifyGCloudTask) { Debug.WriteLine("Aborting deployment, no kubectl was found."); return; } var gcloudContext = new GCloudContext { CredentialsPath = CredentialsStore.Default.CurrentAccountPath, ProjectId = CredentialsStore.Default.CurrentProjectId, AppName = GoogleCloudExtensionPackage.ApplicationName, AppVersion = GoogleCloudExtensionPackage.ApplicationVersion, }; var kubectlContextTask = GCloudWrapper.GetKubectlContextForClusterAsync( cluster: SelectedCluster.Name, zone: SelectedCluster.Zone, context: gcloudContext); _publishDialog.TrackTask(kubectlContextTask); using (var kubectlContext = await kubectlContextTask) { var deploymentExistsTask = KubectlWrapper.DeploymentExistsAsync(DeploymentName, kubectlContext); _publishDialog.TrackTask(deploymentExistsTask); if (await deploymentExistsTask) { if (!UserPromptUtils.ActionPrompt( String.Format(Resources.GkePublishDeploymentAlreadyExistsMessage, DeploymentName), Resources.GkePublishDeploymentAlreadyExistsTitle, actionCaption: Resources.UiUpdateButtonCaption)) { return; } } var options = new GkeDeployment.DeploymentOptions { Cluster = SelectedCluster.Name, Zone = SelectedCluster.Zone, DeploymentName = DeploymentName, DeploymentVersion = DeploymentVersion, ExposeService = ExposeService, ExposePublicService = ExposePublicService, GCloudContext = gcloudContext, KubectlContext = kubectlContext, Replicas = int.Parse(Replicas), WaitingForServiceIpCallback = () => GcpOutputWindow.OutputLine(Resources.GkePublishWaitingForServiceIpMessage) }; GcpOutputWindow.Activate(); GcpOutputWindow.Clear(); GcpOutputWindow.OutputLine(String.Format(Resources.GkePublishDeployingToGkeMessage, project.Name)); _publishDialog.FinishFlow(); TimeSpan deploymentDuration; GkeDeploymentResult result; using (StatusbarHelper.Freeze()) using (StatusbarHelper.ShowDeployAnimation()) using (var progress = StatusbarHelper.ShowProgressBar(Resources.GkePublishDeploymentStatusMessage)) using (ShellUtils.SetShellUIBusy()) { var deploymentStartTime = DateTime.Now; result = await GkeDeployment.PublishProjectAsync( project, options, progress, VsVersionUtils.ToolsPathProvider, GcpOutputWindow.OutputLine); deploymentDuration = DateTime.Now - deploymentStartTime; } if (result != null) { OutputResultData(result, options); StatusbarHelper.SetText(Resources.PublishSuccessStatusMessage); if (OpenWebsite && result.ServiceExposed && result.PublicServiceIpAddress != null) { Process.Start($"http://{result.PublicServiceIpAddress}"); } EventsReporterWrapper.ReportEvent(GkeDeployedEvent.Create(CommandStatus.Success, deploymentDuration)); } else { GcpOutputWindow.OutputLine(String.Format(Resources.GkePublishDeploymentFailureMessage, project.Name)); StatusbarHelper.SetText(Resources.PublishFailureStatusMessage); EventsReporterWrapper.ReportEvent(GkeDeployedEvent.Create(CommandStatus.Failure)); } } } catch (Exception ex) when(!ErrorHandlerUtils.IsCriticalException(ex)) { GcpOutputWindow.OutputLine(String.Format(Resources.GkePublishDeploymentFailureMessage, project.Name)); StatusbarHelper.SetText(Resources.PublishFailureStatusMessage); _publishDialog.FinishFlow(); EventsReporterWrapper.ReportEvent(GkeDeployedEvent.Create(CommandStatus.Failure)); } }