private static void executeCopy(string[] args) { var nArgs = CLIHelper.GetNamedArguments(args); switch (args[1]?.ToLower()) { case "local": { var config = nArgs["config"].ToFileInfo(); Console.WriteLine($"Local Copy Execution according to '{config.FullName}'."); var configs = config.DeserialiseJson <CopyConfig[]>(); foreach (var cfg in configs) { string src, dst; if (!RuntimeEx.IsWindows()) { Console.WriteLine($"Detected OS is NOT Windows, paths containing '\\' and ':' will be replaced with '/'"); src = cfg.Source.ToLinuxPath(); dst = cfg.Destination.ToLinuxPath(); } else { src = cfg.Source; dst = cfg.Destination; } if (src.IsFile()) { Console.WriteLine($"Detected, that Source is a FILE"); var srcInfo = src.ToFileInfo(); var dstInfo = dst.ToFileInfo(); if (!srcInfo.Exists) { throw new Exception($"Source file: '{srcInfo.FullName}' does not exit."); } if (!dstInfo.Directory.Exists) { Console.WriteLine($"Destination directory '{dstInfo.Directory.FullName}' does not exist, creating..."); dstInfo.Directory.Create(); } Console.WriteLine($"Copying Files '{srcInfo.FullName}' => '{dstInfo.FullName}' (Override: {cfg.Override})."); srcInfo.Copy(dstInfo, cfg.Override); } else if (src.IsDirectory()) { Console.WriteLine($"Detected, that Source is a DIRECTORY"); var srcInfo = src.ToDirectoryInfo(); var dstInfo = dst.ToDirectoryInfo(); if (!srcInfo.Exists) { throw new Exception($"Source directory: '{srcInfo.FullName}' does not exit."); } if (!dstInfo.Exists) { Console.WriteLine($"Destination directory '{dstInfo.FullName}' does not exist, creating..."); dstInfo.Create(); } if (!dst.IsDirectory()) { throw new Exception("If source is a directory then destination also must be a directory."); } Console.WriteLine($"Recursive Copy: '{cfg.Recursive}'"); foreach (string newPath in Directory.GetFiles(srcInfo.FullName, "*.*", cfg.Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { Console.WriteLine($"Copying Files '{srcInfo.FullName}' => '{dstInfo.FullName}' (Override: {cfg.Override})."); File.Copy(newPath, newPath.Replace(srcInfo.FullName, dstInfo.FullName), cfg.Override); } } else { throw new Exception($"Source '{src}' is neither a file or a directory."); } } } ; break; case "help": case "--help": case "-help": case "-h": case "h": HelpPrinter($"{args[0]}", "Copy", ("local", "Accepts params: config, override")); break; default: { Console.WriteLine($"Try '{args[0]} help' to find out list of available commands."); throw new Exception($"Unknown Copy command: '{args[0]} {args[1]}'"); } } }
private static async Task <bool> executeScheduler(string[] args) { var nArgs = CLIHelper.GetNamedArguments(args); switch (args[1]?.ToLower()) { case "github": { if (Environment.GetEnvironmentVariable("test_connection").ToBoolOrDefault(false)) { Console.WriteLine($"Your Internet Connection is {(SilyWebClientEx.CheckInternetAccess(timeout: 5000) ? "" : "NOT")} available."); } var userWhitelist = nArgs.GetValueOrDefault("users")?.Split(','); var repositoriesWhitelist = nArgs.GetValueOrDefault("repositories")?.Split(','); Console.WriteLine($"Fetching scheduler info."); var workingDirectory = (await GetVariableByKey("working_directory", nArgs: nArgs)).ToDirectoryInfo(); var githubSchedule = await GetVariableByKey("github_schedule", nArgs : nArgs); var user = GITWrapper.GitHubHelperEx.GetUserFromUrl(githubSchedule); if (!userWhitelist.IsNullOrEmpty() && !userWhitelist.Any(x => x == user)) { throw new Exception($"User was specified but, user '{user ?? "undefined"}' was not present among whitelisted users: {userWhitelist.JsonSerialize()}"); } var accessToken = await GetSecretHexToken("github_token", nArgs); var repo = GITWrapper.GitHubHelperEx.GetRepoFromUrl(githubSchedule); if (!repositoriesWhitelist.IsNullOrEmpty() && !repositoriesWhitelist.Any(x => x == user)) { throw new Exception($"Repository was specified but, repo '{repo ?? "undefined"}' was not present among whitelisted repositories: {repositoriesWhitelist.JsonSerialize()}"); } var branch = GITWrapper.GitHubHelperEx.GetBranchFromUrl(githubSchedule); var scheduleLocation = GITWrapper.GitHubHelperEx.GetFileFromUrl(githubSchedule); var git = new GITWrapper.GitHubHelper(new GITWrapper.Models.GitHubRepoConfig() { accessToken = accessToken, user = user, repository = repo, branch = branch }); var contentDirectory = PathEx.RuntimeCombine(workingDirectory.FullName, repo).ToDirectoryInfo(); var statusDirectory = PathEx.RuntimeCombine(workingDirectory.FullName, "status").ToDirectoryInfo(); var logsDirectory = PathEx.RuntimeCombine(workingDirectory.FullName, "logs").ToDirectoryInfo(); var scheduleFileInfo = PathEx.RuntimeCombine(contentDirectory.FullName, scheduleLocation).ToFileInfo(); contentDirectory.TryDelete(recursive: true, exception: out var contentDirectoryException); Console.WriteLine($"Removing git directory '{contentDirectory.FullName}' {(contentDirectory.Exists ? $"did NOT suceeded, error: {contentDirectoryException.JsonSerializeAsPrettyException()}" : "succeded")}."); statusDirectory.TryCreate(); CommandOutput result; var pullCommand = $"git clone https://{accessToken}@github.com/{user}/{repo}.git --branch {branch}"; result = CLIHelper.Console(pullCommand, workingDirectory: workingDirectory.FullName); Console.WriteLine(result.JsonSerialize()); var gitDirectory = PathEx.RuntimeCombine(contentDirectory.FullName, ".git").ToDirectoryInfo(); gitDirectory.TryDelete(recursive: true); Console.WriteLine($"Removing git directory '{gitDirectory.FullName}' {(gitDirectory.Exists ? "did NOT" : "")} succeded."); if (!RuntimeEx.IsWindows()) { result = CLIHelper.Console($"chmod 777 -R ./{repo}", workingDirectory: workingDirectory.FullName); Console.WriteLine(result.JsonSerialize()); } if (!scheduleFileInfo.Exists) { Console.WriteLine($"FAILURE, schedule file '{scheduleFileInfo.FullName}' does not exist or was not defined."); return(false); } var deploymentConfig = scheduleFileInfo.DeserialiseJson <DeploymentConfig>(); var deploymentConfigOld = deploymentConfig.LoadDeploymentConfig(statusDirectory); if (deploymentConfig?.enable != true || deploymentConfig.schedules.IsNullOrEmpty()) { Console.WriteLine($"Deployment config '{scheduleFileInfo.FullName}' was not enabled or schedules were not defined."); return(false); } //Defines if schedule executuions should be triggered var masterTrigger = deploymentConfig.IsTriggered(deploymentConfigOld); var serialSchedules = deploymentConfig.schedules .Where(x => !(x?.id).IsNullOrEmpty() && x.parallelizable == false) ?.OrderBy(x => x.priority)?.DistinctBy(x => x.id)?.ToArray(); var parallelSchedules = deploymentConfig.schedules .Where(x => !(x?.id).IsNullOrEmpty() && x.parallelizable == true) ?.OrderBy(x => x.priority)?.DistinctBy(x => x.id)?.ToArray(); var breakAll = false; async Task TryCatchExecute(ExecutionSchedule s) { var sOld = s.LoadExecutionSchedule(statusDirectory); if (s == null || sOld == null) { Console.WriteLine($"New or old schedule could not be found."); return; } if (!s.IsTriggered(sOld, masterTrigger)) { Console.WriteLine($"WARNING, schedule '{s?.id ?? "undefined"}' execution was not triggered."); return; } Console.WriteLine($"Processing executioon schedule '{s.id}', parralelized: {s.parallelizable}, cron: {s.cron ?? "null"}, trigger: {s.trigger}/{sOld.trigger}."); if (s.delay > 0) { await Task.Delay(s.delay); } if (_debug) { Console.WriteLine($"WARNING! github schedule will be processed in DEBUG mode"); await ProcessSchedule(s, sOld, contentDirectory, statusDirectory, logsDirectory, masterTrigger : masterTrigger); return; } try { await ProcessSchedule(s, sOld, contentDirectory, statusDirectory, logsDirectory, masterTrigger : masterTrigger); breakAll = s.breakAllOnFinalize; if (s.sleep > 0) { await Task.Delay(s.sleep); } } catch (Exception ex) { try { if (deploymentConfig.throwOnFailure == true) { if (deploymentConfig.finalizeOnFailure) { deploymentConfig.UpdateDeploymentConfig(statusDirectory); breakAll = s.breakAllOnFinalize; } throw; } Console.WriteLine($"FAILED! execution of schedule '{s.id}', parralelized: {s.parallelizable}, error: {ex.JsonSerializeAsPrettyException()}."); } finally { var logPath = PathEx.Combine(logsDirectory.FullName, $"{s.GetFileSafeId() ?? "tmp.log"}.log").ToFileInfo(); if (logPath.TryCreate()) { logPath.AppendAllText(ex.JsonSerializeAsPrettyException()); } } } } if (deploymentConfig.delay > 0) { await Task.Delay(deploymentConfig.delay); } var sum = 0; if (!serialSchedules.IsNullOrEmpty()) { sum += serialSchedules.Length; foreach (var s in serialSchedules) { await TryCatchExecute(s); } } if (!parallelSchedules.IsNullOrEmpty()) { sum += serialSchedules.Length; await ParallelEx.ForEachAsync(parallelSchedules, s => TryCatchExecute(s), maxDegreeOfParallelism : parallelSchedules.Count()); } deploymentConfig.UpdateDeploymentConfig(statusDirectory); Console.WriteLine($"SUCCESS, {sum} github schedule/s was/were executed out of {deploymentConfig.schedules.Length}."); if (deploymentConfig.sleep > 0) { await Task.Delay(deploymentConfig.sleep); } return(true); } case "help": case "--help": case "-help": case "-h": case "h": { HelpPrinter($"{args[0]}", "Command Deployment", ("github", "Accepts params: working_directory, github_schedule, github_token")); return(true); } default: { Console.WriteLine($"Try '{args[0]} help' to find out list of available commands."); throw new Exception($"Unknown String command: '{args[0]} {args[1]}'"); } } }