示例#1
0
        /// <summary>Run a batch of containers. Must have already created state for them. Waits till the batch is complete and
        ///   returns the status.</summary>
        public async Task <IReadOnlyCollection <PipeRunMetadata> > Launch(IPipeCtx ctx, IReadOnlyCollection <PipeRunId> ids, bool returnOnRunning,
                                                                          bool exclusive, ILogger log, CancellationToken cancel)
        {
            var res = await ids.BlockFunc(async runId => {
                var runCfg = runId.PipeCfg(ctx.PipeCfg); // id is for the sub-pipe, ctx is for the root

                var tag           = await FindPipeTag(runCfg.Container.ImageName);
                var fullImageName = runCfg.Container.FullContainerImageName(tag);
                var pipeLog       = log.ForContext("Image", fullImageName).ForContext("Pipe", runId.Name);

                var containerGroup = runId.ContainerGroupName(exclusive, Version);
                var containerName  = runCfg.Container.ImageName.ToLowerInvariant();

                var(group, launchDur) = await Launch(runCfg.Container, containerGroup, containerName,
                                                     fullImageName, ctx.AppCtx.EnvironmentVariables,
                                                     runId.PipeArgs(), returnOnRunning, ctx.AppCtx.CustomRegion, pipeLog, cancel).WithDuration();

                var logTxt  = await group.GetLogContentAsync(containerName);
                var logPath = new StringPath($"{runId.StatePath()}.log.txt");

                var launchState = group.State();

                var errorMsg = launchState.In(ContainerState.Failed, ContainerState.Terminated, ContainerState.Unknown)
          ? $"The container is in an error state '{group.State}', see {logPath}"
          : null;
                if (errorMsg.HasValue())
                {
                    pipeLog.Error("{RunId} - failed: {Log}", runId.ToString(), logTxt);
                }

                var md = new PipeRunMetadata {
                    Id           = runId,
                    Duration     = launchDur,
                    Containers   = group.Containers.Select(c => c.Value).ToArray(),
                    RawState     = group.State,
                    State        = group.State(),
                    RunCfg       = runCfg,
                    ErrorMessage = errorMsg
                };
                await Task.WhenAll(
                    ctx.Store.Save(logPath, logTxt.AsStream(), pipeLog),
                    md.Save(ctx.Store, pipeLog));

                // delete succeeded non-exclusive containers. Failed, and rutned on running will be cleaned up by another process
                if (group.State() == ContainerState.Succeeded && !(exclusive && runId.Num > 0))
                {
                    await DeleteContainer(containerGroup, log);
                }

                return(md);
            }, ctx.PipeCfg.Azure.Parallel);

            return(res);
        }
示例#2
0
        public async Task <IReadOnlyCollection <PipeRunMetadata> > Launch(IPipeCtx ctx, IReadOnlyCollection <PipeRunId> ids, ILogger log, CancellationToken cancel)
        {
            var res = await ids.BlockFunc(async id => {
                await ctx.DoPipeWork(id, cancel);
                var md = new PipeRunMetadata {
                    Id = id
                };
                await md.Save(ctx.Store, log);
                return(md);
            });

            return(res);
        }