Example #1
0
        public TrackingConfigBase LoadIfExists(IExecutionContext executionContext, string file)
        {
            Trace.Entering();

            // The tracking config will not exist for a new definition.
            if (!File.Exists(file))
            {
                return null;
            }

            // Load the content and distinguish between tracking config file
            // version 1 and file version 2.
            string content = File.ReadAllText(file);
            string fileFormatVersionJsonProperty = StringUtil.Format(
                @"""{0}""",
                TrackingConfig.FileFormatVersionJsonProperty);
            if (content.Contains(fileFormatVersionJsonProperty))
            {
                // The config is the new format.
                Trace.Verbose("Parsing new tracking config format.");
                return JsonConvert.DeserializeObject<TrackingConfig>(content);
            }

            // Attempt to parse the legacy format.
            Trace.Verbose("Parsing legacy tracking config format.");
            LegacyTrackingConfig config = LegacyTrackingConfig.TryParse(content);
            if (config == null)
            {
                executionContext.Warning(StringUtil.Loc("UnableToParseBuildTrackingConfig0", content));
            }

            return config;
        }
Example #2
0
        public override CommandResultCode Execute(IExecutionContext context, CommandArguments args)
        {
            if (!args.MoveNext()) {
                ProductInfo product = ProductInfo.Current;
                StringWriter writer = new StringWriter();
                writer.WriteLine("---------------------------------------------------------------------------");
                writer.WriteLine(" {0} {1} {2}", product.Title, product.Version, product.Copyright);
                writer.WriteLine();
                writer.WriteLine(" CloudB Admin is provided AS IS and comes with ABSOLUTELY NO WARRANTY");
                writer.WriteLine(" This is free software, and you are welcome to redistribute it under the");
                writer.WriteLine(" conditions of the Lesser GNU Public License.");
                writer.WriteLine("---------------------------------------------------------------------------");
                Out.Write(writer.ToString());
                return CommandResultCode.Success;
            }

            if (args.Current == "version") {
                //TODO:
            } else if (args.Current == "license") {
                Out.WriteLine("Lesser GNU Public License <http://www.gnu.org/licenses/lgpl.txt>");
                return CommandResultCode.Success;
            }

            return CommandResultCode.SyntaxError;
        }
Example #3
0
        public override IEnumerable<IDocument> Execute(IReadOnlyList<IDocument> inputs, IExecutionContext context)
        {
            ImmutableArray<IDocument> commitDocuments = GetCommitDocuments(inputs, context);

            // Outputting commits as new documents
            if (string.IsNullOrEmpty(_commitsMetadataKey))
            {
                return commitDocuments;
            }
            var test = commitDocuments.Select(x => x.Get<IReadOnlyDictionary<string, string>>(GitKeys.Entries));

            // Outputting commit information for each document
            string repositoryLocation = GetRepositoryLocation(context);
            return inputs.AsParallel().Select(input =>
            {
                if (string.IsNullOrEmpty(input.Source))
                {
                    return input;
                }
                string relativePath = PathHelper.GetRelativePath(repositoryLocation, input.Source);
                if (string.IsNullOrEmpty(relativePath))
                {
                    return input;
                }
                ImmutableArray<IDocument> inputCommitDocuments = commitDocuments
                    .Where(x => x.Get<IReadOnlyDictionary<string, string>>(GitKeys.Entries).ContainsKey(relativePath))
                    .ToImmutableArray();
                return context.GetDocument(input, new MetadataItems
                {
                    new MetadataItem(_commitsMetadataKey, inputCommitDocuments)
                });
            });
        }
Example #4
0
        public override CommandResultCode Execute(IExecutionContext context, CommandArguments args)
        {
            ISettingsHandler handler = Application as ISettingsHandler;
            if (handler == null) {
                Error.WriteLine("The application doesn't support settings.");
                return CommandResultCode.ExecutionFailed;
            }

            if (args.MoveNext())
                return CommandResultCode.SyntaxError;

            VarColumns[0].ResetWidth();
            VarColumns[1].ResetWidth();

            TableRenderer table = new TableRenderer(VarColumns, Out);
            table.EnableHeader = true;
            table.EnableFooter = true;
            foreach(KeyValuePair<string, string> setting in handler.Settings) {
                if (setting.Key == ApplicationSettings.SpecialLastCommand)
                    continue;

                ColumnValue[] row = new ColumnValue[4];
                row[0] = new ColumnValue(setting.Key);
                row[1] = new ColumnValue(setting.Value);
                table.AddRow(row);
            }

            table.CloseTable();
            Error.WriteLine();

            return CommandResultCode.Success;
        }
Example #5
0
        public string GetBuildDirectoryHashKey(IExecutionContext executionContext, ServiceEndpoint endpoint)
        {
            // Validate parameters.
            Trace.Entering();
            ArgUtil.NotNull(executionContext, nameof(executionContext));
            ArgUtil.NotNull(executionContext.Variables, nameof(executionContext.Variables));
            ArgUtil.NotNull(endpoint, nameof(endpoint));
            ArgUtil.NotNull(endpoint.Url, nameof(endpoint.Url));

            // Calculate the hash key.
            const string Format = "{{{{ \r\n    \"system\" : \"build\", \r\n    \"collectionId\" = \"{0}\", \r\n    \"definitionId\" = \"{1}\", \r\n    \"repositoryUrl\" = \"{2}\", \r\n    \"sourceFolder\" = \"{{0}}\",\r\n    \"hashKey\" = \"{{1}}\"\r\n}}}}";
            string hashInput = string.Format(
                CultureInfo.InvariantCulture,
                Format,
                executionContext.Variables.System_CollectionId,
                executionContext.Variables.System_DefinitionId,
                endpoint.Url.AbsoluteUri);
            using (SHA1 sha1Hash = SHA1.Create())
            {
                byte[] data = sha1Hash.ComputeHash(Encoding.UTF8.GetBytes(hashInput));
                StringBuilder hexString = new StringBuilder();
                for (int i = 0; i < data.Length; i++)
                {
                    hexString.Append(data[i].ToString("x2"));
                }

                return hexString.ToString();
            }
        }
 /// <summary>
 /// Checks if a retry should be performed with the given execution context and exception.
 /// </summary>
 /// <param name="executionContext">The execution context which contains both the
 /// requests and response context.</param>
 /// <param name="exception">The exception throw after issuing the request.</param>
 /// <returns>Returns true if the request should be retried, else false.</returns>
 public bool Retry(IExecutionContext executionContext, Exception exception)
 {
     return
         !RetryLimitReached(executionContext) &&
         CanRetry(executionContext) &&
         RetryForExceptionHelper(executionContext, exception);
 }
