private void SetupFunctionAppExpressArtifacts(DeploymentContext context) { string sitePackages = "/home/data/SitePackages"; string packageNameFile = Path.Combine(sitePackages, "packagename.txt"); string packagePathFile = Path.Combine(sitePackages, "packagepath.txt"); FileSystemHelpers.EnsureDirectory(sitePackages); string zipAppName = $"{DateTime.UtcNow.ToString("yyyyMMddHHmmss")}.zip"; string createdZip = PackageArtifactFromFolder(context, OryxBuildConstants.FunctionAppBuildSettings.ExpressBuildSetup, OryxBuildConstants.FunctionAppBuildSettings.ExpressBuildSetup, zipAppName, BuildArtifactType.Zip, numBuildArtifacts: -1); var copyExe = ExternalCommandFactory.BuildExternalCommandExecutable(OryxBuildConstants.FunctionAppBuildSettings.ExpressBuildSetup, sitePackages, context.Logger); var copyToPath = Path.Combine(sitePackages, zipAppName); try { copyExe.ExecuteWithProgressWriter(context.Logger, context.Tracer, $"cp {createdZip} {copyToPath}"); } catch (Exception) { context.GlobalLogger.LogError(); throw; } // Gotta remove the old zips DeploymentHelper.PurgeBuildArtifactsIfNecessary(sitePackages, BuildArtifactType.Zip, context.Tracer, totalAllowedFiles: 2); File.WriteAllText(packageNameFile, zipAppName); File.WriteAllText(packagePathFile, sitePackages); }
private void SetupAppServiceArtifacts(DeploymentContext context) { string sitePackages = "/home/data/SitePackages"; string deploymentsPath = $"/home/site/deployments/"; string artifactPath = $"/home/site/deployments/{context.CommitId}/artifact"; string packageNameFile = Path.Combine(sitePackages, "packagename.txt"); string packagePathFile = Path.Combine(sitePackages, "packagepath.txt"); FileSystemHelpers.EnsureDirectory(sitePackages); FileSystemHelpers.EnsureDirectory(artifactPath); string zipAppName = $"{DateTime.UtcNow.ToString("yyyyMMddHHmmss")}.zip"; string createdZip = PackageArtifactFromFolder(context, context.BuildTempPath, context.BuildTempPath, zipAppName, BuildArtifactType.Zip, numBuildArtifacts: -1); var copyExe = ExternalCommandFactory.BuildExternalCommandExecutable(context.BuildTempPath, artifactPath, context.Logger); var copyToPath = Path.Combine(artifactPath, zipAppName); try { copyExe.ExecuteWithProgressWriter(context.Logger, context.Tracer, $"cp {createdZip} {copyToPath}"); } catch (Exception) { context.GlobalLogger.LogError(); throw; } // Gotta remove the old zips DeploymentHelper.PurgeOldDeploymentsIfNecessary(deploymentsPath, context.Tracer, totalAllowedDeployments: 10); File.WriteAllText(packageNameFile, zipAppName); File.WriteAllText(packagePathFile, artifactPath); }
private void SetupFunctionAppExpressArtifacts(DeploymentContext context) { string sitePackages = "/home/data/SitePackages"; string packageNameFile = Path.Combine(sitePackages, "packagename.txt"); string packagePathFile = Path.Combine(sitePackages, "packagepath.txt"); FileSystemHelpers.EnsureDirectory(sitePackages); string zipAppName = $"{DateTime.UtcNow.ToString("yyyyMMddHHmmss")}.zip"; string zipFile = Path.Combine(sitePackages, zipAppName); context.Logger.Log("Writing the artifacts to a zip file"); var exe = ExternalCommandFactory.BuildExternalCommandExecutable(OryxBuildConstants.FunctionAppBuildSettings.ExpressBuildSetup, sitePackages, context.Logger); try { exe.ExecuteWithProgressWriter(context.Logger, context.Tracer, $"zip -r {zipFile} .", String.Empty); } catch (Exception) { context.GlobalLogger.LogError(); throw; } // Just to be sure that we don't keep adding zip files here DeploymentHelper.PurgeZipsIfNecessary(sitePackages, context.Tracer, totalAllowedZips: 3); File.WriteAllText(packageNameFile, zipAppName); File.WriteAllText(packagePathFile, sitePackages); }
private void GenerateScript(DeploymentContext context, ILogger buildLogger) { try { using (context.Tracer.Step("Generating deployment script")) { var scriptGenerator = ExternalCommandFactory.BuildExternalCommandExecutable(RepositoryPath, context.OutputPath, buildLogger); // Set home path to the user profile so cache directories created by azure-cli are created there scriptGenerator.SetHomePath(System.Environment.GetEnvironmentVariable("APPDATA")); var scriptGeneratorCommandArguments = String.Format(ScriptGeneratorCommandArgumentsFormat, RepositoryPath, Environment.DeploymentToolsPath, ScriptGeneratorCommandArguments); var scriptGeneratorCommand = "\"{0}\" {1}".FormatInvariant(DeploymentScriptGeneratorToolPath, scriptGeneratorCommandArguments); bool cacheUsed = UseCachedDeploymentScript(scriptGeneratorCommandArguments, context); if (!cacheUsed) { buildLogger.Log(Resources.Log_DeploymentScriptGeneratorCommand, scriptGeneratorCommandArguments); scriptGenerator.ExecuteWithProgressWriter(buildLogger, context.Tracer, scriptGeneratorCommand); if (!OSDetector.IsOnWindows()) { // Kuduscript output is typically not given execute permission, so add it var deploymentScriptPath = DeploymentManager.GetCachedDeploymentScriptPath(Environment); PermissionHelper.Chmod("ugo+x", deploymentScriptPath, Environment, DeploymentSettings, buildLogger); } CacheDeploymentScript(scriptGeneratorCommandArguments, context); } else { buildLogger.Log(Resources.Log_DeploymentScriptGeneratorUsingCache, scriptGeneratorCommandArguments); } } } catch (Exception ex) { context.Tracer.TraceError(ex); // HACK: Log an empty error to the global logger (post receive hook console output). // The reason we don't log the real exception is because the 'live output' running // msbuild has already been captured. context.GlobalLogger.LogError(); throw; } }
protected void RunCommand(DeploymentContext context, string command) { ILogger customLogger = context.Logger.Log("Running deployment command..."); customLogger.Log("Command: " + command); // Creates an executable pointing to cmd and the working directory being // the repository root var exe = _externalCommandFactory.BuildExternalCommandExecutable(RepositoryPath, context.OutputPath, customLogger); exe.EnvironmentVariables[PreviousManifestPath] = context.PreviousManifestFilePath ?? String.Empty; exe.EnvironmentVariables[NextManifestPath] = context.NextManifestFilePath; // Create a directory for the script output temporary artifacts string buildTempPath = Path.Combine(Environment.TempPath, Guid.NewGuid().ToString()); FileSystemHelpers.EnsureDirectory(buildTempPath); exe.EnvironmentVariables[BuildTempPath] = buildTempPath; // Populate the enviornment with the build propeties foreach (var property in PropertyProvider.GetProperties()) { exe.EnvironmentVariables[property.Key] = property.Value; } try { exe.ExecuteWithProgressWriter(customLogger, context.Tracer, command, String.Empty); } catch (Exception ex) { context.Tracer.TraceError(ex); // HACK: Log an empty error to the global logger (post receive hook console output). // The reason we don't log the real exception is because the 'live output' running // msbuild has already been captured. context.GlobalLogger.LogError(); throw; } finally { // Clean the temp folder up CleanBuild(context.Tracer, buildTempPath); FileSystemHelpers.DeleteDirectorySafe(buildTempPath); } }
private void SetupAppServiceArtifacts(DeploymentContext context) { var tempArtifactDir = context.BuildTempPath; string framework = System.Environment.GetEnvironmentVariable(OryxBuildConstants.OryxEnvVars.FrameworkSetting); if (framework.StartsWith("DOTNETCORE", StringComparison.OrdinalIgnoreCase)) { tempArtifactDir = Path.Combine(context.BuildTempPath, "oryx-out"); } string sitePackages = "/home/data/SitePackages"; string deploymentsPath = $"/home/site/deployments/"; string artifactPath = $"/home/site/deployments/{context.CommitId}/artifact"; string packageNameFile = Path.Combine(sitePackages, "packagename.txt"); string packagePathFile = Path.Combine(sitePackages, "packagepath.txt"); FileSystemHelpers.EnsureDirectory(sitePackages); FileSystemHelpers.EnsureDirectory(artifactPath); string zipAppName = $"{DateTime.UtcNow.ToString("yyyyMMddHHmmss")}.zip"; string createdZip = PackageArtifactFromFolder(context, tempArtifactDir, tempArtifactDir, zipAppName, BuildArtifactType.Zip, numBuildArtifacts: -1); var copyExe = ExternalCommandFactory.BuildExternalCommandExecutable(tempArtifactDir, artifactPath, context.Logger); var copyToPath = Path.Combine(artifactPath, zipAppName); try { copyExe.ExecuteWithProgressWriter(context.Logger, context.Tracer, $"cp {createdZip} {copyToPath}"); } catch (Exception) { context.GlobalLogger.LogError(); throw; } // Gotta remove the old zips DeploymentHelper.PurgeOldDeploymentsIfNecessary(deploymentsPath, context.Tracer, totalAllowedDeployments: 10); File.WriteAllText(packageNameFile, zipAppName); File.WriteAllText(packagePathFile, artifactPath); }
/// <summary> /// Package every files and sub directories from a source folder /// </summary> /// <param name="context">The deployment context in current scope</param> /// <param name="srcDirectory">The source directory to be packed</param> /// <param name="artifactDirectory">The destination directory to eject the build artifact</param> /// <param name="artifactFilename">The filename of the build artifact</param> /// <param name="artifactType">The method for packing the artifact</param> /// <param name="numBuildArtifacts">The number of temporary artifacts should be hold in the destination directory</param> /// <returns></returns> private string PackageArtifactFromFolder(DeploymentContext context, string srcDirectory, string artifactDirectory, string artifactFilename, BuildArtifactType artifactType, int numBuildArtifacts = 0) { context.Logger.Log($"Writing the artifacts to a {artifactType.ToString()} file"); string file = Path.Combine(artifactDirectory, artifactFilename); var exe = ExternalCommandFactory.BuildExternalCommandExecutable(srcDirectory, artifactDirectory, context.Logger); try { switch (artifactType) { case BuildArtifactType.Zip: exe.ExecuteWithProgressWriter(context.Logger, context.Tracer, $"zip -r -0 -q {file} ."); break; case BuildArtifactType.Squashfs: exe.ExecuteWithProgressWriter(context.Logger, context.Tracer, $"mksquashfs . {file} -noappend"); break; default: throw new ArgumentException($"Received unknown file extension {artifactType.ToString()}"); } } catch (Exception) { context.GlobalLogger.LogError(); throw; } // Just to be sure that we don't keep adding build artifacts here if (numBuildArtifacts > 0) { DeploymentHelper.PurgeBuildArtifactsIfNecessary(artifactDirectory, artifactType, context.Tracer, numBuildArtifacts); } return(file); }
protected virtual IProcess CreateProcess(string connectionId, string shell) { var externalCommandFactory = new ExternalCommandFactory(_environment, _settings, _environment.RootPath); var exe = externalCommandFactory.BuildExternalCommandExecutable(_environment.RootPath, _environment.WebRootPath, NullLogger.Instance); var startInfo = new ProcessStartInfo() { UseShellExecute = false, CreateNoWindow = true, RedirectStandardError = true, RedirectStandardInput = true, RedirectStandardOutput = true, WorkingDirectory = _environment.RootPath }; if (shell.Equals("powershell", StringComparison.OrdinalIgnoreCase)) { startInfo.FileName = System.Environment.ExpandEnvironmentVariables(@"%windir%\System32\WindowsPowerShell\v1.0\powershell.exe"); startInfo.Arguments = "-File -"; } else { startInfo.FileName = System.Environment.ExpandEnvironmentVariables(@"%windir%\System32\cmd.exe"); startInfo.Arguments = "/Q"; } foreach (var environmentVariable in exe.EnvironmentVariables) { startInfo.EnvironmentVariables[environmentVariable.Key] = environmentVariable.Value; } // add '>' to distinguish PROMPT from other output startInfo.EnvironmentVariables["PROMPT"] = "$P$G"; // dir cmd would list folders then files alpabetically // consistent with FileBrowser ui. startInfo.EnvironmentVariables["DIRCMD"] = "/OG /ON"; var process = new Process { StartInfo = startInfo, EnableRaisingEvents = true }; process.Exited += delegate { SafeInvoke(() => { ProcessInfo temp; _processes.TryRemove(connectionId, out temp); Connection.Send(connectionId, new { Output = "\r\nprocess [" + process.Id + "] terminated! Press ENTER to start a new cmd process.\r\n", RunningProcessesCount = _processes.Count }).Wait(); }); }; process.Start(); EnsureIdleTimer(); HookProcessStreamsToConnection(process, connectionId); return new ProcessWrapper(process); }