Пример #1
0
        /// <summary>
        /// Creates a child log scope.
        /// </summary>
        /// <param name="scopeName">The child scope name.</param>
        /// <returns>Newly-created scope.</returns>
        public BackgroundLogScope CreateChildScope(string scopeName)
        {
            var now = DateTime.UtcNow;
            int scopeSequence;

            lock (this.syncLock)
            {
                if (this.completed.HasValue)
                {
                    throw new InvalidOperationException($"Log scope \"{this.Name}\" has alrady been completed.");
                }

                scopeSequence = this.ExecutionLogger.GetNextScopeSequence();
                var scope = new BackgroundLogScope(this.ExecutionLogger, scopeName ?? string.Empty, Task.Run(createScopeInternalAsync));
                this.childScopes.Add(scope);
                return(scope);
            }

            async Task <int?> createScopeInternalAsync()
            {
                int?parentScopeId = await this.ScopeId.ConfigureAwait(false);

                await RompDb.CreateLogScopeAsync(this.ExecutionId, scopeSequence, parentScopeId, scopeName ?? string.Empty, now);

                return(scopeSequence);
            }
        }
Пример #2
0
        public static PackageSpecifier FromArgs(ArgList args)
        {
            var packageName = args.PopCommand();

            if (string.IsNullOrEmpty(packageName))
            {
                return(null);
            }

            var inst = new PackageSpecifier();

            args.ProcessOptions(inst.ParseOption);

            // set source to default if not already specified
            if (inst.Source == null && !string.IsNullOrWhiteSpace(RompConfig.DefaultSource))
            {
                var match = RompDb.GetPackageSources()
                            .FirstOrDefault(s => string.Equals(s.Name, RompConfig.DefaultSource, StringComparison.OrdinalIgnoreCase));

                if (match != null)
                {
                    if (string.IsNullOrEmpty(match.UserName) || match.Password == null)
                    {
                        inst.Source = new UniversalFeedEndpoint(match.FeedUrl, true);
                    }
                    else
                    {
                        inst.Source = new UniversalFeedEndpoint(new Uri(match.FeedUrl), match.UserName, match.Password);
                    }
                }
            }


            if (packageName.EndsWith(".upack", StringComparison.OrdinalIgnoreCase))
            {
                if (inst.Source != null)
                {
                    throw new RompException("--source cannot be specified if <packageName> refers to a file.");
                }
                if (inst.PackageVersion != null)
                {
                    throw new RompException("--version cannot be specified if <packageName> refers to a file.");
                }

                inst.FileName = packageName;
            }
            else
            {
                try
                {
                    inst.PackageId = UniversalPackageId.Parse(packageName);
                }
                catch (Exception ex)
                {
                    throw new RompException("Invalid package name: " + packageName, ex);
                }
            }

            return(inst);
        }
Пример #3
0
        public async Task ExecuteAsync()
        {
            var startTime = DateTime.UtcNow;

            this.ExecutionId            = RompDb.CreateExecution(startTime, Domains.ExecutionStatus.Normal, Domains.ExecutionRunState.Executing, this.Simulation);
            this.DefaultExternalContext = new RompExecutionContext(this);

            this.Executer = new ExecuterThread(new AnonymousBlockStatement(this.plan), this);

            var result = ExecutionStatus.Error;

            try
            {
                await RompSessionVariable.ExpandValuesAsync(this.DefaultExternalContext);

                var targetDir = RompSessionVariable.GetSessionVariable(new RuntimeVariableName("TargetDirectory", RuntimeValueType.Scalar))?.GetValue().AsString();
                if (string.IsNullOrWhiteSpace(targetDir) || !PathEx.IsPathRooted(targetDir))
                {
                    this.Executer.RootLogScope.Log(LogLevel.Error, "Invalid value for $TargetDirectory.");
                    result = ExecutionStatus.Error;
                }
                else
                {
                    PackageInstaller.TargetDirectory = targetDir;
                    DirectoryEx.Create(targetDir);
                    result = await this.Executer.ExecuteAsync();
                }
            }
            catch (Exception ex)
            {
                if (!(ex is ExecutionFailureException))
                {
                    Logger.Log(MessageLevel.Error, "Unhandled exception in executer: " + ex.ToString());
                }

                result = ExecutionStatus.Error;
            }
            finally
            {
                try
                {
                    this.CleanTempDirectory();
                }
                catch
                {
                }

                await this.RootExecutionLog.CompleteAllAsync();

                RompDb.CompleteExecution(
                    executionId: this.ExecutionId.Value,
                    endDate: DateTime.UtcNow,
                    statusCode: result >= ExecutionStatus.Error ? Domains.ExecutionStatus.Error : result >= ExecutionStatus.Warning ? Domains.ExecutionStatus.Warning : Domains.ExecutionStatus.Normal
                    );
            }
        }