Example #7
0
        public void AssignValue(IExecutionContext context, object val)
        {
            object obj = Expr1.Eval(context);

            if(obj is Hashtable)
            {
                ((Hashtable)obj)[Expr2.Eval(context)] = val;
                return;
            }
            else if(obj is Array)
            {
                object index = Expr2.Eval(context);
                if(!IsInteger(index))
                    throw new Exception("Index pole musí být celočíselný");
                ((Array)obj).SetValue(val, Convert.ToInt64(index));
                return;
            }
            else
            {
                object index = Expr2.Eval(context);
                Type t = obj.GetType();
                // find indexer //
                PropertyInfo prop = t.GetProperty("Item");
                prop.GetSetMethod().Invoke(obj, new object[] {index, val});
            }
            //throw new System.NotImplementedException ();
        }
Example #8
0
 public IEnumerable<IDocument> Execute(IReadOnlyList<IDocument> inputs, IExecutionContext context)
 {
     foreach (IDocument input in inputs)
     {
         string path = _path(input);
         if (path != null)
         {
             path = Path.Combine(context.InputFolder, path);
             string fileRoot = Path.GetDirectoryName(path);
             if (fileRoot != null && Directory.Exists(fileRoot))
             {
                 foreach (string file in Directory.EnumerateFiles(fileRoot, Path.GetFileName(path), _searchOption).Where(x => _where == null || _where(x)))
                 {
                     string content = File.ReadAllText(file);
                     context.Trace.Verbose("Read file {0}", file);
                     yield return input.Clone(content, new Dictionary<string, object>
                     {
                         {MetadataKeys.SourceFileRoot, fileRoot},
                         {MetadataKeys.SourceFileBase, Path.GetFileNameWithoutExtension(file)},
                         {MetadataKeys.SourceFileExt, Path.GetExtension(file)},
                         {MetadataKeys.SourceFileName, Path.GetFileName(file)},
                         {MetadataKeys.SourceFileDir, Path.GetDirectoryName(file)},
                         {MetadataKeys.SourceFilePath, file},
                         {MetadataKeys.RelativeFilePath, Path.Combine(PathHelper.GetRelativePath(context.InputFolder, file))}
                     });
                 }
             }
         }
     }
 }
Example #9
0
 public IEnumerable<IDocument> Execute(IReadOnlyList<IDocument> inputs, IExecutionContext context)
 {
     return inputs
        .AsParallel()
        .Select(input =>
        {
            try
            {
                object data = _data(input, context);
                if (data != null)
                {
                    string result = JsonConvert.SerializeObject(data,
                        _indenting ? Formatting.Indented : Formatting.None);
                    if (string.IsNullOrEmpty(_destinationKey))
                    {
                        return context.GetDocument(input, result);
                    }
                    return context.GetDocument(input, new MetadataItems
                    {
                        {_destinationKey, result}
                    });
                }
            }
            catch (Exception ex)
            {
                Trace.Error("Error serializing JSON for {0}: {1}", input.Source, ex.ToString());
            }
            return input;
        })
        .Where(x => x != null);
 }
Example #10
0
 public static void RegisterAllAssemblies(IExecutionContext context, AppDomain domain)
 {
     foreach(Assembly assembly in domain.GetAssemblies())
     {
         context.RegisterAssembly(assembly);
     }
 }
Example #11
0
File: If.cs Project: ibebbs/Wyam
        public IEnumerable<IDocument> Execute(IReadOnlyList<IDocument> inputs, IExecutionContext context)
        {
            List<IDocument> results = new List<IDocument>();
            IEnumerable<IDocument> documents = inputs;
            foreach (Tuple<DocumentConfig, IModule[]> condition in _conditions)
            {
                // Split the documents into ones that satisfy the predicate and ones that don't
                List<IDocument> handled = new List<IDocument>();
                List<IDocument> unhandled = new List<IDocument>();
                foreach (IDocument document in documents)
                {
                    if (condition.Item1 == null || condition.Item1.Invoke<bool>(document, context))
                    {
                        handled.Add(document);
                    }
                    else
                    {
                        unhandled.Add(document);
                    }
                }

                // Run the modules on the documents that satisfy the predicate
                results.AddRange(context.Execute(condition.Item2, handled));

                // Continue with the documents that don't satisfy the predicate
                documents = unhandled;
            }

            // Add back any documents that never matched a predicate
            results.AddRange(documents);

            return results;
        }
Example #12
0
File: Meta.cs Project: st1pps/Wyam
        public IEnumerable<IDocument> Execute(IReadOnlyList<IDocument> inputs, IExecutionContext context)
        {
            if (_modules != null)
            {
                Dictionary<string, object> metadata = new Dictionary<string, object>();

                // Execute the modules for each input document
                if (_forEachDocument)
                {
                    return inputs.Select(input =>
                    {
                        foreach (IDocument result in context.Execute(_modules, new[] { input }))
                        {
                            foreach (KeyValuePair<string, object> kvp in result)
                            {
                                metadata[kvp.Key] = kvp.Value;
                            }
                        }
                        return input.Clone(metadata);
                    });
                }

                // Execute the modules once and apply to each input document
                foreach (IDocument result in context.Execute(_modules))
                {
                    foreach (KeyValuePair<string, object> kvp in result)
                    {
                        metadata[kvp.Key] = kvp.Value;
                    }
                }
                return inputs.Select(input => input.Clone(metadata));
            }

            return inputs.Select(x => x.Clone(new [] { new KeyValuePair<string, object>(_key, _metadata.GetValue(x, context)) }));
        }
