private async Task RunBuildCacheAsync(
            Context context, BuildCacheServiceConfiguration config, Func <ICache, Task> funcAsync)
        {
            VssCredentialsFactory credentialsFactory = new VssCredentialsFactory(new VsoCredentialHelper());
            ICache cache = BuildCacheCacheFactory.Create(_fileSystem, _logger, credentialsFactory, config, null);

            using (cache)
            {
                BoolResult r = await cache.StartupAsync(context);

                if (!r.Succeeded)
                {
                    _tracer.Error(context, $"Failed to start up BuildCache client. Result=[{r}]");
                    return;
                }

                try
                {
                    await funcAsync(cache);
                }
                finally
                {
                    r = await cache.ShutdownAsync(context);

                    if (!r.Succeeded)
                    {
                        _tracer.Error(context, $"Failed to shut down BuildCache client. Result=[{r}]");
                    }
                }
            }
        }
예제 #2
0
        internal static BuildXL.Cache.MemoizationStore.Interfaces.Caches.ICache CreateBuildCacheCache <T>(T cacheConfig, ILogger logger, string pat = null) where T : BuildCacheCacheConfig
        {
            // TODO: Remove check when all clients are updated with unified Dedup flag
            if ((ContentHashingUtilities.HashInfo.HashType.IsValidDedup()) ^ cacheConfig.UseDedupStore)
            {
                var store = cacheConfig.UseDedupStore ? "DedupStore" : "BlobStore";
                throw new ArgumentException($"HashType {ContentHashingUtilities.HashInfo.HashType} cannot be used with {store}");
            }

            var credentialProviderHelper = new CredentialProviderHelper(m => logger.Debug(m));

            if (credentialProviderHelper.IsCredentialProviderSpecified())
            {
                logger.Debug($"Credential providers path specified: '{credentialProviderHelper.CredentialHelperPath}'");
            }
            else
            {
                logger.Debug("Using current user's credentials for obtaining AAD token");
            }

            var credentialsFactory = new VssCredentialsFactory(pat, credentialProviderHelper, m => logger.Debug(m));

            logger.Diagnostic("Creating BuildCacheCache factory");
            var fileSystem = new PassThroughFileSystem(logger);

            // TODO: Once write-behind is implemented send a contentstorefunc down to the create.
            Func <IContentStore> writeThroughStore = null;

            if (!string.IsNullOrWhiteSpace(cacheConfig.CacheName))
            {
                ServiceClientRpcConfiguration rpcConfiguration;
                if (cacheConfig.GrpcPort != 0)
                {
                    rpcConfiguration = new ServiceClientRpcConfiguration((int)cacheConfig.GrpcPort);
                }
                else
                {
                    var factory    = new MemoryMappedFileGrpcPortSharingFactory(logger, cacheConfig.GrpcPortFileName);
                    var portReader = factory.GetPortReader();
                    var port       = portReader.ReadPort();

                    rpcConfiguration = new ServiceClientRpcConfiguration(port);
                }

                writeThroughStore = () =>
                                    new ServiceClientContentStore(
                    logger,
                    fileSystem,
                    cacheConfig.CacheName,
                    rpcConfiguration,
                    cacheConfig.ConnectionRetryIntervalSeconds,
                    cacheConfig.ConnectionRetryCount,
                    scenario: cacheConfig.ScenarioName);
            }

            BuildCacheServiceConfiguration buildCacheServiceConfiguration = cacheConfig.AsBuildCacheServiceConfigurationFile();

            return(BuildCacheCacheFactory.Create(fileSystem, logger, credentialsFactory, buildCacheServiceConfiguration, writeThroughStore));
        }
예제 #3
0
 protected override ICachePublisher CreatePublisher(
     string sessionName,
     BuildCacheServiceConfiguration config,
     string pat,
     Context context)
 {
     sessionName.Should().NotBeNull();
     return(new DummyPublisher(config.ForceUpdateOnAddContentHashList));
 }