Пример #4
0
        private bool ParseOption(ArgOption o)
        {
            if (string.Equals("source", o.Key, StringComparison.OrdinalIgnoreCase))
            {
                if (string.IsNullOrWhiteSpace(o.Value))
                {
                    throw new RompException("Expected source name or URL after --source=");
                }

                if (o.Value.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || o.Value.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
                {
                    this.Source = new UniversalFeedEndpoint(o.Value, true);
                }
                else
                {
                    var source = RompDb.GetPackageSources()
                                 .FirstOrDefault(s => string.Equals(s.Name, o.Value, StringComparison.OrdinalIgnoreCase));

                    if (source == null)
                    {
                        throw new RompException($"Package source \"{o.Value}\" not found.");
                    }

                    if (string.IsNullOrEmpty(source.UserName) || source.Password == null)
                    {
                        this.Source = new UniversalFeedEndpoint(source.FeedUrl, true);
                    }
                    else
                    {
                        this.Source = new UniversalFeedEndpoint(new Uri(source.FeedUrl), source.UserName, source.Password);
                    }
                }

                return(true);
            }
            else if (string.Equals("version", o.Key, StringComparison.OrdinalIgnoreCase))
            {
                if (string.IsNullOrWhiteSpace(o.Value))
                {
                    throw new RompException("Expected package version after --version=");
                }

                try
                {
                    this.PackageVersion = UniversalPackageVersion.Parse(o.Value);
                }
                catch (Exception ex)
                {
                    throw new RompException("Invalid version: " + o.Value, ex);
                }

                return(true);
            }

            return(false);
        }
Пример #5
0
        /// <summary>
        /// Completes the log scope with the specified time.
        /// </summary>
        /// <param name="endTime">Log scope end time.</param>
        public Task CompleteScopeAsync(DateTime endTime)
        {
            lock (this.syncLock)
            {
                if (this.completeLogScopeTask != null)
                {
                    return(this.completeLogScopeTask);
                }

                this.completed            = endTime;
                this.completeLogScopeTask = innerCompleteAsync();
            }

            return(innerCompleteAsync());

            async Task innerCompleteAsync()
            {
                var tasks     = new List <Task>(this.childScopes.Count + 1);
                var writeTask = this.writeLogMessagesTask;

                if (writeTask != null)
                {
                    tasks.Add(writeTask);
                }

                if (this.childScopes.Count > 0)
                {
                    foreach (var s in this.childScopes)
                    {
                        tasks.Add(s.CompleteScopeAsync(endTime));
                    }
                }

                await Task.WhenAll(tasks).ConfigureAwait(false);

                foreach (var s in this.childScopes)
                {
                    if (s.maxLevel > this.maxLevel)
                    {
                        this.maxLevel = s.maxLevel;
                    }
                }

                await RompDb.CompleteLogScopeAsync(this.ExecutionId, this.ScopeId.Result.Value, endTime);
            }
        }
Пример #6
0
        private void MessagesWritten(Task task)
        {
            lock (this.syncLock)
            {
                if (this.entries.Count > 0)
                {
                    var entries   = this.entries;
                    var writeTask = Task.Run(() => RompDb.WriteLogMessagesAsync(this.ExecutionId, (int)this.ScopeId.Result, entries));

                    this.writeLogMessagesTask = writeTask.ContinueWith(this.MessagesWritten);
                    this.entries = new List <LogEntry>();
                }
                else
                {
                    this.writeLogMessagesTask = null;
                }
            }
        }
Пример #7
0
        public static ResourceCredentials TryGetCredentials(this IHasCredentials obj)
        {
            if (obj == null)
            {
                throw new ArgumentNullException(nameof(obj));
            }

            var name = CredentialName.TryParse(obj.CredentialName);

            if (name == null)
            {
                return(null);
            }

            var credentialInfo = RompDb.GetCredentialsByName(name.TypeName, name.Name);

            if (credentialInfo == null)
            {
                return(null);
            }

            return(Factory.CreateResourceCredentials(credentialInfo));
        }
Пример #8
0
        /// <summary>
        /// Posts a log message to be written to the database as soon as possible.
        /// </summary>
        /// <param name="level">The message level.</param>
        /// <param name="message">The message text.</param>
        public void WriteMessage(MessageLevel level, string message)
        {
            var now = DateTime.UtcNow;

            lock (this.syncLock)
            {
                if (this.completed.HasValue)
                {
                    throw new InvalidOperationException($"Log scope {this.Name} has already been completed.");
                }

                if (this.maxLevel < (int)level)
                {
                    this.maxLevel = (int)level;
                }

                // scope has not been created yet or waiting on messages to be written
                if (!this.ScopeId.IsCompleted || this.writeLogMessagesTask != null)
                {
                    this.entries.Add(new LogEntry(this.ExecutionLogger.GetNextLogEntrySequence(), level, message));
                    if (this.writeLogMessagesTask == null)
                    {
                        this.writeLogMessagesTask = this.ScopeId.ContinueWith(this.MessagesWritten);
                    }
                }
                // scope is created and nothing is being written
                else
                {
                    this.writeLogMessagesTask = Task.Run(() => RompDb.WriteLogMessagesAsync(
                                                             executionId: this.ExecutionId,
                                                             scopeSequence: this.ScopeId.Result.Value,
                                                             new[] { new LogEntry(this.ExecutionLogger.GetNextLogEntrySequence(), level, message) }
                                                             )).ContinueWith(this.MessagesWritten);
                }
            }
        }
Пример #9
0
        private static async Task RunPlanAsync(ScopedStatementBlock script, bool simulate)
        {
            if (simulate)
            {
                Console.WriteLine("Running as simulation");
            }

            Console.WriteLine();

            var executer = new RompExecutionEnvironment(script, simulate);

            if (!Console.IsOutputRedirected)
            {
                RompConsoleMessenger.ShowProgress = true;
                using (var done = new CancellationTokenSource())
                {
                    Task consoleTask = null;
                    try
                    {
                        consoleTask = Task.Run(() => RompConsoleMessenger.MonitorStatus(executer, done.Token));
                        await executer.ExecuteAsync();
                    }
                    finally
                    {
                        done.Cancel();
                        try
                        {
                            if (consoleTask != null)
                            {
                                await consoleTask;
                            }
                        }
                        catch
                        {
                        }
                    }
                }
            }
            else
            {
                RompConsoleMessenger.ShowProgress = false;
                await executer.ExecuteAsync();
            }

            var exec = RompDb.GetExecutions()
                       .FirstOrDefault(e => e.ExecutionId == executer.ExecutionId);

            if (exec != null)
            {
                var logs = RompDb.GetExecutionLogs(exec.ExecutionId);
                foreach (var log in logs)
                {
                    log.WriteErrors(Console.Out);
                }

                if (exec.StatusCode == Domains.ExecutionStatus.Normal)
                {
                    RompConsoleMessenger.WriteDirect($"Job #{executer.ExecutionId} completed successfully.", ConsoleColor.White);
                }
                else if (exec.StatusCode == Domains.ExecutionStatus.Warning)
                {
                    RompConsoleMessenger.WriteDirect($"Job #{executer.ExecutionId} completed with warnings.", ConsoleColor.Yellow);
                }
                else
                {
                    RompConsoleMessenger.WriteDirect($"Job #{executer.ExecutionId} encountered an error.", ConsoleColor.Red);
                    throw new RompException("Job execution failed.");
                }

                Console.WriteLine();
            }
            else
            {
                throw new RompException("Execution could not be created.");
            }
        }
Пример #10
0
 public override IEnumerable <SDK.CredentialsInfo> GetCredentials() => RompDb.GetCredentials().Select(c => new SDK.CredentialsInfo(c.CredentialType_Name, c.Credential_Name, c.Configuration_Xml, null, null));
Пример #11
0
        private async Task <int?> CreateRootScopeAsync(int sequence)
        {
            await Task.Run(() => RompDb.CreateLogScopeAsync(this.ExecutionId, sequence, null, string.Empty, DateTime.UtcNow));

            return(sequence);
        }
Пример #12
0
        private static void Credentials(ArgList args)
        {
            var command = args.PopCommand()?.ToLowerInvariant();

            switch (command)
            {
            case "list":
                list();
                break;

            case "display":
                display();
                break;

            case "store":
                store();
                break;

            case "delete":
                delete();
                break;

            default:
                Console.WriteLine("Usage:");
                Console.WriteLine("romp credentials list");
                Console.WriteLine("romp credentials display <name> [--show-hidden]");
                Console.WriteLine("romp credentials store <name>");
                Console.WriteLine("romp credentials delete <name>");
                break;
            }

            void list()
            {
                foreach (var c in RompDb.GetCredentials())
                {
                    Console.WriteLine(c.CredentialType_Name + "::" + c.Credential_Name);
                }
            }

            void display()
            {
                var(type, name) = parseQualifiedName();
                var creds = RompDb.GetCredentialsByName(type, name);

                if (creds == null)
                {
                    throw new RompException($"Credentials {type}::{name} not found.");
                }

                bool showHidden = false;

                args.ProcessOptions(
                    o =>
                {
                    if (string.Equals(o.Key, "show-hidden", StringComparison.OrdinalIgnoreCase))
                    {
                        showHidden = true;
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
                    );

                args.ThrowIfAnyRemaining();

                var instance = (ResourceCredentials)Persistence.DeserializeFromPersistedObjectXml(creds.Configuration_Xml);

                Console.WriteLine($"Name: {creds.CredentialType_Name}::{creds.Credential_Name}");

                foreach (var prop in Persistence.GetPersistentProperties(instance.GetType(), false))
                {
                    var alias = prop.GetCustomAttribute <ScriptAliasAttribute>()?.Alias;
                    if (alias != null) // only show items with ScriptAlias
                    {
                        var  propName = prop.GetCustomAttribute <DisplayNameAttribute>()?.DisplayName ?? alias;
                        bool hidden   = prop.GetCustomAttribute <PersistentAttribute>().Encrypted;

                        var value = prop.GetValue(instance);
                        if (value is SecureString secure)
                        {
                            value = AH.Unprotect(secure);
                        }

                        if (hidden && !showHidden)
                        {
                            value = "(hidden)";
                        }
                        if (value == null)
                        {
                            value = "(not specified)";
                        }

                        Console.WriteLine(propName + ": " + value);
                    }
                }
            }

            void store()
            {
                var n    = parseQualifiedName();
                var type = (from c in ExtensionsManager.GetComponentsByBaseClass <ResourceCredentials>()
                            let a = c.ComponentType.GetCustomAttribute <ScriptAliasAttribute>()
                                    where string.Equals(a?.Alias, n.type, StringComparison.OrdinalIgnoreCase) || string.Equals(c.ComponentType.Name, n.type, StringComparison.OrdinalIgnoreCase)
                                    orderby string.Equals(a?.Alias, n.type, StringComparison.OrdinalIgnoreCase) descending
                                    select c.ComponentType).FirstOrDefault();

                if (type == null)
                {
                    throw new RompException($"Unknown credentials type \"{n.type}\". Are you missing an extension?");
                }

                var credentials = (ResourceCredentials)Activator.CreateInstance(type);

                if (!Console.IsInputRedirected)
                {
                    foreach (var property in Persistence.GetPersistentProperties(type, true))
                    {
Again:
                        Console.Write((property.GetCustomAttribute <DisplayNameAttribute>()?.DisplayName ?? property.Name) + ": ");
                        string value;
                        if (property.GetCustomAttribute <PersistentAttribute>()?.Encrypted == true || property.PropertyType == typeof(SecureString))
                        {
                            value = ReadSensitive();
                        }
                        else
                        {
                            value = Console.ReadLine();
                        }

                        if (!string.IsNullOrEmpty(value))
                        {
                            if (property.PropertyType == typeof(string))
                            {
                                property.SetValue(credentials, value);
                            }
                            else if (property.PropertyType == typeof(SecureString))
                            {
                                property.SetValue(credentials, AH.CreateSecureString(value));
                            }
                            else
                            {
                                try
                                {
                                    var convertedValue = Convert.ChangeType(value, Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType);
                                    property.SetValue(credentials, convertedValue);
                                }
                                catch (Exception ex)
                                {
                                    Console.Error.WriteLine("Invalid value: " + ex.Message);
                                    goto Again;
                                }
                            }
                        }
                    }
                }
                else
                {
                    throw new RompException("Credentials must be stored interactively.");
                }

                RompDb.CreateOrUpdateCredentials(n.name, credentials, true);
                Console.WriteLine("Credentials stored.");
            }

            void delete()
            {
                var(type, name) = parseQualifiedName();
                RompDb.DeleteCredentials(type, name);
                Console.WriteLine("Credentials deleted.");
            }

            (string type, string name) parseQualifiedName()
            {
                var qualifiedName = args.PopCommand();

                if (string.IsNullOrEmpty(qualifiedName))
                {
                    throw new RompException("Expected credentials name.");
                }

                var parts = qualifiedName.Split(new[] { "::" }, StringSplitOptions.None);

                if (parts.Length != 2 || string.IsNullOrWhiteSpace(parts[0]) || string.IsNullOrWhiteSpace(parts[1]))
                {
                    throw new RompException("Invalid credentials name specification.");
                }

                return(parts[0], parts[1]);
            }
        }
Пример #13
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();
            }
        }
Пример #14
0
        private static void Sources(ArgList args)
        {
            var command = args.PopCommand()?.ToLowerInvariant();

            switch (command)
            {
            case "list":
                list();
                break;

            case "display":
                display();
                break;

            case "create":
                create();
                break;

            case "delete":
                delete();
                break;

            case "default":
                defaultCommand();
                break;

            default:
                Console.WriteLine("Usage:");
                Console.WriteLine("romp sources list");
                Console.WriteLine("romp sources display <name> [--show-hidden]");
                Console.WriteLine("romp sources create <name> <url>");
                Console.WriteLine("romp sources delete <name>");
                break;
            }

            void list()
            {
                bool any = false;

                Console.WriteLine("Package sources:");

                foreach (var s in RompDb.GetPackageSources())
                {
                    any = true;
                    var url = s.FeedUrl;
                    if (!string.IsNullOrEmpty(s.UserName))
                    {
                        url = s.UserName + "@" + url;
                    }
                    Console.WriteLine(" " + s.Name + ": " + url);
                }

                if (!any)
                {
                    Console.WriteLine(" (none)");
                }
            }

            void display()
            {
                var name = args.PopCommand();

                if (string.IsNullOrEmpty(name))
                {
                    throw new RompException("Expected source name.");
                }

                var source = RompDb.GetPackageSources()
                             .FirstOrDefault(s => string.Equals(s.Name, name, StringComparison.OrdinalIgnoreCase));

                if (source == null)
                {
                    throw new RompException($"Source {name} not found.");
                }

                bool showHidden = false;

                args.ProcessOptions(
                    o =>
                {
                    if (string.Equals(o.Key, "show-hidden", StringComparison.OrdinalIgnoreCase))
                    {
                        showHidden = true;
                        return(true);
                    }
                    else
                    {
                        return(false);
                    }
                }
                    );

                args.ThrowIfAnyRemaining();

                Console.WriteLine("Name: " + source.Name);
                Console.WriteLine("Url: " + source.FeedUrl);
                Console.WriteLine("User: "******"(not specified)");
                if (showHidden)
                {
                    Console.WriteLine("Password: "******"(not specified)");
                }
            }

            void create()
            {
                var name = args.PopCommand();
                var url  = args.PopCommand();

                if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(url))
                {
                    throw new RompException("Usage: romp sources create <name> <url>");
                }

                Uri uri;

                try
                {
                    uri = new Uri(url);
                }
                catch (Exception ex)
                {
                    throw new RompException("Invalid URL: " + ex.Message, ex);
                }

                string       userName = null;
                SecureString password = null;

                if (!string.IsNullOrEmpty(uri.UserInfo))
                {
                    var parts = uri.UserInfo.Split(new[] { ':' }, 2);
                    userName = parts[0];
                    password = AH.CreateSecureString(parts.Length > 1 ? parts[1] : string.Empty);
                }

                var sanitizedUrl = new UriBuilder(uri)
                {
                    UserName = null,
                    Password = null
                };

                RompDb.CreateOrUpdatePackageSource(name, sanitizedUrl.ToString(), userName, password);
                Console.WriteLine("Package source stored.");
            }

            void delete()
            {
                var name = args.PopCommand();

                if (string.IsNullOrEmpty(name))
                {
                    throw new RompException("Expected source name.");
                }

                RompDb.DeletePackageSource(name);
                Console.WriteLine("Package source deleted.");

                if (string.Equals(RompConfig.DefaultSource, name, StringComparison.OrdinalIgnoreCase))
                {
                    RompConfig.DeleteValue("default-source");
                }
            }

            void defaultCommand()
            {
                var name = args.PopCommand();

                if (string.IsNullOrEmpty(name))
                {
                    throw new RompException("Expected source name.");
                }

                if (!RompDb.GetPackageSources().Any(s => string.Equals(s.Name, name, StringComparison.OrdinalIgnoreCase)))
                {
                    throw new RompException($"No source named {name} has been configured.");
                }

                RompConfig.SetValue("default-source", name);
                Console.WriteLine($"Default source set to {name}.");
            }
        }
Пример #15
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();
            }
        }
Пример #16
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);
            }
        }