Example #13
0
        public override CommandResult Do(IExecutionContext context)
        {
            RegistryKey key = Registry.ClassesRoot.OpenSubKey(@"CLSID\" + ClassId);
            context.SaveResult(ResultName, key != null);

            return CommandResult.Next;
        }
Example #14
0
 public void AssignValue(IExecutionContext context, object val)
 {
     if(IsInitializer)
         context.InitVariable(Name, val);
     else
         context.SetVariable(Name, val);
 }
Example #15
0
 public override void Run(IExecutionContext context)
 {
     if(IsInitializer)
     {
         context.InitVariable(Name);
     }
 }
Example #16
0
        public static IValue For(IExecutionContext ctx, IList<IArgument> arguments)
        {
            var args = CommandUtilities.ManageArguments(arguments)
                .Exactly(4)
                .CanConvert<IExecutable>()
                .Results();

            IExecutionContext outerCtx = ctx.CreateChildContext();
            IExecutable initializer = args[0].GetValue<IExecutable>();
            IExecutable check = args[1].GetValue<IExecutable>();
            IExecutable increment = args[2].GetValue<IExecutable>();
            IExecutable execute = args[3].GetValue<IExecutable>();

            outerCtx.Execute(initializer);

            IValue lastValue = GenericValue<object>.Default;

            while(outerCtx.Execute(check).GetValue<bool>())
            {
                IExecutionContext innerCtx = outerCtx.CreateChildContext();
                lastValue = innerCtx.Execute(execute, breakable: true);

                if (execute.DidBreak())
                    break;

                outerCtx.Execute(increment);
            }

            return lastValue;
        }
Example #17
0
        public override CommandResultCode Execute(IExecutionContext context, CommandArguments args)
        {
            if (args.Count != 1)
                return CommandResultCode.SyntaxError;

            PropertyRegistry properties = Properties;
            if (properties == null) {
                Application.Error.WriteLine("the current context does not support properties.");
                return CommandResultCode.ExecutionFailed;
            }

            if (!args.MoveNext())
                return CommandResultCode.SyntaxError;

            String name = args.Current;
            PropertyHolder holder = properties.GetProperty(name);
            if (holder == null)
                return CommandResultCode.ExecutionFailed;

            string defaultValue = holder.DefaultValue;

            try {
                properties.SetProperty(name, defaultValue);
            } catch (Exception) {
                Application.Error.WriteLine("setting to default '" + defaultValue + "' failed.");
                return CommandResultCode.ExecutionFailed;
            }
            return CommandResultCode.Success;
        }
Example #18
0
 public override object Eval(IExecutionContext context)
 {
     base.Eval(context);
     foreach(TreeViewColumnExpression col in Columns)
         col.Run(context);
     return this;
 }
Example #19
0
 public override void DoProcessRequest(IExecutionContext context)
 {
     // The runtime will react to the null by setting the Anonymous 
     // profile as the current user. the other option is the Abandon
     // method on the context.
     context.Authenticate(null);
 }
Example #20
0
 protected ExecutionContext(IExecutionContext ParentContext, IExecutionContext GlobalContext, ToolScriptParser Parser)
 {
     this.GlobalContext = GlobalContext ?? this;
     this.ParentContext = ParentContext;
     this.Parser = Parser;
     LocalVariables = new Dictionary<string, object>();
 }
Example #21
0
        public IEnumerable<IDocument> Execute(IReadOnlyList<IDocument> inputs, IExecutionContext context)
        {
            // Get syntax trees (supply path so that XML doc includes can be resolved)
            ConcurrentBag<SyntaxTree> syntaxTrees = new ConcurrentBag<SyntaxTree>();
            Parallel.ForEach(inputs, input =>
            {
                using (Stream stream = input.GetStream())
                {
                    SourceText sourceText = SourceText.From(stream);
                    syntaxTrees.Add(CSharpSyntaxTree.ParseText(sourceText, 
                        path: input.String(Keys.SourceFilePath, string.Empty)));
                }
            });

            // Create the compilation (have to supply an XmlReferenceResolver to handle include XML doc comments)
            MetadataReference mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
            CSharpCompilation compilation = CSharpCompilation
                .Create("CodeAnalysisModule", syntaxTrees)
                .WithReferences(mscorlib)
                .WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary,
                    xmlReferenceResolver: new XmlFileResolver(context.InputFolder)));

            // Get and return the document tree
            AnalyzeSymbolVisitor visitor = new AnalyzeSymbolVisitor(context, _symbolPredicate,
                _writePath ?? (x => DefaultWritePath(x, _writePathPrefix)), _cssClasses, _docsForImplicitSymbols);
            visitor.Visit(compilation.Assembly.GlobalNamespace);
            return visitor.Finish();
        }
Example #22
0
        protected override async Task<object> EvaluateCoreAsync(IExecutionContext executionContext, CancellationToken cancellationToken)
        {
            var date = (DateTime) await DateParameter.EvaluateAsync(executionContext, cancellationToken);
            var amount = (double) await AmountParameter.EvaluateAsync(executionContext, cancellationToken);

            return date + _service.GetTimeSpan(amount);           
        }
Example #23
0
        public override CommandResultCode Execute(IExecutionContext context, CommandArguments args)
        {
            if (args.MoveNext())
                return CommandResultCode.SyntaxError;

            NetworkContext networkContext = context as NetworkContext;
            if (networkContext == null)
                return CommandResultCode.ExecutionFailed;

            Out.WriteLine();
            Out.WriteLine("refreshing...");
            Out.Flush();

            networkContext.Network.Refresh();

            try {
                //TODO:
                // networkContext.Network.Configuration.Reload();
            } catch (IOException e) {
                Error.WriteLine("Unable to refresh network config due to IO error");
                Error.WriteLine(e.Message);
                Error.WriteLine(e.StackTrace);
            }

            Out.WriteLine("done.");
            Out.WriteLine();

            return CommandResultCode.Success;
        }
Example #24
0
 public IEnumerable<IDocument> Execute(IReadOnlyList<IDocument> inputs, IExecutionContext context)
 {
     return _searchPattern != null
         ? Execute(null, _searchPattern, context)
         : inputs.AsParallel().SelectMany(input =>
             Execute(input, _sourcePathDelegate.Invoke<string>(input, context), context));
 }
Example #25
0
 IEnumerable<IDocument> IModule.Execute(IReadOnlyList<IDocument> inputs, IExecutionContext context)
 {
     if (_executeDocuments != null)
         return inputs.SelectMany(x => _executeDocuments.Invoke<IEnumerable<IDocument>>(x, context) ?? Array.Empty<IDocument>());
     else
         return _executeContext.Invoke<IEnumerable<IDocument>>(context) ?? Array.Empty<IDocument>();
 }
        /// <summary>
        /// Writes the log.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="stream">The stream.</param>
        /// <param name="callback">The callback for UI updates.</param>
        public void WriteLog(IExecutionContext context, Stream stream, ProgressCallback callback)
        {
            using (BinaryWriter s = new BinaryWriter(stream, Encoding.ASCII))
            {
                s.Write("[PacketLogConverter v1]");

                foreach (PacketLog log in context.LogManager.Logs)
                {
                    for (int i = 0; i < log.Count; i++)
                    {
                        if (callback != null && (i & 0xFFF) == 0) // update progress every 4096th packet
                            callback(i + 1, log.Count);

                        Packet packet = log[i];
                        if (context.FilterManager.IsPacketIgnored(packet))
                            continue;

                        byte[] buf = packet.GetBuffer();
                        s.Write((ushort) buf.Length);
                        s.Write(packet.GetType().FullName);
                        s.Write((ushort) packet.Code);
                        s.Write((byte) packet.Direction);
                        s.Write((byte) packet.Protocol);
                        s.Write(packet.Time.Ticks);
                        s.Write(buf);
                    }
                }
            }
        }
