protected override Task <bool> PerformActionAsync() { this.EnsureInProjectDirectory(); var projectLocation = Utilities.DetermineProjectLocation(this.WorkingDirectory, this.GetStringValueOrDefault(this.ProjectLocation, CommonDefinedCommandOptions.ARGUMENT_PROJECT_LOCATION, false)); string configuration = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.Configuration, CommonDefinedCommandOptions.ARGUMENT_CONFIGURATION, false) ?? "Release"; string targetFramework = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.TargetFramework, CommonDefinedCommandOptions.ARGUMENT_FRAMEWORK, false); string publishOptions = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.PublishOptions, CommonDefinedCommandOptions.ARGUMENT_PUBLISH_OPTIONS, false); if (string.IsNullOrEmpty(targetFramework)) { targetFramework = Utilities.LookupTargetFrameworkFromProjectFile(projectLocation); if (string.IsNullOrEmpty(targetFramework)) { targetFramework = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.TargetFramework, CommonDefinedCommandOptions.ARGUMENT_FRAMEWORK, true); } } var dotnetCli = new DotNetCLIWrapper(this.Logger, projectLocation); var publishLocation = Utilities.DeterminePublishLocation(null, projectLocation, configuration, targetFramework); this.Logger?.WriteLine("Determine publish location: " + publishLocation); this.Logger?.WriteLine("Executing publish command"); if (dotnetCli.Publish(projectLocation, publishLocation, targetFramework, configuration, publishOptions) != 0) { throw new ElasticBeanstalkExceptions("Error executing \"dotnet publish\"", ElasticBeanstalkExceptions.CommonErrorCode.DotnetPublishFailed); } EBUtilities.SetupAWSDeploymentManifest(this.Logger, this, this.DeployEnvironmentOptions, publishLocation); string package = this.GetStringValueOrDefault(this.OutputPackageFileName, EBDefinedCommandOptions.ARGUMENT_OUTPUT_PACKAGE, false); string zipArchivePath = null; if (!string.IsNullOrWhiteSpace(package)) { zipArchivePath = package; } else { zipArchivePath = Path.Combine(Directory.GetParent(publishLocation).FullName, new DirectoryInfo(projectLocation).Name + "-" + DateTime.Now.Ticks + ".zip"); } this.Logger?.WriteLine("Zipping up publish folder"); Utilities.ZipDirectory(this.Logger, publishLocation, zipArchivePath); this.Logger?.WriteLine("Zip archive created: " + zipArchivePath); return(Task.FromResult(true)); }
protected virtual void BuildProject(string projectLocation, string configuration, string targetFramework, string publishOptions, string publishLocation) { this.EnsureInProjectDirectory(); var dotnetCli = new DotNetCLIWrapper(this.Logger, projectLocation); this.Logger?.WriteLine("Executing publish command"); if (dotnetCli.Publish(projectLocation, publishLocation, targetFramework, configuration, publishOptions) != 0) { throw new ToolsException("Error executing \"dotnet publish\"", ToolsException.CommonErrorCode.DotnetPublishFailed); } }
public override async Task <bool> ExecuteAsync() { try { var projectLocation = Utilities.DetermineProjectLocation(this.WorkingDirectory, this.GetStringValueOrDefault(this.ProjectLocation, CommonDefinedCommandOptions.ARGUMENT_PROJECT_LOCATION, false)); string configuration = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.Configuration, CommonDefinedCommandOptions.ARGUMENT_CONFIGURATION, false) ?? "Release"; string targetFramework = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.TargetFramework, CommonDefinedCommandOptions.ARGUMENT_FRAMEWORK, false); if (string.IsNullOrEmpty(targetFramework)) { targetFramework = Utilities.LookupTargetFrameworkFromProjectFile(projectLocation); if (string.IsNullOrEmpty(targetFramework)) { targetFramework = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.TargetFramework, CommonDefinedCommandOptions.ARGUMENT_FRAMEWORK, true); } } string application = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.Application, EBDefinedCommandOptions.ARGUMENT_EB_APPLICATION, true); string environment = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.Environment, EBDefinedCommandOptions.ARGUMENT_EB_ENVIRONMENT, true); string versionLabel = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.VersionLabel, EBDefinedCommandOptions.ARGUMENT_EB_VERSION_LABEL, false) ?? DateTime.Now.Ticks.ToString(); bool doesApplicationExist = await DoesApplicationExist(application); bool doesEnvironmentExist = doesApplicationExist ? await DoesEnvironmentExist(application, environment) : false; if (!doesApplicationExist) { try { this.Logger?.WriteLine("Creating new Elastic Beanstalk Application"); await this.EBClient.CreateApplicationAsync(new CreateApplicationRequest { ApplicationName = application }); } catch (Exception e) { throw new ElasticBeanstalkExceptions("Error creating Elastic Beanstalk application: " + e.Message, ElasticBeanstalkExceptions.EBCode.FailedCreateApplication); } } var dotnetCli = new DotNetCLIWrapper(this.Logger, projectLocation); var publishLocation = Utilities.DeterminePublishLocation(projectLocation, configuration, targetFramework); this.Logger?.WriteLine("Determine publish location: " + publishLocation); this.Logger?.WriteLine("Executing publish command"); if (dotnetCli.Publish(projectLocation, publishLocation, targetFramework, configuration) != 0) { throw new ElasticBeanstalkExceptions("Error executing \"dotnet publish\"", ElasticBeanstalkExceptions.CommonErrorCode.DotnetPublishFailed); } SetupAWSDeploymentManifest(publishLocation); var zipArchivePath = Path.Combine(Directory.GetParent(publishLocation).FullName, new DirectoryInfo(projectLocation).Name + "-" + DateTime.Now.Ticks + ".zip"); this.Logger?.WriteLine("Zipping up publish folder"); Utilities.ZipDirectory(this.Logger, publishLocation, zipArchivePath); this.Logger?.WriteLine("Zip archive created: " + zipArchivePath); S3Location s3Loc; try { s3Loc = await this.UploadDeploymentPackageAsync(application, versionLabel, zipArchivePath).ConfigureAwait(false); } catch (Exception e) { throw new ElasticBeanstalkExceptions("Error uploading application bundle to S3: " + e.Message, ElasticBeanstalkExceptions.EBCode.FailedToUploadBundle); } try { this.Logger?.WriteLine("Creating new application version: " + versionLabel); await this.EBClient.CreateApplicationVersionAsync(new CreateApplicationVersionRequest { ApplicationName = application, VersionLabel = versionLabel, SourceBundle = s3Loc }).ConfigureAwait(false); } catch (Exception e) { throw new ElasticBeanstalkExceptions("Error creating Elastic Beanstalk application version: " + e.Message, ElasticBeanstalkExceptions.EBCode.FailedCreateApplicationVersion); } this.Logger?.WriteLine("Getting latest environment event date before update"); var startingEventDate = await GetLatestEventDateAsync(application, environment); string environmentArn; if (doesEnvironmentExist) { environmentArn = await UpdateEnvironment(application, environment, versionLabel); } else { environmentArn = await CreateEnvironment(application, environment, versionLabel); } bool?waitForUpdate = this.GetBoolValueOrDefault(this.DeployEnvironmentOptions.WaitForUpdate, EBDefinedCommandOptions.ARGUMENT_WAIT_FOR_UPDATE, false); if (!waitForUpdate.HasValue || waitForUpdate.Value) { this.Logger?.WriteLine("Waiting for environment update to complete"); var success = await this.WaitForDeploymentCompletionAsync(application, environment, startingEventDate); if (success) { this.Logger?.WriteLine("Update Complete"); } else { throw new ElasticBeanstalkExceptions("Environment update failed", ElasticBeanstalkExceptions.EBCode.FailedEnvironmentUpdate); } } else { this.Logger?.WriteLine("Environment update initiated"); } if (doesEnvironmentExist) { var tags = ConvertToTagsCollection(); if (tags != null && tags.Count > 0) { var updateTagsRequest = new UpdateTagsForResourceRequest { ResourceArn = environmentArn, TagsToAdd = tags }; this.Logger?.WriteLine("Updating Tags on environment"); try { await this.EBClient.UpdateTagsForResourceAsync(updateTagsRequest); } catch (Exception e) { throw new ElasticBeanstalkExceptions("Error updating tags for environment: " + e.Message, ElasticBeanstalkExceptions.EBCode.FailedToUpdateTags); } } } if (this.GetBoolValueOrDefault(this.PersistConfigFile, CommonDefinedCommandOptions.ARGUMENT_PERSIST_CONFIG_FILE, false).GetValueOrDefault()) { this.SaveConfigFile(); } } catch (ToolsException e) { this.Logger?.WriteLine(e.Message); this.LastToolsException = e; return(false); } catch (Exception e) { this.Logger?.WriteLine($"Unknown error deploying application to Elastic Beanstalk: {e.Message}"); this.Logger?.WriteLine(e.StackTrace); return(false); } return(true); }
private async Task <CreateLayerZipFileResult> CreateRuntimePackageStoreLayerZipFile(string layerName, string s3Prefix) { var targetFramework = this.GetStringValueOrDefault(this.TargetFramework, CommonDefinedCommandOptions.ARGUMENT_FRAMEWORK, true); var projectLocation = this.GetStringValueOrDefault(this.ProjectLocation, CommonDefinedCommandOptions.ARGUMENT_PROJECT_LOCATION, false); var enableOptimization = this.GetBoolValueOrDefault(this.EnablePackageOptimization, LambdaDefinedCommandOptions.ARGUMENT_ENABLE_PACKAGE_OPTIMIZATION, false).GetValueOrDefault(); if (string.Equals(targetFramework, "netcoreapp3.1")) { var version = DotNetCLIWrapper.GetSdkVersion(); // .NET SDK 3.1 versions less then 3.1.400 have an issue throwing NullReferenceExceptions when pruning packages out with the manifest. // https://github.com/dotnet/sdk/issues/10973 if (version < Version.Parse("3.1.400")) { var message = $"Publishing runtime package store layers targeting .NET Core 3.1 requires at least version 3.1.400 of the .NET SDK. Current version installed is {version}."; throw new LambdaToolsException(message, LambdaToolsException.LambdaErrorCode.DisabledSupportForNET31Layers); } } #if NETCORE if (enableOptimization) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { throw new LambdaToolsException($"Package optimization is only possible on Amazon Linux. To use this feature execute the command in an Amazon Linux environment.", LambdaToolsException.LambdaErrorCode.UnsupportedOptimizationPlatform); } else { this.Logger.WriteLine("Warning: Package optimization has been enabled. Be sure to run this on an Amazon Linux environment or the optimization might not be compatbile with the Lambda runtime."); } } #else // This is the case the code is run in the AWS Toolkit for Visual Studio which will never run on Amazon Linux. enableOptimization = false; #endif // This is the manifest that list the NuGet packages via <PackageReference> elements in the msbuild project file. var packageManifest = this.GetStringValueOrDefault(this.PackageManifest, LambdaDefinedCommandOptions.ARGUMENT_PACKAGE_MANIFEST, false); // If this is null attempt to use the current directory. This is likely if the intent is to make a // layer from the current Lambda project. if (string.IsNullOrEmpty(packageManifest)) { packageManifest = Utilities.DetermineProjectLocation(this.WorkingDirectory, projectLocation); } // If this is a directory look to see if there is a single csproj of fsproj in the directory in use that. // This is to make it easy to make a layer in the current directory of a Lambda function. if (Directory.Exists(packageManifest)) { var files = Directory.GetFiles(packageManifest, "*.csproj"); if (files.Length == 1) { packageManifest = Path.Combine(packageManifest, files[0]); } else if (files.Length == 0) { files = Directory.GetFiles(packageManifest, "*.fsproj"); if (files.Length == 1) { packageManifest = Path.Combine(packageManifest, files[0]); } } } if (!File.Exists(packageManifest)) { throw new LambdaToolsException($"Can not find package manifest {packageManifest}. Make sure to point to a file not a directory.", LambdaToolsException.LambdaErrorCode.LayerPackageManifestNotFound); } // Create second subdirectory so that when the directory is zipped the sub directory is retained in the zip file. // The sub directory will be created in the /opt directory in the Lambda environment. var tempDirectoryName = $"{layerName}-{DateTime.UtcNow.Ticks}".ToLower(); var optDirectory = this.GetStringValueOrDefault(this.OptDirectory, LambdaDefinedCommandOptions.ARGUMENT_OPT_DIRECTORY, false); if (string.IsNullOrEmpty(optDirectory)) { optDirectory = LambdaConstants.DEFAULT_LAYER_OPT_DIRECTORY; } var tempRootPath = Path.Combine(Path.GetTempPath(), tempDirectoryName); var storeOutputDirectory = Path.Combine(tempRootPath, optDirectory); { var convertResult = LambdaUtilities.ConvertManifestToSdkManifest(targetFramework, packageManifest); if (convertResult.ShouldDelete) { this.Logger?.WriteLine("Converted ASP.NET Core project file to temporary package manifest file."); } var architecture = this.GetStringValueOrDefault(this.Architecture, LambdaDefinedCommandOptions.ARGUMENT_FUNCTION_ARCHITECTURE, false); var cliWrapper = new LambdaDotNetCLIWrapper(this.Logger, this.WorkingDirectory); if (cliWrapper.Store(defaults: this.DefaultConfig, projectLocation: projectLocation, outputLocation: storeOutputDirectory, targetFramework: targetFramework, packageManifest: convertResult.PackageManifest, architecture: architecture, enableOptimization: enableOptimization) != 0) { throw new LambdaToolsException($"Error executing the 'dotnet store' command", LambdaToolsException.LambdaErrorCode.StoreCommandError); } if (convertResult.ShouldDelete) { File.Delete(convertResult.PackageManifest); } } // The artifact.xml file is generated by the "dotnet store" command that lists the packages that were added to the store. // It is required during a "dotnet publish" so the NuGet packages in the store will be filtered out. var artifactXmlPath = Path.Combine(storeOutputDirectory, "x64", targetFramework, "artifact.xml"); if (!File.Exists(artifactXmlPath)) { throw new LambdaToolsException($"Failed to find artifact.xml file in created local store.", LambdaToolsException.LambdaErrorCode.FailedToFindArtifactZip); } this.Logger.WriteLine($"Uploading runtime package store manifest to S3"); var s3Key = await UploadFile(artifactXmlPath, $"{s3Prefix}artifact.xml"); this.Logger.WriteLine($"Create zip file of runtime package store directory"); var zipPath = Path.Combine(Path.GetTempPath(), $"{layerName}-{DateTime.UtcNow.Ticks}.zip"); if (File.Exists(zipPath)) { File.Delete(zipPath); } LambdaPackager.BundleDirectory(zipPath, tempRootPath, false, this.Logger); var result = new CreateLayerZipFileResult { ZipFile = zipPath, LayerDirectory = optDirectory }; var s3Bucket = this.GetStringValueOrDefault(this.S3Bucket, LambdaDefinedCommandOptions.ARGUMENT_S3_BUCKET, true); // Set the description field to the our JSON layer manifest file so when the tooling is used // to create a package of a Lambda function in the future the artifact.xml file can be used during "dotnet publish". result.Description = GeneratorRuntimePackageManifestLayerDescription(optDirectory, s3Bucket, s3Key, enableOptimization); var compatibleRuntime = LambdaUtilities.DetermineLambdaRuntimeFromTargetFramework(targetFramework); if (!string.IsNullOrEmpty(compatibleRuntime)) { result.CompatibleRuntimes = new List <string>() { compatibleRuntime }; } return(result); }
public override async Task <bool> ExecuteAsync() { try { string configuration = this.GetStringValueOrDefault(this.PushDockerImageProperties.Configuration, CommonDefinedCommandOptions.ARGUMENT_CONFIGURATION, false) ?? "Release"; string targetFramework = this.GetStringValueOrDefault(this.PushDockerImageProperties.TargetFramework, CommonDefinedCommandOptions.ARGUMENT_FRAMEWORK, false); this.PushDockerImageProperties.DockerImageTag = this.GetStringValueOrDefault(this.PushDockerImageProperties.DockerImageTag, ECSDefinedCommandOptions.ARGUMENT_DOCKER_TAG, true).ToLower(); if (!this.PushDockerImageProperties.DockerImageTag.Contains(":")) { this.PushDockerImageProperties.DockerImageTag += ":latest"; } var projectLocation = Utilities.DetermineProjectLocation(this.WorkingDirectory, this.ProjectLocation); var dockerDetails = InspectDockerFile(projectLocation); if (!dockerDetails.SkipDotnetBuild) { var dotnetCli = new DotNetCLIWrapper(this.Logger, projectLocation); this.Logger?.WriteLine("Executing publish command"); if (dotnetCli.Publish(projectLocation, dockerDetails.ExpectedPublishLocation, targetFramework, configuration) != 0) { throw new DockerToolsException("Error executing \"dotnet publish\"", DockerToolsException.CommonErrorCode.DotnetPublishFailed); } } var dockerCli = new DockerCLIWrapper(this.Logger, projectLocation); this.Logger?.WriteLine("Executing docker build"); string dockerBuildWorkingDirectory = dockerDetails.BuildFromSolutionDirectory ? DetermineSolutionDirectory(projectLocation) : projectLocation; if (dockerCli.Build(this.DefaultConfig, dockerBuildWorkingDirectory, Path.Combine(projectLocation, "Dockerfile"), this.PushDockerImageProperties.DockerImageTag) != 0) { throw new DockerToolsException("Error executing \"docker build\"", DockerToolsException.ECSErrorCode.DockerBuildFailed); } await InitiateDockerLogin(dockerCli); Repository repository = await SetupECRRepository(this.PushDockerImageProperties.DockerImageTag.Substring(0, this.PushDockerImageProperties.DockerImageTag.IndexOf(':'))); var targetTag = repository.RepositoryUri + this.PushDockerImageProperties.DockerImageTag.Substring(this.PushDockerImageProperties.DockerImageTag.IndexOf(':')); this.Logger?.WriteLine($"Taging image {this.PushDockerImageProperties.DockerImageTag} with {targetTag}"); if (dockerCli.Tag(this.PushDockerImageProperties.DockerImageTag, targetTag) != 0) { throw new DockerToolsException("Error executing \"docker tag\"", DockerToolsException.ECSErrorCode.DockerTagFail); } this.Logger?.WriteLine("Pushing image to ECR repository"); if (dockerCli.Push(targetTag) != 0) { throw new DockerToolsException("Error executing \"docker push\"", DockerToolsException.ECSErrorCode.DockerPushFail); } this.PushedImageUri = targetTag; this.Logger?.WriteLine($"Image {this.PushedImageUri} Push Complete. "); if (this.GetBoolValueOrDefault(this.PersistConfigFile, CommonDefinedCommandOptions.ARGUMENT_PERSIST_CONFIG_FILE, false).GetValueOrDefault()) { this.SaveConfigFile(); } } catch (DockerToolsException e) { this.Logger?.WriteLine(e.Message); this.LastToolsException = e; return(false); } catch (Exception e) { this.Logger?.WriteLine($"Unknown error executing docker push to Amazon Elastic Container Registry: {e.Message}"); this.Logger?.WriteLine(e.StackTrace); return(false); } return(true); }
protected override async Task <bool> PerformActionAsync() { string package = this.GetStringValueOrDefault(this.Package, EBDefinedCommandOptions.ARGUMENT_INPUT_PACKAGE, false); string application = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.Application, EBDefinedCommandOptions.ARGUMENT_EB_APPLICATION, true); string versionLabel = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.VersionLabel, EBDefinedCommandOptions.ARGUMENT_EB_VERSION_LABEL, false) ?? DateTime.Now.Ticks.ToString(); string environment = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.Environment, EBDefinedCommandOptions.ARGUMENT_EB_ENVIRONMENT, true); bool doesApplicationExist = await DoesApplicationExist(application); var environmentDescription = doesApplicationExist ? await GetEnvironmentDescription(application, environment) : null; bool isWindowsEnvironment; List <ConfigurationOptionSetting> existingSettings = null; if (environmentDescription != null) { isWindowsEnvironment = EBUtilities.IsSolutionStackWindows(environmentDescription.SolutionStackName); var response = await this.EBClient.DescribeConfigurationSettingsAsync(new DescribeConfigurationSettingsRequest { ApplicationName = environmentDescription.ApplicationName, EnvironmentName = environmentDescription.EnvironmentName }); if (response.ConfigurationSettings.Count != 1) { throw new ElasticBeanstalkExceptions($"Unknown error to retrieving settings for existing Beanstalk environment.", ElasticBeanstalkExceptions.EBCode.FailedToDescribeEnvironmentSettings); } existingSettings = response.ConfigurationSettings[0].OptionSettings; } else { isWindowsEnvironment = EBUtilities.IsSolutionStackWindows(this.GetSolutionStackOrDefault(this.DeployEnvironmentOptions.SolutionStack, EBDefinedCommandOptions.ARGUMENT_SOLUTION_STACK, true)); } await CreateEBApplicationIfNotExist(application, doesApplicationExist); string zipArchivePath = null; if (string.IsNullOrEmpty(package)) { this.EnsureInProjectDirectory(); var projectLocation = Utilities.DetermineProjectLocation(this.WorkingDirectory, this.GetStringValueOrDefault(this.ProjectLocation, CommonDefinedCommandOptions.ARGUMENT_PROJECT_LOCATION, false)); string configuration = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.Configuration, CommonDefinedCommandOptions.ARGUMENT_CONFIGURATION, false) ?? "Release"; string targetFramework = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.TargetFramework, CommonDefinedCommandOptions.ARGUMENT_FRAMEWORK, false); string publishOptions = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.PublishOptions, CommonDefinedCommandOptions.ARGUMENT_PUBLISH_OPTIONS, false); if (string.IsNullOrEmpty(targetFramework)) { targetFramework = Utilities.LookupTargetFrameworkFromProjectFile(projectLocation); if (string.IsNullOrEmpty(targetFramework)) { targetFramework = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.TargetFramework, CommonDefinedCommandOptions.ARGUMENT_FRAMEWORK, true); } } var dotnetCli = new DotNetCLIWrapper(this.Logger, projectLocation); var publishLocation = Utilities.DeterminePublishLocation(null, projectLocation, configuration, targetFramework); this.Logger?.WriteLine("Determine publish location: " + publishLocation); if (!isWindowsEnvironment) { if (publishOptions == null || !publishOptions.Contains("-r ") && !publishOptions.Contains("--runtime ")) { publishOptions += " --runtime linux-x64"; } if (publishOptions == null || !publishOptions.Contains("--self-contained")) { var selfContained = this.GetBoolValueOrDefault(this.DeployEnvironmentOptions.SelfContained, CommonDefinedCommandOptions.ARGUMENT_SELF_CONTAINED, false); publishOptions += $" --self-contained {selfContained.GetValueOrDefault().ToString(CultureInfo.InvariantCulture).ToLowerInvariant()}"; } } this.Logger?.WriteLine("Executing publish command"); if (dotnetCli.Publish(projectLocation, publishLocation, targetFramework, configuration, publishOptions) != 0) { throw new ElasticBeanstalkExceptions("Error executing \"dotnet publish\"", ElasticBeanstalkExceptions.CommonErrorCode.DotnetPublishFailed); } if (isWindowsEnvironment) { this.Logger?.WriteLine("Configuring application bundle for a Windows deployment"); EBUtilities.SetupAWSDeploymentManifest(this.Logger, this, this.DeployEnvironmentOptions, publishLocation); } else { var proxyServer = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.ProxyServer, EBDefinedCommandOptions.ARGUMENT_PROXY_SERVER, false); if (string.IsNullOrEmpty(proxyServer)) { proxyServer = existingSettings.FindExistingValue(OPTIONS_NAMESPACE_ENVIRONMENT_PROXY, OPTIONS_NAMESPACE_APPLICATION_ENVIRONMENT); } var applicationPort = this.GetIntValueOrDefault(this.DeployEnvironmentOptions.ApplicationPort, EBDefinedCommandOptions.ARGUMENT_APPLICATION_PORT, false); if (!applicationPort.HasValue) { var strPort = existingSettings.FindExistingValue(OPTIONS_NAMESPACE_APPLICATION_ENVIRONMENT, OPTIONS_NAME_APPLICATION_PORT); int intPort; if (int.TryParse(strPort, NumberStyles.Any, CultureInfo.InvariantCulture, out intPort)) { applicationPort = intPort; } } this.Logger?.WriteLine("Configuring application bundle for a Linux deployment"); EBUtilities.SetupPackageForLinux(this.Logger, this, this.DeployEnvironmentOptions, publishLocation, proxyServer, applicationPort); } zipArchivePath = Path.Combine(Directory.GetParent(publishLocation).FullName, new DirectoryInfo(projectLocation).Name + "-" + DateTime.Now.Ticks + ".zip"); this.Logger?.WriteLine("Zipping up publish folder"); Utilities.ZipDirectory(this.Logger, publishLocation, zipArchivePath); this.Logger?.WriteLine("Zip archive created: " + zipArchivePath); } else { if (!File.Exists(package)) { throw new ElasticBeanstalkExceptions($"Package {package} does not exist", ElasticBeanstalkExceptions.EBCode.InvalidPackage); } if (!string.Equals(Path.GetExtension(package), ".zip", StringComparison.OrdinalIgnoreCase)) { throw new ElasticBeanstalkExceptions($"Package {package} must be a zip file", ElasticBeanstalkExceptions.EBCode.InvalidPackage); } this.Logger?.WriteLine($"Skipping compilation and using precompiled package {package}"); zipArchivePath = package; } S3Location s3Loc; try { s3Loc = await this.UploadDeploymentPackageAsync(application, versionLabel, zipArchivePath).ConfigureAwait(false); } catch (Exception e) { throw new ElasticBeanstalkExceptions("Error uploading application bundle to S3: " + e.Message, ElasticBeanstalkExceptions.EBCode.FailedToUploadBundle); } try { this.Logger?.WriteLine("Creating new application version: " + versionLabel); await this.EBClient.CreateApplicationVersionAsync(new CreateApplicationVersionRequest { ApplicationName = application, VersionLabel = versionLabel, SourceBundle = s3Loc }).ConfigureAwait(false); } catch (Exception e) { throw new ElasticBeanstalkExceptions("Error creating Elastic Beanstalk application version: " + e.Message, ElasticBeanstalkExceptions.EBCode.FailedCreateApplicationVersion); } this.Logger?.WriteLine("Getting latest environment event date before update"); var startingEventDate = await GetLatestEventDateAsync(application, environment); string environmentArn; if (environmentDescription != null) { environmentArn = await UpdateEnvironment(environmentDescription, versionLabel); } else { environmentArn = await CreateEnvironment(application, environment, versionLabel, isWindowsEnvironment); } bool?waitForUpdate = this.GetBoolValueOrDefault(this.DeployEnvironmentOptions.WaitForUpdate, EBDefinedCommandOptions.ARGUMENT_WAIT_FOR_UPDATE, false); if (!waitForUpdate.HasValue || waitForUpdate.Value) { this.Logger?.WriteLine("Waiting for environment update to complete"); var success = await this.WaitForDeploymentCompletionAsync(application, environment, startingEventDate); if (success) { this.Logger?.WriteLine("Update Complete"); } else { throw new ElasticBeanstalkExceptions("Environment update failed", ElasticBeanstalkExceptions.EBCode.FailedEnvironmentUpdate); } } else { this.Logger?.WriteLine("Environment update initiated"); } if (environmentDescription != null) { var tags = ConvertToTagsCollection(); if (tags != null && tags.Count > 0) { var updateTagsRequest = new UpdateTagsForResourceRequest { ResourceArn = environmentArn, TagsToAdd = tags }; this.Logger?.WriteLine("Updating Tags on environment"); try { await this.EBClient.UpdateTagsForResourceAsync(updateTagsRequest); } catch (Exception e) { throw new ElasticBeanstalkExceptions("Error updating tags for environment: " + e.Message, ElasticBeanstalkExceptions.EBCode.FailedToUpdateTags); } } } return(true); }
protected override async Task <bool> PerformActionAsync() { var configuration = this.GetStringValueOrDefault(this.PushDockerImageProperties.Configuration, CommonDefinedCommandOptions.ARGUMENT_CONFIGURATION, false) ?? "Release"; var targetFramework = this.GetStringValueOrDefault(this.PushDockerImageProperties.TargetFramework, CommonDefinedCommandOptions.ARGUMENT_FRAMEWORK, false); string publishOptions = this.GetStringValueOrDefault(this.PushDockerImageProperties.PublishOptions, CommonDefinedCommandOptions.ARGUMENT_PUBLISH_OPTIONS, false); this.PushDockerImageProperties.DockerImageTag = this.GetStringValueOrDefault(this.PushDockerImageProperties.DockerImageTag, ECSDefinedCommandOptions.ARGUMENT_DOCKER_TAG, true).ToLower(); if (!this.PushDockerImageProperties.DockerImageTag.Contains(":")) { this.PushDockerImageProperties.DockerImageTag += ":latest"; } var projectLocation = Utilities.DetermineProjectLocation(this.WorkingDirectory, this.ProjectLocation); var dockerDetails = InspectDockerFile(this.Logger, projectLocation); if (!dockerDetails.SkipDotnetBuild) { this.EnsureInProjectDirectory(); var dotnetCli = new DotNetCLIWrapper(this.Logger, projectLocation); this.Logger?.WriteLine("Executing publish command"); if (dotnetCli.Publish(projectLocation, dockerDetails.ExpectedPublishLocation, targetFramework, configuration, publishOptions) != 0) { throw new DockerToolsException("Error executing \"dotnet publish\"", DockerToolsException.CommonErrorCode.DotnetPublishFailed); } } var dockerCli = new DockerCLIWrapper(this.Logger, projectLocation); this.Logger?.WriteLine("Executing docker build"); var dockerBuildWorkingDirectory = this.GetStringValueOrDefault(this.PushDockerImageProperties.DockerBuildWorkingDirectory, ECSDefinedCommandOptions.ARGUMENT_DOCKER_BUILD_WORKING_DIRECTORY, false); if (string.IsNullOrEmpty(dockerBuildWorkingDirectory)) { dockerBuildWorkingDirectory = dockerDetails.BuildFromSolutionDirectory ? DetermineSolutionDirectory(projectLocation) : projectLocation; } else { if (!Path.IsPathRooted(dockerBuildWorkingDirectory)) { dockerBuildWorkingDirectory = Path.GetFullPath(Path.Combine(projectLocation, dockerBuildWorkingDirectory)); } this.PushDockerImageProperties.DockerBuildWorkingDirectory = Utilities.RelativePathTo(projectLocation, dockerBuildWorkingDirectory); } var dockerBuildOptions = this.GetStringValueOrDefault(this.PushDockerImageProperties.DockerBuildOptions, ECSDefinedCommandOptions.ARGUMENT_DOCKER_BUILD_OPTIONS, false); if (dockerCli.Build(this.DefaultConfig, dockerBuildWorkingDirectory, Path.Combine(projectLocation, "Dockerfile"), this.PushDockerImageProperties.DockerImageTag, dockerBuildOptions) != 0) { throw new DockerToolsException("Error executing \"docker build\"", DockerToolsException.ECSErrorCode.DockerBuildFailed); } await InitiateDockerLogin(dockerCli); Repository repository = await SetupECRRepository(this.PushDockerImageProperties.DockerImageTag.Substring(0, this.PushDockerImageProperties.DockerImageTag.IndexOf(':'))); var targetTag = repository.RepositoryUri + this.PushDockerImageProperties.DockerImageTag.Substring(this.PushDockerImageProperties.DockerImageTag.IndexOf(':')); this.Logger?.WriteLine($"Taging image {this.PushDockerImageProperties.DockerImageTag} with {targetTag}"); if (dockerCli.Tag(this.PushDockerImageProperties.DockerImageTag, targetTag) != 0) { throw new DockerToolsException("Error executing \"docker tag\"", DockerToolsException.ECSErrorCode.DockerTagFail); } this.Logger?.WriteLine("Pushing image to ECR repository"); if (dockerCli.Push(targetTag) != 0) { throw new DockerToolsException("Error executing \"docker push\"", DockerToolsException.ECSErrorCode.DockerPushFail); } this.PushedImageUri = targetTag; this.Logger?.WriteLine($"Image {this.PushedImageUri} Push Complete. "); return(true); }
protected override async Task <bool> PerformActionAsync() { string package = this.GetStringValueOrDefault(this.Package, EBDefinedCommandOptions.ARGUMENT_INPUT_PACKAGE, false); string application = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.Application, EBDefinedCommandOptions.ARGUMENT_EB_APPLICATION, true); string versionLabel = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.VersionLabel, EBDefinedCommandOptions.ARGUMENT_EB_VERSION_LABEL, false) ?? DateTime.Now.Ticks.ToString(); string environment = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.Environment, EBDefinedCommandOptions.ARGUMENT_EB_ENVIRONMENT, true); bool doesApplicationExist = await DoesApplicationExist(application); bool doesEnvironmentExist = doesApplicationExist ? await DoesEnvironmentExist(application, environment) : false; await CreateEBApplicationIfNotExist(application, doesApplicationExist); string zipArchivePath = null; if (string.IsNullOrEmpty(package)) { this.EnsureInProjectDirectory(); var projectLocation = Utilities.DetermineProjectLocation(this.WorkingDirectory, this.GetStringValueOrDefault(this.ProjectLocation, CommonDefinedCommandOptions.ARGUMENT_PROJECT_LOCATION, false)); string configuration = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.Configuration, CommonDefinedCommandOptions.ARGUMENT_CONFIGURATION, false) ?? "Release"; string targetFramework = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.TargetFramework, CommonDefinedCommandOptions.ARGUMENT_FRAMEWORK, false); string publishOptions = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.PublishOptions, CommonDefinedCommandOptions.ARGUMENT_PUBLISH_OPTIONS, false); if (string.IsNullOrEmpty(targetFramework)) { targetFramework = Utilities.LookupTargetFrameworkFromProjectFile(projectLocation); if (string.IsNullOrEmpty(targetFramework)) { targetFramework = this.GetStringValueOrDefault(this.DeployEnvironmentOptions.TargetFramework, CommonDefinedCommandOptions.ARGUMENT_FRAMEWORK, true); } } var dotnetCli = new DotNetCLIWrapper(this.Logger, projectLocation); var publishLocation = Utilities.DeterminePublishLocation(null, projectLocation, configuration, targetFramework); this.Logger?.WriteLine("Determine publish location: " + publishLocation); this.Logger?.WriteLine("Executing publish command"); if (dotnetCli.Publish(projectLocation, publishLocation, targetFramework, configuration, publishOptions) != 0) { throw new ElasticBeanstalkExceptions("Error executing \"dotnet publish\"", ElasticBeanstalkExceptions.CommonErrorCode.DotnetPublishFailed); } EBUtilities.SetupAWSDeploymentManifest(this.Logger, this, this.DeployEnvironmentOptions, publishLocation); zipArchivePath = Path.Combine(Directory.GetParent(publishLocation).FullName, new DirectoryInfo(projectLocation).Name + "-" + DateTime.Now.Ticks + ".zip"); this.Logger?.WriteLine("Zipping up publish folder"); Utilities.ZipDirectory(this.Logger, publishLocation, zipArchivePath); this.Logger?.WriteLine("Zip archive created: " + zipArchivePath); } else { if (!File.Exists(package)) { throw new ElasticBeanstalkExceptions($"Package {package} does not exist", ElasticBeanstalkExceptions.EBCode.InvalidPackage); } if (!string.Equals(Path.GetExtension(package), ".zip", StringComparison.OrdinalIgnoreCase)) { throw new ElasticBeanstalkExceptions($"Package {package} must be a zip file", ElasticBeanstalkExceptions.EBCode.InvalidPackage); } this.Logger?.WriteLine($"Skipping compilation and using precompiled package {package}"); zipArchivePath = package; } S3Location s3Loc; try { s3Loc = await this.UploadDeploymentPackageAsync(application, versionLabel, zipArchivePath).ConfigureAwait(false); } catch (Exception e) { throw new ElasticBeanstalkExceptions("Error uploading application bundle to S3: " + e.Message, ElasticBeanstalkExceptions.EBCode.FailedToUploadBundle); } try { this.Logger?.WriteLine("Creating new application version: " + versionLabel); await this.EBClient.CreateApplicationVersionAsync(new CreateApplicationVersionRequest { ApplicationName = application, VersionLabel = versionLabel, SourceBundle = s3Loc }).ConfigureAwait(false); } catch (Exception e) { throw new ElasticBeanstalkExceptions("Error creating Elastic Beanstalk application version: " + e.Message, ElasticBeanstalkExceptions.EBCode.FailedCreateApplicationVersion); } this.Logger?.WriteLine("Getting latest environment event date before update"); var startingEventDate = await GetLatestEventDateAsync(application, environment); string environmentArn; if (doesEnvironmentExist) { environmentArn = await UpdateEnvironment(application, environment, versionLabel); } else { environmentArn = await CreateEnvironment(application, environment, versionLabel); } bool?waitForUpdate = this.GetBoolValueOrDefault(this.DeployEnvironmentOptions.WaitForUpdate, EBDefinedCommandOptions.ARGUMENT_WAIT_FOR_UPDATE, false); if (!waitForUpdate.HasValue || waitForUpdate.Value) { this.Logger?.WriteLine("Waiting for environment update to complete"); var success = await this.WaitForDeploymentCompletionAsync(application, environment, startingEventDate); if (success) { this.Logger?.WriteLine("Update Complete"); } else { throw new ElasticBeanstalkExceptions("Environment update failed", ElasticBeanstalkExceptions.EBCode.FailedEnvironmentUpdate); } } else { this.Logger?.WriteLine("Environment update initiated"); } if (doesEnvironmentExist) { var tags = ConvertToTagsCollection(); if (tags != null && tags.Count > 0) { var updateTagsRequest = new UpdateTagsForResourceRequest { ResourceArn = environmentArn, TagsToAdd = tags }; this.Logger?.WriteLine("Updating Tags on environment"); try { await this.EBClient.UpdateTagsForResourceAsync(updateTagsRequest); } catch (Exception e) { throw new ElasticBeanstalkExceptions("Error updating tags for environment: " + e.Message, ElasticBeanstalkExceptions.EBCode.FailedToUpdateTags); } } } return(true); }