예제 #4
0
 public BuildCacheTestPublishingSession(
     BuildCacheServiceConfiguration config,
     string name,
     string pat,
     IContentSession contentSource,
     IAbsFileSystem fileSystem,
     SemaphoreSlim publishingGate)
     : base(config, name, pat, contentSource, fileSystem, publishingGate)
 {
 }
        internal void IncorporateStrongFingerprints(
            [Required, Description("Path to log containing the strong fingerpints")] string log,
            [Required, Description("BuildCache url to which to incorporate the fingerprints")] string buildCacheUrl,
            [Required, Description("BlobStore url associated to the buildCache url")] string blobStoreUrl,
            [Required, Description("Cache namespace to target within BuildCache")] string cacheNamespace,
            [Required, Description("Whether or not to use the newer Blob implementation of BuildCache")] bool useBlobContentHashLists,
            [DefaultValue(false), Description("Whether or not to use aad authentication")] bool useAad,
            [DefaultValue(null), Description("Maximum number of fingerprint batches sent in parallel within a set. Default: System.Environment.ProcessorCount")] int?maxDegreeOfParallelism,
            [DefaultValue(null), Description("Maximum number of fingerprints per batch within a set. Default: 500")] int?maxFingerprintsPerRequest,
            [DefaultValue(1), Description("How many times to incorporate the set of fingerprints")] int iterationCount,
            [DefaultValue(1), Description("How many sets of fingerprints to incorporate in parallel")] int iterationDegreeOfParallelism)
        {
            Initialize();

            Stopwatch    stopwatch = Stopwatch.StartNew();
            int          count     = 0;
            AbsolutePath logPath   = new AbsolutePath(log);

            if (!_fileSystem.FileExists(logPath))
            {
                throw new ArgumentException($"Log file {log} does not exist.", nameof(log));
            }

            BuildCacheServiceConfiguration config = new BuildCacheServiceConfiguration(buildCacheUrl, blobStoreUrl)
            {
                CacheNamespace                  = cacheNamespace,
                UseAad                          = useAad,
                UseBlobContentHashLists         = useBlobContentHashLists,
                FingerprintIncorporationEnabled = true
            };

            if (maxDegreeOfParallelism.HasValue)
            {
                config.MaxDegreeOfParallelismForIncorporateRequests = maxDegreeOfParallelism.Value;
            }

            if (maxFingerprintsPerRequest.HasValue)
            {
                config.MaxFingerprintsPerIncorporateRequest = maxFingerprintsPerRequest.Value;
            }

            using (var logStream = _fileSystem.OpenReadOnlySafeAsync(logPath, FileShare.Read | FileShare.Delete).Result)
                using (StreamReader reader = new StreamReader(logStream))
                {
                    Context context = new Context(_logger);
                    RunBuildCacheAsync(
                        context,
                        config,
                        async cache =>
                    {
                        const string sessionName      = "CommandLineSessionName";
                        const ImplicitPin implicitPin = ImplicitPin.None;

                        List <StrongFingerprint> strongFingerprints = EnumerateUniqueStrongFingerprints(reader).ToList();
                        count = strongFingerprints.Count;
                        _logger.Always($"Incorporating {count} strong fingerprints {iterationCount} times");

                        ActionBlock <List <StrongFingerprint> > incorporateBlock =
                            new ActionBlock <List <StrongFingerprint> >(
                                async fingerprints =>
                        {
                            var iterationStopwatch = Stopwatch.StartNew();
                            var iterationContext   = context.CreateNested(nameof(IncorporateStrongFingerprints));
                            CreateSessionResult <ICacheSession> createSessionResult = cache.CreateSession(
                                iterationContext, sessionName, implicitPin);
                            if (!createSessionResult.Succeeded)
                            {
                                _tracer.Error(iterationContext, $"Failed to create BuildCache session. Result=[{createSessionResult}]");
                                return;
                            }

                            using (ICacheSession session = createSessionResult.Session)
                            {
                                BoolResult r = await session.StartupAsync(iterationContext);
                                if (!r.Succeeded)
                                {
                                    _tracer.Error(iterationContext, $"Failed to start up BuildCache client session. Result=[{r}]");
                                    return;
                                }

                                try
                                {
                                    await session.IncorporateStrongFingerprintsAsync(
                                        iterationContext, strongFingerprints.AsTasks(), CancellationToken.None).IgnoreFailure();
                                }
                                finally
                                {
                                    iterationStopwatch.Stop();
                                    r = await session.ShutdownAsync(iterationContext);
                                    if (r.Succeeded)
                                    {
                                        _tracer.Always(context,
                                                       $"Incorporated {count} fingerprints in {iterationStopwatch.ElapsedMilliseconds / 1000} seconds.");
                                    }
                                    else
                                    {
                                        _tracer.Error(iterationContext, $"Failed to shut down BuildCache client Session. Result=[{r}]");
                                    }
                                }
                            }
                        },
                                new ExecutionDataflowBlockOptions {
                            MaxDegreeOfParallelism = iterationDegreeOfParallelism
                        });

                        for (int i = 0; i < iterationCount; i++)
                        {
                            await incorporateBlock.SendAsync(strongFingerprints);
                        }

                        incorporateBlock.Complete();

                        await incorporateBlock.Completion;
                    }).Wait();
                }

            stopwatch.Stop();
            _logger.Always($"Incorporated {count} unique strong fingerprints {iterationCount} times in {stopwatch.ElapsedMilliseconds / 1000} seconds.");
        }