Example #27
0
        public override void DoProcessRequest(IExecutionContext context)
        {
            userProfile profile = UserHelper.Instance.LoadUser(username);
            if (profile == null || !profile.Authenticate(password))
            {
                ReportError(null, "The user name or password is incorrect");
                return;
            }

            else
                // this is the key line. this sets the profile as the 
                // current user, and marks the session as authenticated
                context.Authenticate(profile);

            if (ContentTypeHelper.Instance.Parse(defaultContentType) != profile.UserType.ContentType)
                defaultContentType = ContentTypeHelper.Instance.GetSimpleName(profile.UserType.ContentType);

            // hack. we didn't create a table to store the roles, so now 
            // we're faking them through here
            if (profile.UserType.Equals(UserType.Company)) {
                var node = profile.role.AppendNode();
                node.Name = "company";
            }

            if (String.IsNullOrEmpty(originalRequest))
                context.Transfer("/default");
            else
                context.Transfer(HttpUtility.UrlDecode(originalRequest));
        }
        protected override void HandleException(IExecutionContext executionContext, Exception exception)
        {

            var putObjectRequest = executionContext.RequestContext.OriginalRequest as PutObjectRequest;
            if (putObjectRequest != null)
            {
                // If InputStream was a HashStream, compare calculated hash to returned etag
                HashStream hashStream = putObjectRequest.InputStream as HashStream;
                if (hashStream != null)
                {
                    // Set InputStream to its original value
                    putObjectRequest.InputStream = hashStream.GetNonWrapperBaseStream();
                }
            }

            var uploadPartRequest = executionContext.RequestContext.OriginalRequest as UploadPartRequest;
            if (uploadPartRequest != null)
            {
                // If InputStream was a HashStream, compare calculated hash to returned etag
                HashStream hashStream = uploadPartRequest.InputStream as HashStream;
                if (hashStream != null)
                {
                    // Set InputStream to its original value
                    uploadPartRequest.InputStream = hashStream.GetNonWrapperBaseStream();
                }
            }

            if (executionContext.RequestContext.Request != null)
                AmazonS3Client.CleanupRequest(executionContext.RequestContext.Request);
        }
        /// <summary>
        /// Writes the log.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="stream">The stream.</param>
        /// <param name="callback">The callback for UI updates.</param>
        public void WriteLog(IExecutionContext context, Stream stream, ProgressCallback callback)
        {
            TimeSpan baseTime = new TimeSpan(0);
            using (StreamWriter s = new StreamWriter(stream))
            {
                foreach (PacketLog log in context.LogManager.Logs)
                {
                    // Log file name
                    s.WriteLine();
                    s.WriteLine();
                    s.WriteLine("Log file: " + log.StreamName);
                    s.WriteLine("==============================================");

                    for (int i = 0; i < log.Count; i++)
                    {
                        // Update progress every 4096th packet
                        if (callback != null && (i & 0xFFF) == 0)
                            callback(i, log.Count - 1);

                        Packet packet = log[i];
                        if (context.FilterManager.IsPacketIgnored(packet))
                            continue;

                        s.WriteLine(packet.ToHumanReadableString(baseTime, true));
                    }
                }
            }
        }
Example #30
0
        public override object Eval(IExecutionContext context)
        {
            object vl = ExprLow.Eval(context);
            object vh = ExprHigh.Eval(context);
            if(vl != null && vh != null)
            {
                if(IsNumeric(vl) && IsNumeric(vh))
                    return new Range<Decimal>(Convert.ToDecimal(vl), Convert.ToDecimal(vh), this.RangeType);
                if(vl is DateTime && vh is DateTime)
                    return new Range<DateTime>((DateTime)vl, (DateTime)vh, this.RangeType);
            }
            else if(vl != null)
            {
                if(IsNumeric(vl))
                    return new Range<Decimal>(Convert.ToDecimal(vl), null, this.RangeType);
                if(vl is DateTime)
                    return new Range<DateTime>((DateTime)vl, null, this.RangeType);
            }
            else if(vh != null)
            {
                if(IsNumeric(vh))
                    return new Range<Decimal>(null, Convert.ToDecimal(vh), this.RangeType);
                if(vl is DateTime && vh is DateTime)
                    return new Range<DateTime>(null, (DateTime)vh, this.RangeType);
            }

            throw new InvalidOperationException();
        }
Example #31
0
 public override CommandResult Do(IExecutionContext context)
 {
     Thread.Sleep(MilliSeconds);
     return(CommandResult.Next);
 }
 /// <summary>
 /// Calls pre invoke logic before calling the next handler
 /// in the pipeline.
 /// </summary>
 /// <typeparam name="T">The response type for the current request.</typeparam>
 /// <param name="executionContext">The execution context, it contains the
 /// request and response context.</param>
 /// <returns>A task that represents the asynchronous operation.</returns>
 public override System.Threading.Tasks.Task <T> InvokeAsync <T>(IExecutionContext executionContext)
 {
     PreInvoke(executionContext);
     return(base.InvokeAsync <T>(executionContext));
 }
 /// <summary>
 /// Calls pre invoke logic before calling the next handler
 /// in the pipeline.
 /// </summary>
 /// <param name="executionContext">The execution context which contains both the
 /// requests and response context.</param>
 public override void InvokeSync(IExecutionContext executionContext)
 {
     PreInvoke(executionContext);
     base.InvokeSync(executionContext);
 }
        public bool TryProcessCommand(IExecutionContext context, string input, ContainerInfo container)
        {
            if (string.IsNullOrEmpty(input))
            {
                return(false);
            }

            // TryParse input to Command
            ActionCommand actionCommand;

            if (!ActionCommand.TryParseV2(input, _registeredCommands, out actionCommand) &&
                !ActionCommand.TryParse(input, _registeredCommands, out actionCommand))
            {
                return(false);
            }

            // process action command in serialize order.
            lock (_commandSerializeLock)
            {
                if (_stopProcessCommand)
                {
                    if (!string.IsNullOrEmpty(_stopToken) &&
                        string.Equals(actionCommand.Command, _stopToken, StringComparison.OrdinalIgnoreCase))
                    {
                        context.Output(input);
                        context.Debug("Resume processing commands");
                        _registeredCommands.Remove(_stopToken);
                        _stopProcessCommand = false;
                        _stopToken          = null;
                        return(true);
                    }
                    else
                    {
                        context.Debug($"Process commands has been stopped and waiting for '##[{_stopToken}]' to resume.");
                        return(false);
                    }
                }
                else
                {
                    if (string.Equals(actionCommand.Command, _stopCommand, StringComparison.OrdinalIgnoreCase))
                    {
                        context.Output(input);
                        context.Debug("Paused processing commands until '##[{actionCommand.Data}]' is received");
                        _stopToken          = actionCommand.Data;
                        _stopProcessCommand = true;
                        _registeredCommands.Add(_stopToken);
                        return(true);
                    }
                    else if (_commandExtensions.TryGetValue(actionCommand.Command, out IActionCommandExtension extension))
                    {
                        if (context.EchoOnActionCommand && !extension.OmitEcho)
                        {
                            context.Output(input);
                        }

                        try
                        {
                            extension.ProcessCommand(context, input, actionCommand, container);
                        }
                        catch (Exception ex)
                        {
                            var commandInformation = extension.OmitEcho ? extension.Command : input;
                            context.Error($"Unable to process command '{commandInformation}' successfully.");
                            context.Error(ex);
                            context.CommandResult = TaskResult.Failed;
                        }
                    }
                    else
                    {
                        context.Warning($"Can't find command extension for ##[{actionCommand.Command}.command].");
                    }
                }
            }

            return(true);
        }
        public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
        {
            var data = this is GroupCommandExtension ? command.Data : string.Empty;

            context.Output($"##[{Command}]{data}");
        }
 public void ProcessCommand(IExecutionContext context, string inputLine, ActionCommand command, ContainerInfo container)
 {
     context.Debug(command.Data);
 }
 public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
 {
     ArgUtil.NotNullOrEmpty(command.Data, "path");
     context.Global.PrependPath.RemoveAll(x => string.Equals(x, command.Data, StringComparison.CurrentCulture));
     context.Global.PrependPath.Add(command.Data);
 }
