示例#1
0
        /// <summary>
        /// Loads configured symlink definitions (if not already loaded)
        /// Stores to cache for use by workers in distributed build
        /// Eagerly creates symlinks if lazy symlink creation is disabled
        /// </summary>
        public static async Task <Possible <SymlinkDefinitions> > TryPrepareSymlinkDefinitionsAsync(
            LoggingContext loggingContext,
            GraphReuseResult reuseResult,
            IConfiguration configuration,
            MasterService masterService,
            CacheInitializationTask cacheInitializerTask,
            PipExecutionContext context,
            ITempDirectoryCleaner tempDirectoryCleaner = null)
        {
            var  pathTable           = context.PathTable;
            bool isDistributedMaster = configuration.Distribution.BuildRole == DistributedBuildRoles.Master;
            Possible <SymlinkDefinitions> maybeSymlinkDefinitions = new Possible <SymlinkDefinitions>((SymlinkDefinitions)null);

            if (reuseResult?.IsFullReuse == true)
            {
                maybeSymlinkDefinitions = reuseResult.EngineSchedule.Scheduler.SymlinkDefinitions;
            }
            else if (configuration.Layout.SymlinkDefinitionFile.IsValid)
            {
                var symlinkFilePath = configuration.Layout.SymlinkDefinitionFile.ToString(pathTable);
                Logger.Log.SymlinkFileTraceMessage(loggingContext, I($"Loading symlink file from location '{symlinkFilePath}'."));
                maybeSymlinkDefinitions = await SymlinkDefinitions.TryLoadAsync(
                    loggingContext,
                    pathTable,
                    symlinkFilePath,
                    symlinksDebugPath : configuration.Logging.LogsDirectory.Combine(pathTable, "DebugSymlinksDefinitions.log").ToString(pathTable),
                    tempDirectoryCleaner : tempDirectoryCleaner);
            }

            if (!maybeSymlinkDefinitions.Succeeded || maybeSymlinkDefinitions.Result == null)
            {
                return(maybeSymlinkDefinitions);
            }

            // Need to store symlinks to cache for workers
            if (configuration.Distribution.BuildRole == DistributedBuildRoles.Master)
            {
                var possibleCacheInitializer = await cacheInitializerTask;
                if (!possibleCacheInitializer.Succeeded)
                {
                    return(possibleCacheInitializer.Failure);
                }

                Logger.Log.SymlinkFileTraceMessage(loggingContext, I($"Storing symlink file for use by workers."));

                var symlinkFile = configuration.Layout.SymlinkDefinitionFile.Expand(pathTable);

                var possibleStore = await TryStoreToCacheAsync(
                    loggingContext,
                    cache : possibleCacheInitializer.Result.CreateCacheForContext(context).ArtifactContentCache,
                    symlinkFile : symlinkFile);

                if (!possibleStore.Succeeded)
                {
                    return(possibleStore.Failure);
                }

                masterService.SymlinkFileContentHash = possibleStore.Result;
                Logger.Log.SymlinkFileTraceMessage(loggingContext, I($"Stored symlink file for use by workers."));
            }

            if (!configuration.Schedule.UnsafeLazySymlinkCreation || configuration.Engine.PopulateSymlinkDirectories.Count != 0)
            {
                // Symlink definition file is defined, and BuildXL intends to create it eagerly.
                // At this point master and worker should have had its symlink definition file, if specified.
                if (!FileContentManager.CreateSymlinkEagerly(loggingContext, configuration, pathTable, maybeSymlinkDefinitions.Result, context.CancellationToken))
                {
                    return(new Failure <string>("Failed eagerly creating symlinks"));
                }
            }

            return(maybeSymlinkDefinitions);
        }