Exemplo n.º 1
0
    private async Task <ResultVoid <TaskConfigError> > CheckContainers(TaskDefinition definition, TaskConfig config)
    {
        if (config.Containers == null)
        {
            return(ResultVoid <TaskConfigError> .Ok());
        }

        var exist      = new HashSet <string>();
        var containers = new Dictionary <ContainerType, List <Container> >();

        foreach (var container in config.Containers)
        {
            if (exist.Contains(container.Name.ContainerName))
            {
                continue;
            }
            if (await _containers.FindContainer(container.Name, StorageType.Corpus) == null)
            {
                return(ResultVoid <TaskConfigError> .Error(new TaskConfigError($"missing container: {container.Name}")));
            }
            exist.Add(container.Name.ContainerName);

            if (!containers.ContainsKey(container.Type))
            {
                containers.Add(container.Type, new List <Container>());
            }
            containers[container.Type].Add(container.Name);
        }

        foreach (var containerDef in definition.Containers)
        {
            var r = CheckContainer(containerDef.Compare, containerDef.Value, containerDef.Type, containers);
            if (!r.IsOk)
            {
                return(r);
            }
        }

        var containerTypes = definition.Containers.Select(x => x.Type).ToHashSet();
        var missing        = containers.Keys.Where(x => !containerTypes.Contains(x)).ToList();

        if (missing.Any())
        {
            var types = string.Join(", ", missing);
            return(ResultVoid <TaskConfigError> .Error(new TaskConfigError($"unsupported container types for this task: {types}")));
        }

        if (definition.MonitorQueue != null)
        {
            if (!containerTypes.Contains(definition.MonitorQueue.Value))
            {
                return(ResultVoid <TaskConfigError> .Error(new TaskConfigError($"unable to monitor container type as it is not used by this task: {definition.MonitorQueue}")));
            }
        }

        return(ResultVoid <TaskConfigError> .Ok());
    }
Exemplo n.º 2
0
    private static ResultVoid <TaskConfigError> CheckContainer(Compare compare, long expected, ContainerType containerType, Dictionary <ContainerType, List <Container> > containers)
    {
        var actual = containers.ContainsKey(containerType) ? containers[containerType].Count : 0;

        if (!CheckVal(compare, expected, actual))
        {
            return(ResultVoid <TaskConfigError> .Error(
                       new TaskConfigError($"container type {containerType}: expected {compare} {expected}, got {actual}")));
        }

        return(ResultVoid <TaskConfigError> .Ok());
    }
Exemplo n.º 3
0
    private async Task <ResultVoid <TaskConfigError> > CheckTargetExe(TaskConfig config, TaskDefinition definition)
    {
        if (config.Task.TargetExe == null)
        {
            if (definition.Features.Contains(TaskFeature.TargetExe))
            {
                return(ResultVoid <TaskConfigError> .Error(new TaskConfigError("missing target_exe")));
            }

            if (definition.Features.Contains(TaskFeature.TargetExeOptional))
            {
                return(ResultVoid <TaskConfigError> .Ok());
            }
            return(ResultVoid <TaskConfigError> .Ok());
        }

        // User-submitted paths must be relative to the setup directory that contains them.
        // They also must be normalized, and exclude special filesystem path elements.
        //
        // For example, accessing the blob store path "./foo" generates an exception, but
        // "foo" and "foo/bar" do not.

        if (!IsValidBlobName(config.Task.TargetExe))
        {
            return(ResultVoid <TaskConfigError> .Error(new TaskConfigError("target_exe must be a canonicalized relative path")));
        }


        var container = config.Containers !.FirstOrDefault(x => x.Type == ContainerType.Setup);

        if (container != null)
        {
            if (!await _containers.BlobExists(container.Name, config.Task.TargetExe, StorageType.Corpus))
            {
                var err =
                    $"target_exe `{config.Task.TargetExe}` does not exist in the setup container `{container.Name}`";

                _logTracer.Warning(err);
            }
        }

        return(ResultVoid <TaskConfigError> .Ok());
    }