Example #38
0
 /// <inheritdoc />
 public IEnumerable <IDocument> Execute(IReadOnlyList <IDocument> inputs, IExecutionContext context)
 {
     throw new NotImplementedException();
 }
 private Task <int> ExecuteDockerCommandAsync(IExecutionContext context, string command, string options, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(ExecuteDockerCommandAsync(context, command, options, null, cancellationToken));
 }
Example #40
0
 public FM70Actor(ActorService actorService, ActorId actorId, ILifetimeScope lifetimeScope, IExecutionContext executionContext, IJsonSerializationService jsonSerializationService)
     : base(actorService, actorId, lifetimeScope, executionContext, jsonSerializationService)
 {
 }
 public async Task <string> DockerInspect(IExecutionContext context, string dockerObject, string options)
 {
     return((await ExecuteDockerCommandAsync(context, "inspect", $"{options} {dockerObject}")).FirstOrDefault());
 }
        public async Task <RoleDetails> ExecuteAsync(GetRoleDetailsByRoleCodeQuery query, IExecutionContext executionContext)
        {
            var roleCodeLookup = await _roleCache.GetOrAddRoleCodeLookupAsync(async() =>
            {
                var roleCodes = await QueryRoleCodes()
                                .ToDictionaryAsync(r => r.RoleCode, r => r.RoleId);

                return(new ReadOnlyDictionary <string, int>(roleCodes));
            });

            var id = roleCodeLookup.GetOrDefault(query.RoleCode);

            if (id <= 0)
            {
                return(null);
            }

            return(await _internalRoleRepository.GetByIdAsync(id));
        }
 public async Task <int> DockerNetworkPrune(IExecutionContext context)
 {
     return(await ExecuteDockerCommandAsync(context, "network", $"prune --force --filter \"label={DockerInstanceLabel}\"", context.CancellationToken));
 }
        public async Task <List <PortMapping> > DockerPort(IExecutionContext context, string containerId)
        {
            List <string> portMappingLines = await ExecuteDockerCommandAsync(context, "port", containerId);

            return(DockerUtil.ParseDockerPort(portMappingLines));
        }
 public async Task <List <string> > DockerPS(IExecutionContext context, string options)
 {
     return(await ExecuteDockerCommandAsync(context, "ps", options));
 }
 public async Task <int> DockerExec(IExecutionContext context, string containerId, string options, string command)
 {
     return(await ExecuteDockerCommandAsync(context, "exec", $"{options} {containerId} {command}", context.CancellationToken));
 }
 public async Task <int> DockerRemove(IExecutionContext context, string containerId)
 {
     return(await ExecuteDockerCommandAsync(context, "rm", $"--force {containerId}", context.CancellationToken));
 }
 public async Task <int> DockerNetworkRemove(IExecutionContext context, string network)
 {
     return(await ExecuteDockerCommandAsync(context, "network", $"rm {network}", context.CancellationToken));
 }
        public async Task <string> DockerCreate(IExecutionContext context, ContainerInfo container)
        {
            IList <string> dockerOptions = new List <string>();

            // OPTIONS
            dockerOptions.Add($"--name {container.ContainerDisplayName}");
            dockerOptions.Add($"--label {DockerInstanceLabel}");
            if (!string.IsNullOrEmpty(container.ContainerNetwork))
            {
                dockerOptions.Add($"--network {container.ContainerNetwork}");
            }
            if (!string.IsNullOrEmpty(container.ContainerNetworkAlias))
            {
                dockerOptions.Add($"--network-alias {container.ContainerNetworkAlias}");
            }
            foreach (var port in container.UserPortMappings)
            {
                dockerOptions.Add($"-p {port.Value}");
            }
            dockerOptions.Add($"{container.ContainerCreateOptions}");
            foreach (var env in container.ContainerEnvironmentVariables)
            {
                if (String.IsNullOrEmpty(env.Value) && String.IsNullOrEmpty(context.Variables.Get("_VSTS_DONT_RESOLVE_ENV_FROM_HOST")))
                {
                    // TODO: Remove fallback variable if stable
                    dockerOptions.Add($"-e \"{env.Key}\"");
                }
                else
                {
                    dockerOptions.Add($"-e \"{env.Key}={env.Value.Replace("\"", "\\\"")}\"");
                }
            }
            foreach (var volume in container.MountVolumes)
            {
                // replace `"` with `\"` and add `"{0}"` to all path.
                String volumeArg;
                if (String.IsNullOrEmpty(volume.SourceVolumePath))
                {
                    // Anonymous docker volume
                    volumeArg = $"-v \"{volume.TargetVolumePath.Replace("\"", "\\\"")}\"";
                }
                else
                {
                    // Named Docker volume / host bind mount
                    volumeArg = $"-v \"{volume.SourceVolumePath.Replace("\"", "\\\"")}\":\"{volume.TargetVolumePath.Replace("\"", "\\\"")}\"";
                }
                if (volume.ReadOnly)
                {
                    volumeArg += ":ro";
                }
                dockerOptions.Add(volumeArg);
            }
            // IMAGE
            dockerOptions.Add($"{container.ContainerImage}");
            // COMMAND
            dockerOptions.Add($"{container.ContainerCommand}");

            var           optionsString = string.Join(" ", dockerOptions);
            List <string> outputStrings = await ExecuteDockerCommandAsync(context, "create", optionsString);

            return(outputStrings.FirstOrDefault());
        }
 public async Task <int> DockerLogs(IExecutionContext context, string containerId)
 {
     return(await ExecuteDockerCommandAsync(context, "logs", $"--details {containerId}", context.CancellationToken));
 }
 public async Task <int> DockerLogout(IExecutionContext context, string server)
 {
     return(await ExecuteDockerCommandAsync(context, "logout", $"{server}", context.CancellationToken));
 }
 public async Task <int> DockerStart(IExecutionContext context, string containerId)
 {
     return(await ExecuteDockerCommandAsync(context, "start", containerId, context.CancellationToken));
 }