예제 #6
0
        internal static BuildXL.Cache.MemoizationStore.Interfaces.Caches.ICache CreateBuildCacheCache <T>(T cacheConfig, ILogger logger, string pat = null) where T : BuildCacheCacheConfig
        {
            // TODO: Remove check when all clients are updated with unified Dedup flag
            if (ContentHashingUtilities.HashInfo.HashType == HashType.DedupNodeOrChunk ^ cacheConfig.UseDedupStore)
            {
                var store = cacheConfig.UseDedupStore ? "DedupStore" : "BlobStore";
                throw new ArgumentException($"HashType {ContentHashingUtilities.HashInfo.HashType} cannot be used with {store}");
            }

            string credentialProviderPath = Environment.GetEnvironmentVariable(CredentialProvidersPathEnvVariable);

            if (!string.IsNullOrWhiteSpace(credentialProviderPath))
            {
                logger.Debug($"Credential providers path specified: {credentialProviderPath}");
            }
            else
            {
                logger.Debug("Using current user's credentials for obtaining AAD token");
            }

            VssCredentialsFactory credentialsFactory;

#if !PLATFORM_OSX
            string userName = null; // when running on .NET Framework, user name doesn't have to be explicitly provided
#if FEATURE_CORECLR
            userName = GetAadUserNameUpn();
#endif
            credentialsFactory = new VssCredentialsFactory(new VsoCredentialHelper(s => logger.Debug(s)), userName);
#else
            var secPat = new SecureString();
            if (!string.IsNullOrWhiteSpace(pat))
            {
                foreach (char c in pat)
                {
                    secPat.AppendChar(c);
                }
            }
            else
            {
                throw new ArgumentException("PAT must be supplied when running with CoreCLR");
            }

            credentialsFactory = new VssCredentialsFactory(new VssBasicCredential(new NetworkCredential(string.Empty, secPat)));
#endif

            logger.Diagnostic("Creating BuildCacheCache factory");
            var fileSystem = new PassThroughFileSystem(logger);

            // TODO: Once write-behind is implemented send a contentstorefunc down to the create.
            Func <IContentStore> writeThroughStore = null;
            if (!string.IsNullOrWhiteSpace(cacheConfig.CacheName))
            {
                ServiceClientRpcConfiguration rpcConfiguration;
                if (cacheConfig.GrpcPort != 0)
                {
                    rpcConfiguration = new ServiceClientRpcConfiguration((int)cacheConfig.GrpcPort);
                }
                else
                {
                    var factory    = new MemoryMappedFileGrpcPortSharingFactory(logger, cacheConfig.GrpcPortFileName);
                    var portReader = factory.GetPortReader();
                    var port       = portReader.ReadPort();

                    rpcConfiguration = new ServiceClientRpcConfiguration(port);
                }

                writeThroughStore = () =>
                                    new ServiceClientContentStore(
                    logger,
                    fileSystem,
                    cacheConfig.CacheName,
                    rpcConfiguration,
                    cacheConfig.ConnectionRetryIntervalSeconds,
                    cacheConfig.ConnectionRetryCount,
                    scenario: cacheConfig.ScenarioName);
            }

            BuildCacheServiceConfiguration buildCacheServiceConfiguration = cacheConfig.AsBuildCacheServiceConfigurationFile();
            return(BuildCacheCacheFactory.Create(fileSystem, logger, credentialsFactory, buildCacheServiceConfiguration, writeThroughStore));
        }