Exemplo n.º 4
0
    public async Async.Task <ResultVoid <TaskConfigError> > CheckConfig(TaskConfig config)
    {
        if (!Defs.TASK_DEFINITIONS.ContainsKey(config.Task.Type))
        {
            return(ResultVoid <TaskConfigError> .Error(new TaskConfigError($"unsupported task type: {config.Task.Type}")));
        }

        if (config.Vm != null && config.Pool != null)
        {
            return(ResultVoid <TaskConfigError> .Error(new TaskConfigError($"either the vm or pool must be specified, but not both")));
        }

        var definition = Defs.TASK_DEFINITIONS[config.Task.Type];
        var r          = await CheckContainers(definition, config);

        if (!r.IsOk)
        {
            return(r);
        }

        if (definition.Features.Contains(TaskFeature.SupervisorExe) && config.Task.SupervisorExe == null)
        {
            var err = "missing supervisor_exe";
            _logTracer.Error(err);
            return(ResultVoid <TaskConfigError> .Error(new TaskConfigError(err)));
        }

        if (definition.Features.Contains(TaskFeature.TargetMustUseInput) && !TargetUsesInput(config))
        {
            return(ResultVoid <TaskConfigError> .Error(new TaskConfigError("{input} must be used in target_env or target_options")));
        }

        if (config.Vm != null)
        {
            return(ResultVoid <TaskConfigError> .Error(new TaskConfigError("specifying task config vm is no longer supported")));
        }

        if (config.Pool == null)
        {
            return(ResultVoid <TaskConfigError> .Error(new TaskConfigError("pool must be specified")));
        }

        if (!CheckVal(definition.Vm.Compare, definition.Vm.Value, config.Pool !.Count))
        {
            var err =
                $"invalid vm count: expected {definition.Vm.Compare} {definition.Vm.Value}, got {config.Pool.Count}";
            _logTracer.Error(err);
            return(ResultVoid <TaskConfigError> .Error(new TaskConfigError(err)));
        }

        var pool = await _context.PoolOperations.GetByName(config.Pool.PoolName);

        if (!pool.IsOk)
        {
            return(ResultVoid <TaskConfigError> .Error(new TaskConfigError($"invalid pool: {config.Pool.PoolName}")));
        }

        var checkTarget = await CheckTargetExe(config, definition);

        if (!checkTarget.IsOk)
        {
            return(checkTarget);
        }

        if (definition.Features.Contains(TaskFeature.GeneratorExe))
        {
            var container = config.Containers !.First(x => x.Type == ContainerType.Tools);

            if (config.Task.GeneratorExe == null)
            {
                return(ResultVoid <TaskConfigError> .Error(new TaskConfigError($"generator_exe is not defined")));
            }

            var tool_paths = new[] { "{tools_dir}/", "{tools_dir}\\" };

            foreach (var toolPath in tool_paths)
            {
                if (config.Task.GeneratorExe.StartsWith(toolPath))
                {
                    var generator = config.Task.GeneratorExe.Replace(toolPath, "");
                    if (!await _containers.BlobExists(container.Name, generator, StorageType.Corpus))
                    {
                        var err =
                            $"generator_exe `{config.Task.GeneratorExe}` does not exist in the tools container `{container.Name}`";
                        _logTracer.Error(err);
                        return(ResultVoid <TaskConfigError> .Error(new TaskConfigError(err)));
                    }
                }
            }
        }

        if (definition.Features.Contains(TaskFeature.StatsFile))
        {
            if (config.Task.StatsFile != null && config.Task.StatsFormat == null)
            {
                var err2 = "using a stats_file requires a stats_format";
                _logTracer.Error(err2);
                return(ResultVoid <TaskConfigError> .Error(new TaskConfigError(err2)));
            }
        }

        return(ResultVoid <TaskConfigError> .Ok());
    }