Example #53
0
        private async Task StartContainerAsync(IExecutionContext executionContext)
        {
            Trace.Entering();
            ArgUtil.NotNull(executionContext, nameof(executionContext));
            ArgUtil.NotNullOrEmpty(executionContext.Container.ContainerImage, nameof(executionContext.Container.ContainerImage));

            // Check docker client/server version
            DockerVersion dockerVersion = await _dockerManger.DockerVersion(executionContext);

            ArgUtil.NotNull(dockerVersion.ServerVersion, nameof(dockerVersion.ServerVersion));
            ArgUtil.NotNull(dockerVersion.ClientVersion, nameof(dockerVersion.ClientVersion));
            Version requiredDockerVersion = new Version(17, 3);

            if (dockerVersion.ServerVersion < requiredDockerVersion)
            {
                throw new NotSupportedException(StringUtil.Loc("MinRequiredDockerServerVersion", requiredDockerVersion, _dockerManger.DockerPath, dockerVersion.ServerVersion));
            }
            if (dockerVersion.ClientVersion < requiredDockerVersion)
            {
                throw new NotSupportedException(StringUtil.Loc("MinRequiredDockerClientVersion", requiredDockerVersion, _dockerManger.DockerPath, dockerVersion.ClientVersion));
            }

            // Pull down docker image
            int pullExitCode = await _dockerManger.DockerPull(executionContext, executionContext.Container.ContainerImage);

            if (pullExitCode != 0)
            {
                throw new InvalidOperationException($"Docker pull fail with exit code {pullExitCode}");
            }

            // Mount folder into container
            executionContext.Container.MountVolumes.Add(new MountVolume(Path.GetDirectoryName(executionContext.Variables.System_DefaultWorkingDirectory.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar))));
            executionContext.Container.MountVolumes.Add(new MountVolume(executionContext.Variables.Agent_TempDirectory));
            executionContext.Container.MountVolumes.Add(new MountVolume(executionContext.Variables.Agent_ToolsDirectory));
            executionContext.Container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Externals), true));
            executionContext.Container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Tasks), true));

            // Ensure .taskkey file exist so we can mount it.
            string taskKeyFile = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Work), ".taskkey");

            if (!File.Exists(taskKeyFile))
            {
                File.WriteAllText(taskKeyFile, string.Empty);
            }
            executionContext.Container.MountVolumes.Add(new MountVolume(taskKeyFile));

            executionContext.Container.ContainerId = await _dockerManger.DockerCreate(executionContext, executionContext.Container.ContainerImage, executionContext.Container.MountVolumes);

            ArgUtil.NotNullOrEmpty(executionContext.Container.ContainerId, nameof(executionContext.Container.ContainerId));

            // Get current username
            executionContext.Container.CurrentUserName = (await ExecuteCommandAsync(executionContext, "whoami", string.Empty)).FirstOrDefault();
            ArgUtil.NotNullOrEmpty(executionContext.Container.CurrentUserName, nameof(executionContext.Container.CurrentUserName));

            // Get current userId
            executionContext.Container.CurrentUserId = (await ExecuteCommandAsync(executionContext, "id", $"-u {executionContext.Container.CurrentUserName}")).FirstOrDefault();
            ArgUtil.NotNullOrEmpty(executionContext.Container.CurrentUserId, nameof(executionContext.Container.CurrentUserId));

            int startExitCode = await _dockerManger.DockerStart(executionContext, executionContext.Container.ContainerId);

            if (startExitCode != 0)
            {
                throw new InvalidOperationException($"Docker start fail with exit code {startExitCode}");
            }

            // Ensure bash exist in the image
            int execWhichBashExitCode = await _dockerManger.DockerExec(executionContext, executionContext.Container.ContainerId, string.Empty, $"which bash");

            if (execWhichBashExitCode != 0)
            {
                throw new InvalidOperationException($"Docker exec fail with exit code {execWhichBashExitCode}");
            }

            // Create an user with same uid as the agent run as user inside the container.
            // All command execute in docker will run as Root by default,
            // this will cause the agent on the host machine doesn't have permission to any new file/folder created inside the container.
            // So, we create a user account with same UID inside the container and let all docker exec command run as that user.
            int execUseraddExitCode = await _dockerManger.DockerExec(executionContext, executionContext.Container.ContainerId, string.Empty, $"useradd -m -u {executionContext.Container.CurrentUserId} {executionContext.Container.CurrentUserName}_VSTSContainer");

            if (execUseraddExitCode != 0)
            {
                throw new InvalidOperationException($"Docker exec fail with exit code {execUseraddExitCode}");
            }
        }
 public async Task <int> DockerPull(IExecutionContext context, string image)
 {
     return(await ExecuteDockerCommandAsync(context, "pull", image, context.CancellationToken));
 }