예제 #7
0
        internal static BuildXL.Cache.MemoizationStore.Interfaces.Caches.ICache CreateBuildCacheCache <T>(T cacheConfig, ILogger logger, string pat = null) where T : BuildCacheCacheConfig
        {
            // TODO: Remove check when all clients are updated with unified Dedup flag
            if ((ContentHashingUtilities.HashInfo.HashType.IsValidDedup()) ^ cacheConfig.UseDedupStore)
            {
                var store = cacheConfig.UseDedupStore ? "DedupStore" : "BlobStore";
                throw new ArgumentException($"HashType {ContentHashingUtilities.HashInfo.HashType} cannot be used with {store}");
            }

            string credentialProviderPath        = Environment.GetEnvironmentVariable(CredentialProvidersPathEnvVariable);
            bool   isCredentialProviderSpecified = !string.IsNullOrWhiteSpace(credentialProviderPath);

            if (isCredentialProviderSpecified)
            {
                logger.Debug($"Credential providers path specified: {credentialProviderPath}");
            }
            else
            {
                logger.Debug("Using current user's credentials for obtaining AAD token");
            }

            VssCredentialsFactory credentialsFactory;

#if PLATFORM_WIN
            // Obtain and explicitly specify AAD user name ONLY when
            //   (1) no credential provider is specified, and
            //   (2) running on .NET Core.
            // When a credential provider is specified, specifying AAD user name will override it and we don't want to do that.
            // When running on .NET Framework, VsoCredentialHelper will automatically obtain currently logged on AAD user name.
            string userName = !isCredentialProviderSpecified && Utilities.OperatingSystemHelper.IsDotNetCore
                ? GetAadUserNameUpn()
                : null;
            credentialsFactory = new VssCredentialsFactory(new VsoCredentialHelper(s => logger.Debug(s)), userName);
#else
            var secPat = new SecureString();
            if (!string.IsNullOrWhiteSpace(pat))
            {
                foreach (char c in pat)
                {
                    secPat.AppendChar(c);
                }
            }
            else
            {
                throw new ArgumentException("PAT must be supplied when not running on Windows");
            }

            credentialsFactory = new VssCredentialsFactory(new VssBasicCredential(new NetworkCredential(string.Empty, secPat)));
#endif

            logger.Diagnostic("Creating BuildCacheCache factory");
            var fileSystem = new PassThroughFileSystem(logger);

            // TODO: Once write-behind is implemented send a contentstorefunc down to the create.
            Func <IContentStore> writeThroughStore = null;
            if (!string.IsNullOrWhiteSpace(cacheConfig.CacheName))
            {
                ServiceClientRpcConfiguration rpcConfiguration;
                if (cacheConfig.GrpcPort != 0)
                {
                    rpcConfiguration = new ServiceClientRpcConfiguration((int)cacheConfig.GrpcPort);
                }
                else
                {
                    var factory    = new MemoryMappedFileGrpcPortSharingFactory(logger, cacheConfig.GrpcPortFileName);
                    var portReader = factory.GetPortReader();
                    var port       = portReader.ReadPort();

                    rpcConfiguration = new ServiceClientRpcConfiguration(port);
                }

                writeThroughStore = () =>
                                    new ServiceClientContentStore(
                    logger,
                    fileSystem,
                    cacheConfig.CacheName,
                    rpcConfiguration,
                    cacheConfig.ConnectionRetryIntervalSeconds,
                    cacheConfig.ConnectionRetryCount,
                    scenario: cacheConfig.ScenarioName);
            }

            BuildCacheServiceConfiguration buildCacheServiceConfiguration = cacheConfig.AsBuildCacheServiceConfigurationFile();
            return(BuildCacheCacheFactory.Create(fileSystem, logger, credentialsFactory, buildCacheServiceConfiguration, writeThroughStore));
        }