public static async Task <int> Main(string[] args) { try { RompConsoleMessenger.WriteDirect("romp " + typeof(Program).Assembly.GetName().Version.ToString(3), ConsoleColor.White); var argList = new ArgList(args); RompConfig.Initialize(argList); RompSdkConfig.Initialize(); // this is a hack due to the weird way the extensions manager works Directory.CreateDirectory(RompConfig.ExtensionsPath); ExtensionsManager.SetEnvironmentConfiguration(RompConfig.ExtensionsPath, RompConfig.ExtensionsTempPath, AppDomain.CurrentDomain.BaseDirectory); RompDb.Initialize(); GlobalRompPlanValidator.Initialize(); Logger.AddMessenger(new RompConsoleMessenger()); RompConsoleMessenger.MinimumLevel = RompConfig.LogLevel; var command = argList.PopCommand()?.ToLowerInvariant(); switch (command) { case "install": await Install(argList); break; case "uninstall": await Uninstall(argList); break; case "validate": Validate(argList); break; case "inspect": await Inspect(argList); break; case "pack": Pack(argList); break; case "sources": Sources(argList); break; case "jobs": Jobs(argList); break; case "credentials": Credentials(argList); break; case "config": Config(argList); break; case "packages": await Packages(argList); break; case "about": About(argList); break; default: WriteUsage(); break; } WaitForEnter(); return(0); } catch (RompException ex) { Console.Error.WriteLine(ex.Message); WaitForEnter(); return(-1); } finally { RompDb.Cleanup(); } }
private static void Jobs(ArgList args) { var command = args.PopCommand()?.ToLowerInvariant(); switch (command) { case "list": list(); break; case "logs": logs(); break; case "purge": purge(); break; default: Console.WriteLine("Usage:"); Console.WriteLine("romp jobs list"); Console.WriteLine("romp jobs logs [jobId]"); Console.WriteLine("romp jobs purge <days>"); break; } void list() { args.ThrowIfAnyRemaining(); var jobs = RompDb.GetExecutions() .OrderByDescending(j => j.StartDate); Console.WriteLine("Jobs:"); bool any = false; foreach (var job in jobs) { any = true; var text = $" {job.ExecutionId} {job.StartDate.LocalDateTime} {Domains.ExecutionStatus.GetName(job.StatusCode)}"; if (job.StatusCode == Domains.ExecutionStatus.Error) { RompConsoleMessenger.WriteDirect(text, ConsoleColor.Red); } else if (job.StatusCode == Domains.ExecutionStatus.Warning) { RompConsoleMessenger.WriteDirect(text, ConsoleColor.Yellow); } else { RompConsoleMessenger.WriteDirect(text); } } if (!any) { Console.WriteLine(" (none)"); } } void logs() { int?jobId = null; var jobIdText = args.PopCommand(); if (!string.IsNullOrEmpty(jobIdText)) { jobId = AH.ParseInt(jobIdText); if (jobId == null) { throw new RompException("Invalid job ID."); } } args.ThrowIfAnyRemaining(); if (jobId == null) { var latest = RompDb.GetExecutions().OrderByDescending(j => j.ExecutionId).FirstOrDefault(); jobId = latest?.ExecutionId; } if (jobId != null) { foreach (var log in RompDb.GetExecutionLogs(jobId.Value)) { log.WriteText(0, Console.Out); } } } void purge() { var daysText = args.PopCommand(); if (string.IsNullOrEmpty(daysText)) { throw new RompException("Usage: romp logs purge <days>"); } if (!int.TryParse(daysText, out int days) || days < 0) { throw new RompException("Must specify a nonnegative integer for \"days\" argument."); } var now = DateTimeOffset.Now; var executions = RompDb.GetExecutions() .Where(e => (int)now.Subtract(e.StartDate).TotalDays >= days) .ToList(); Console.WriteLine($"Purging logs for jobs older than {days} days."); foreach (var exec in executions) { Console.WriteLine($"Purging job #{exec.ExecutionId} ({exec.StartDate.LocalDateTime})..."); RompDb.DeleteExecution(exec.ExecutionId); } Console.WriteLine($"Purged {executions.Count} jobs."); Console.WriteLine(); } }
private static async Task Install(ArgList args) { var spec = PackageSpecifier.FromArgs(args); if (spec == null) { throw new RompException("Usage: romp install <package-file-or-name> [--version=<version-number>] [--source=<name-or-feed-url>] [--force] [-Vvar=value...]"); } Console.WriteLine("Package: " + spec); Console.WriteLine(); await ExtensionsManager.WaitForInitializationAsync(); bool simulate = false; bool force = false; var vars = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); using (var package = await spec.FetchPackageAsync(args, default)) { args.ProcessOptions(parseOption); if (!force) { var registeredPackage = await GetRegisteredPackageAsync(spec.PackageId); if (registeredPackage != null) { Console.WriteLine("Package is already installed. Use --force to install anyway."); return; } } foreach (var var in vars) { RompSessionVariable.SetSessionVariable(var.Key, var.Value); } var packageInfo = RompPackInfo.Load(package); if (packageInfo.WriteScriptErrors()) { throw new RompException("Error compiling install script."); } foreach (var var in packageInfo.Variables) { if (var.Value.Value != null && !vars.ContainsKey(var.Key)) { RompSessionVariable.SetSessionVariable(var.Key, var.Value.Value.Value); } } foreach (var var in packageInfo.Variables) { // should also validate/coerce type here if (var.Value.Required && var.Value.Value == null && !vars.ContainsKey(var.Key)) { if (Console.IsOutputRedirected) { throw new RompException("Missing required variable: " + var.Key); } Console.WriteLine($"Variable \"{var.Key}\" is required."); if (!string.IsNullOrWhiteSpace(var.Value.Description)) { Console.WriteLine("Description: " + var.Value.Description); } string value; do { // should not assume type to be scalar Console.Write(new RuntimeVariableName(var.Key, RuntimeValueType.Scalar) + ": "); if (var.Value.Sensitive) { value = ReadSensitive(); } else { value = Console.ReadLine(); } }while (string.IsNullOrEmpty(value)); RompSessionVariable.SetSessionVariable(var.Key, value); } } bool credentialsMissing = false; foreach (var creds in packageInfo.Credentials.Values) { if (RompDb.GetCredentialsByName(creds.Type, creds.Name) == null) { credentialsMissing = true; var text = "Credentials required: " + creds.FullName; if (!string.IsNullOrWhiteSpace(creds.Description)) { text += " (" + creds.Description + ")"; } RompConsoleMessenger.WriteDirect(text, ConsoleColor.Red); } } if (credentialsMissing) { throw new RompException("Use \"romp credentials store\" to create missing credentials."); } await PackageInstaller.RunAsync(package, "install.otter", simulate); using (var registry = PackageRegistry.GetRegistry(RompConfig.UserMode)) { await registry.LockAsync(); await registry.RegisterPackageAsync( new RegisteredPackage { Group = package.Group, Name = package.Name, Version = package.Version.ToString(), InstallationDate = DateTimeOffset.Now.ToString("o"), InstalledBy = Environment.UserName, InstalledUsing = "Romp", InstallPath = PackageInstaller.TargetDirectory } ); await registry.UnlockAsync(); } } bool parseOption(ArgOption o) { switch (o.Key.ToLowerInvariant()) { case "force": force = true; return(true); } if (o.Key.StartsWith("V") && o.Key.Length > 1) { vars[o.Key.Substring(1)] = o.Value ?? string.Empty; return(true); } return(false); } }