Example #55
0
        public async Task StartContainersAsync(IExecutionContext executionContext, object data)
        {
            Trace.Entering();
            if (!Constants.Runner.Platform.Equals(Constants.OSPlatform.Linux))
            {
                throw new NotSupportedException("Container operations are only supported on Linux runners");
            }
            ArgUtil.NotNull(executionContext, nameof(executionContext));
            List <ContainerInfo> containers = data as List <ContainerInfo>;

            ArgUtil.NotNull(containers, nameof(containers));

            var postJobStep = new JobExtensionRunner(runAsync: this.StopContainersAsync,
                                                     condition: $"{PipelineTemplateConstants.Always}()",
                                                     displayName: "Stop containers",
                                                     data: data);

            executionContext.Debug($"Register post job cleanup for stopping/deleting containers.");
            executionContext.RegisterPostJobStep(postJobStep);

#if OS_WINDOWS
            // Check OS version (Windows server 1803 is required)
            object windowsInstallationType = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "InstallationType", defaultValue: null);
            ArgUtil.NotNull(windowsInstallationType, nameof(windowsInstallationType));
            object windowsReleaseId = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ReleaseId", defaultValue: null);
            ArgUtil.NotNull(windowsReleaseId, nameof(windowsReleaseId));
            executionContext.Debug($"Current Windows version: '{windowsReleaseId} ({windowsInstallationType})'");

            if (int.TryParse(windowsReleaseId.ToString(), out int releaseId))
            {
                if (!windowsInstallationType.ToString().StartsWith("Server", StringComparison.OrdinalIgnoreCase) || releaseId < 1803)
                {
                    throw new NotSupportedException("Container feature requires Windows Server 1803 or higher.");
                }
            }
            else
            {
                throw new ArgumentOutOfRangeException(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ReleaseId");
            }
#endif

            // Check docker client/server version
            DockerVersion dockerVersion = await _dockerManger.DockerVersion(executionContext);

            ArgUtil.NotNull(dockerVersion.ServerVersion, nameof(dockerVersion.ServerVersion));
            ArgUtil.NotNull(dockerVersion.ClientVersion, nameof(dockerVersion.ClientVersion));

#if OS_WINDOWS
            Version requiredDockerEngineAPIVersion = new Version(1, 30); // Docker-EE version 17.6
#else
            Version requiredDockerEngineAPIVersion = new Version(1, 35); // Docker-CE version 17.12
#endif

            if (dockerVersion.ServerVersion < requiredDockerEngineAPIVersion)
            {
                throw new NotSupportedException($"Min required docker engine API server version is '{requiredDockerEngineAPIVersion}', your docker ('{_dockerManger.DockerPath}') server version is '{dockerVersion.ServerVersion}'");
            }
            if (dockerVersion.ClientVersion < requiredDockerEngineAPIVersion)
            {
                throw new NotSupportedException($"Min required docker engine API client version is '{requiredDockerEngineAPIVersion}', your docker ('{_dockerManger.DockerPath}') client version is '{dockerVersion.ClientVersion}'");
            }

            // Clean up containers left by previous runs
            executionContext.Debug($"Delete stale containers from previous jobs");
            var staleContainers = await _dockerManger.DockerPS(executionContext, $"--all --quiet --no-trunc --filter \"label={_dockerManger.DockerInstanceLabel}\"");

            foreach (var staleContainer in staleContainers)
            {
                int containerRemoveExitCode = await _dockerManger.DockerRemove(executionContext, staleContainer);

                if (containerRemoveExitCode != 0)
                {
                    executionContext.Warning($"Delete stale containers failed, docker rm fail with exit code {containerRemoveExitCode} for container {staleContainer}");
                }
            }

            executionContext.Debug($"Delete stale container networks from previous jobs");
            int networkPruneExitCode = await _dockerManger.DockerNetworkPrune(executionContext);

            if (networkPruneExitCode != 0)
            {
                executionContext.Warning($"Delete stale container networks failed, docker network prune fail with exit code {networkPruneExitCode}");
            }

            // Create local docker network for this job to avoid port conflict when multiple runners run on same machine.
            // All containers within a job join the same network
            var containerNetwork = $"github_network_{Guid.NewGuid().ToString("N")}";
            await CreateContainerNetworkAsync(executionContext, containerNetwork);

            executionContext.JobContext.Container["network"] = new StringContextData(containerNetwork);

            foreach (var container in containers)
            {
                container.ContainerNetwork = containerNetwork;
                await StartContainerAsync(executionContext, container);
            }

            foreach (var container in containers.Where(c => !c.IsJobContainer))
            {
                await ContainerHealthcheck(executionContext, container);
            }
        }
Example #56
0
 /// <summary>
 /// Invokes the inner handler and performs a retry, if required as per the
 /// retry policy.
 /// </summary>
 /// <param name="executionContext">The execution context which contains both the
 /// requests and response context.</param>
 public override void InvokeSync(IExecutionContext executionContext)
 {
     InvokeAsync(executionContext).Wait();
 }
        public async Task ExecuteAsync(DeleteUnstructuredDataDependenciesCommand command, IExecutionContext executionContext)
        {
            string entityName;

            var entityDefinition = _entityDefinitionRepository.GetByCode(command.RootEntityDefinitionCode);

            EntityNotFoundException.ThrowIfNull(entityDefinition, command.RootEntityDefinitionCode);
            entityName = entityDefinition.Name;

            var query        = new GetEntityDependencySummaryByRelatedEntityQuery(command.RootEntityDefinitionCode, command.RootEntityId);
            var dependencies = await _queryExecutor.ExecuteAsync(query);

            var requiredDependency = dependencies.FirstOrDefault(d => !d.CanDelete);

            if (requiredDependency != null)
            {
                throw new ValidationException(
                          string.Format("Cannot delete this {0} because {1} '{2}' has a dependency on it.",
                                        entityName,
                                        requiredDependency.Entity.EntityDefinitionName.ToLower(),
                                        requiredDependency.Entity.RootEntityTitle));
            }

            await _entityFrameworkSqlExecutor
            .ExecuteCommandAsync("Cofoundry.UnstructuredDataDependency_Delete",
                                 new SqlParameter("EntityDefinitionCode", command.RootEntityDefinitionCode),
                                 new SqlParameter("EntityId", command.RootEntityId)
                                 );
        }
Example #58
0
        public async Task <PageRoutingInfo> ExecuteAsync(GetPageRoutingInfoByPathQuery query, IExecutionContext executionContext)
        {
            // Deal with malformed query
            if (!string.IsNullOrWhiteSpace(query.Path) && !Uri.IsWellFormedUriString(query.Path, UriKind.Relative))
            {
                return(null);
            }

            var path      = _pathHelper.StandardizePath(query.Path);
            var allRoutes = await _queryExecutor.ExecuteAsync(new GetAllPageRoutesQuery(), executionContext);

            var pageRoutes = allRoutes
                             .Where(r => r.FullPath.Equals(path) || (r.PageType == PageType.CustomEntityDetails && IsCustomRoutingMatch(path, r.FullPath)))
                             .Where(r => query.IncludeUnpublished || r.IsPublished())
                             .Where(r => r.Locale == null || MatchesLocale(r.Locale, query.LocaleId))
                             .OrderByDescending(r => r.FullPath.Equals(path))
                             .ThenByDescending(r => MatchesLocale(r.Locale, query.LocaleId))
                             .ToList();

            PageRoutingInfo result = null;

            if (!pageRoutes.Any())
            {
                return(result);
            }

            // Exact match
            if (pageRoutes[0].PageType != PageType.CustomEntityDetails)
            {
                result = ToRoutingInfo(pageRoutes[0]);
            }
            else
            {
                var allRules = await _queryExecutor.ExecuteAsync(new GetAllCustomEntityRoutingRulesQuery(), executionContext);

                // I'm only anticipating a single rule to match at the moment, but eventually there might be multiple rules to match e.g. categories page
                foreach (var pageRoute in pageRoutes)
                {
                    // Find a routing rule, matching higher priorities first
                    var rule = allRules
                               .Where(r => r.MatchesRule(query.Path, pageRoute))
                               .OrderBy(r => r.Priority)
                               .ThenBy(r => r.RouteFormat.Length)
                               .FirstOrDefault();

                    if (rule != null)
                    {
                        var customEntityRouteQuery = rule.ExtractRoutingQuery(query.Path, pageRoute);
                        var customEntityRoute      = await _queryExecutor.ExecuteAsync(customEntityRouteQuery, executionContext);

                        if (customEntityRoute != null && (query.IncludeUnpublished || customEntityRoute.IsPublished()))
                        {
                            return(ToRoutingInfo(pageRoute, customEntityRoute, rule));
                        }
                    }
                }
            }

            return(result);
        }
 public AddParameterToContainerCommand(IParameter parameterToAdd, IContainer parentContainer, IExecutionContext context)
     : base(parameterToAdd, parentContainer, context)
 {
 }
