예제 #1
0
        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();
            }
        }
예제 #2
0
        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();
            }
        }
예제 #3
0
        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);
            }
        }