Example #60
0
        private async Task StartContainerAsync(IExecutionContext executionContext, ContainerInfo container)
        {
            Trace.Entering();
            ArgUtil.NotNull(executionContext, nameof(executionContext));
            ArgUtil.NotNull(container, nameof(container));
            ArgUtil.NotNullOrEmpty(container.ContainerImage, nameof(container.ContainerImage));

            Trace.Info($"Container name: {container.ContainerName}");
            Trace.Info($"Container image: {container.ContainerImage}");
            Trace.Info($"Container options: {container.ContainerCreateOptions}");
            foreach (var port in container.UserPortMappings)
            {
                Trace.Info($"User provided port: {port.Value}");
            }
            foreach (var volume in container.UserMountVolumes)
            {
                Trace.Info($"User provided volume: {volume.Value}");
                var mount = new MountVolume(volume.Value);
                if (string.Equals(mount.SourceVolumePath, "/", StringComparison.OrdinalIgnoreCase))
                {
                    executionContext.Warning($"Volume mount {volume.Value} is going to mount '/' into the container which may cause file ownership change in the entire file system and cause Actions Runner to lose permission to access the disk.");
                }
            }

            // Pull down docker image with retry up to 3 times
            int retryCount   = 0;
            int pullExitCode = 0;

            while (retryCount < 3)
            {
                pullExitCode = await _dockerManger.DockerPull(executionContext, container.ContainerImage);

                if (pullExitCode == 0)
                {
                    break;
                }
                else
                {
                    retryCount++;
                    if (retryCount < 3)
                    {
                        var backOff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(10));
                        executionContext.Warning($"Docker pull failed with exit code {pullExitCode}, back off {backOff.TotalSeconds} seconds before retry.");
                        await Task.Delay(backOff);
                    }
                }
            }

            if (retryCount == 3 && pullExitCode != 0)
            {
                throw new InvalidOperationException($"Docker pull failed with exit code {pullExitCode}");
            }

            if (container.IsJobContainer)
            {
                // Configure job container - Mount workspace and tools, set up environment, and start long running process
                var githubContext = executionContext.ExpressionValues["github"] as GitHubContext;
                ArgUtil.NotNull(githubContext, nameof(githubContext));
                var workingDirectory = githubContext["workspace"] as StringContextData;
                ArgUtil.NotNullOrEmpty(workingDirectory, nameof(workingDirectory));
                container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Work), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Work))));
#if OS_WINDOWS
                container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Externals), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Externals))));
#else
                container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Externals), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Externals)), true));
#endif
                container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Temp), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Temp))));
                container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Actions), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Actions))));
                container.MountVolumes.Add(new MountVolume(HostContext.GetDirectory(WellKnownDirectory.Tools), container.TranslateToContainerPath(HostContext.GetDirectory(WellKnownDirectory.Tools))));

                var tempHomeDirectory = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Temp), "_github_home");
                Directory.CreateDirectory(tempHomeDirectory);
                container.MountVolumes.Add(new MountVolume(tempHomeDirectory, "/github/home"));
                container.AddPathTranslateMapping(tempHomeDirectory, "/github/home");
                container.ContainerEnvironmentVariables["HOME"] = container.TranslateToContainerPath(tempHomeDirectory);

                var tempWorkflowDirectory = Path.Combine(HostContext.GetDirectory(WellKnownDirectory.Temp), "_github_workflow");
                Directory.CreateDirectory(tempWorkflowDirectory);
                container.MountVolumes.Add(new MountVolume(tempWorkflowDirectory, "/github/workflow"));
                container.AddPathTranslateMapping(tempWorkflowDirectory, "/github/workflow");

                container.ContainerWorkDirectory  = container.TranslateToContainerPath(workingDirectory);
                container.ContainerEntryPoint     = "tail";
                container.ContainerEntryPointArgs = "\"-f\" \"/dev/null\"";
            }

            container.ContainerId = await _dockerManger.DockerCreate(executionContext, container);

            ArgUtil.NotNullOrEmpty(container.ContainerId, nameof(container.ContainerId));

            // Start container
            int startExitCode = await _dockerManger.DockerStart(executionContext, container.ContainerId);

            if (startExitCode != 0)
            {
                throw new InvalidOperationException($"Docker start fail with exit code {startExitCode}");
            }

            try
            {
                // Make sure container is up and running
                var psOutputs = await _dockerManger.DockerPS(executionContext, $"--all --filter id={container.ContainerId} --filter status=running --no-trunc --format \"{{{{.ID}}}} {{{{.Status}}}}\"");

                if (psOutputs.FirstOrDefault(x => !string.IsNullOrEmpty(x))?.StartsWith(container.ContainerId) != true)
                {
                    // container is not up and running, pull docker log for this container.
                    await _dockerManger.DockerPS(executionContext, $"--all --filter id={container.ContainerId} --no-trunc --format \"{{{{.ID}}}} {{{{.Status}}}}\"");

                    int logsExitCode = await _dockerManger.DockerLogs(executionContext, container.ContainerId);

                    if (logsExitCode != 0)
                    {
                        executionContext.Warning($"Docker logs fail with exit code {logsExitCode}");
                    }

                    executionContext.Warning($"Docker container {container.ContainerId} is not in running state.");
                }
            }
            catch (Exception ex)
            {
                // pull container log is best effort.
                Trace.Error("Catch exception when check container log and container status.");
                Trace.Error(ex);
            }

            // Gather runtime container information
            if (!container.IsJobContainer)
            {
                var service = new DictionaryContextData()
                {
                    ["id"]      = new StringContextData(container.ContainerId),
                    ["ports"]   = new DictionaryContextData(),
                    ["network"] = new StringContextData(container.ContainerNetwork)
                };
                container.AddPortMappings(await _dockerManger.DockerPort(executionContext, container.ContainerId));
                foreach (var port in container.PortMappings)
                {
                    (service["ports"] as DictionaryContextData)[port.ContainerPort] = new StringContextData(port.HostPort);
                }
                executionContext.JobContext.Services[container.ContainerNetworkAlias] = service;
            }
            else
            {
                var configEnvFormat = "--format \"{{range .Config.Env}}{{println .}}{{end}}\"";
                var containerEnv    = await _dockerManger.DockerInspect(executionContext, container.ContainerId, configEnvFormat);

                container.ContainerRuntimePath = DockerUtil.ParsePathFromConfigEnv(containerEnv);
                executionContext.JobContext.Container["id"] = new StringContextData(container.ContainerId);
            }
        }