示例#1
0
        protected override void Execute(GVFSEnlistment enlistment)
        {
            this.BlockEmptyCacheServerUrl(this.CacheToSet);

            RetryConfig retryConfig = new RetryConfig(RetryConfig.DefaultMaxRetries, TimeSpan.FromMinutes(RetryConfig.FetchAndCloneTimeoutMinutes));

            using (ITracer tracer = new JsonTracer(GVFSConstants.GVFSEtwProviderName, "CacheVerb"))
            {
                string authErrorMessage;
                if (!this.TryAuthenticate(tracer, enlistment, out authErrorMessage))
                {
                    this.ReportErrorAndExit(tracer, "Authentication failed: " + authErrorMessage);
                }

                ServerGVFSConfig serverGVFSConfig = this.QueryGVFSConfig(tracer, enlistment, retryConfig);

                CacheServerResolver cacheServerResolver = new CacheServerResolver(tracer, enlistment);
                string error = null;

                if (this.CacheToSet != null)
                {
                    CacheServerInfo cacheServer = cacheServerResolver.ParseUrlOrFriendlyName(this.CacheToSet);
                    cacheServer = this.ResolveCacheServer(tracer, cacheServer, cacheServerResolver, serverGVFSConfig);

                    if (!cacheServerResolver.TrySaveUrlToLocalConfig(cacheServer, out error))
                    {
                        this.ReportErrorAndExit("Failed to save cache to config: " + error);
                    }

                    this.Output.WriteLine("You must remount GVFS for this to take effect.");
                }
                else if (this.ListCacheServers)
                {
                    List <CacheServerInfo> cacheServers = serverGVFSConfig.CacheServers.ToList();

                    if (cacheServers != null && cacheServers.Any())
                    {
                        this.Output.WriteLine();
                        this.Output.WriteLine("Available cache servers");
                        foreach (CacheServerInfo cacheServer in cacheServers)
                        {
                            this.Output.WriteLine("server.");
                        }
                    }
                    else
                    {
                        this.Output.WriteLine("There are no available cache servers for: " + enlistment.RepoUrl);
                    }
                }
                else
                {
                    string          cacheServerUrl = CacheServerResolver.GetUrlFromConfig(enlistment);
                    CacheServerInfo cacheServer    = cacheServerResolver.ResolveNameFromRemote(cacheServerUrl, serverGVFSConfig);
                    this.Output.WriteLine("Using cache server");
                }
            }
        }
示例#2
0
 public InProcessMount(ITracer tracer, GVFSEnlistment enlistment, CacheServerInfo cacheServer, RetryConfig retryConfig, bool showDebugWindow)
 {
     this.tracer          = tracer;
     this.retryConfig     = retryConfig;
     this.cacheServer     = cacheServer;
     this.enlistment      = enlistment;
     this.showDebugWindow = showDebugWindow;
     this.unmountEvent    = new ManualResetEvent(false);
 }
示例#3
0
        private string GetCacheServerDisplay(CacheServerInfo cacheServer, string repoUrl)
        {
            if (!cacheServer.IsNone(repoUrl))
            {
                return("from cache server");
            }

            return("from origin (no cache server)");
        }
        private string GetCacheServerDisplay(CacheServerInfo cacheServer)
        {
            if (cacheServer.Name != null && !cacheServer.Name.Equals(CacheServerInfo.ReservedNames.None))
            {
                return("from cache server");
            }

            return("from origin (no cache server)");
        }
示例#5
0
        private string GetCacheServerDisplay(CacheServerInfo cacheServer)
        {
            if (cacheServer.HasResolvedName())
            {
                return("from " + cacheServer.Name + " cache server");
            }

            return("from " + cacheServer.Url);
        }
示例#6
0
        public void Execute()
        {
            GVFSEnlistment enlistment = this.CreateEnlistment(this.EnlistmentRootPathParameter);

            EventLevel verbosity;
            Keywords   keywords;

            this.ParseEnumArgs(out verbosity, out keywords);

            JsonTracer tracer = this.CreateTracer(enlistment, verbosity, keywords);

            CacheServerInfo cacheServer = CacheServerResolver.GetCacheServerFromConfig(enlistment);

            tracer.WriteStartEvent(
                enlistment.EnlistmentRoot,
                enlistment.RepoUrl,
                cacheServer.Url,
                new EventMetadata
            {
                { "IsElevated", GVFSPlatform.Instance.IsElevated() },
                { nameof(this.EnlistmentRootPathParameter), this.EnlistmentRootPathParameter },
                { nameof(this.StartedByService), this.StartedByService },
            });

            AppDomain.CurrentDomain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) =>
            {
                this.UnhandledGVFSExceptionHandler(tracer, sender, e);
            };

            string      error;
            RetryConfig retryConfig;

            if (!RetryConfig.TryLoadFromGitConfig(tracer, enlistment, out retryConfig, out error))
            {
                this.ReportErrorAndExit(tracer, "Failed to determine GVFS timeout and max retries: " + error);
            }

            GitStatusCacheConfig gitStatusCacheConfig;

            if (!GitStatusCacheConfig.TryLoadFromGitConfig(tracer, enlistment, out gitStatusCacheConfig, out error))
            {
                tracer.RelatedWarning("Failed to determine GVFS status cache backoff time: " + error);
                gitStatusCacheConfig = GitStatusCacheConfig.DefaultConfig;
            }

            InProcessMount mountHelper = new InProcessMount(tracer, enlistment, cacheServer, retryConfig, gitStatusCacheConfig, this.ShowDebugWindow);

            try
            {
                mountHelper.Mount(verbosity, keywords);
            }
            catch (Exception ex)
            {
                this.ReportErrorAndExit(tracer, "Failed to mount: {0}", ex.Message);
            }
        }
示例#7
0
        public void CanResolveNameFromCustomUrl()
        {
            const string CustomUrl = "https://not/a/known/cache/server";

            CacheServerResolver resolver            = this.CreateResolver();
            CacheServerInfo     resolvedCacheServer = resolver.ResolveNameFromRemote(CustomUrl, this.CreateGVFSConfig());

            resolvedCacheServer.Url.ShouldEqual(CustomUrl);
            resolvedCacheServer.Name.ShouldEqual(CacheServerInfo.ReservedNames.UserDefined);
        }
示例#8
0
        private void MountAndStartWorkingDirectoryCallbacks(CacheServerInfo cache)
        {
            string error;

            if (!this.context.Enlistment.Authentication.TryInitialize(this.context.Tracer, this.context.Enlistment, out error))
            {
                this.FailMountAndExit("Failed to obtain git credentials: " + error);
            }

            GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(this.context.Tracer, this.context.Enlistment, cache, this.retryConfig);

            this.gitObjects = new GVFSGitObjects(this.context, objectRequestor);
            FileSystemVirtualizer virtualizer = this.CreateOrReportAndExit(() => GVFSPlatformLoader.CreateFileSystemVirtualizer(this.context, this.gitObjects), "Failed to create src folder virtualizer");

            GitStatusCache gitStatusCache = (!this.context.Unattended && GVFSPlatform.Instance.IsGitStatusCacheSupported()) ? new GitStatusCache(this.context, this.gitStatusCacheConfig) : null;

            if (gitStatusCache != null)
            {
                this.tracer.RelatedInfo("Git status cache enabled. Backoff time: {0}ms", this.gitStatusCacheConfig.BackoffTime.TotalMilliseconds);
            }

            this.fileSystemCallbacks  = this.CreateOrReportAndExit(() => new FileSystemCallbacks(this.context, this.gitObjects, RepoMetadata.Instance, virtualizer, gitStatusCache), "Failed to create src folder callback listener");
            this.maintenanceScheduler = this.CreateOrReportAndExit(() => new GitMaintenanceScheduler(this.context, this.gitObjects), "Failed to start maintenance scheduler");

            int majorVersion;
            int minorVersion;

            if (!RepoMetadata.Instance.TryGetOnDiskLayoutVersion(out majorVersion, out minorVersion, out error))
            {
                this.FailMountAndExit("Error: {0}", error);
            }

            if (majorVersion != RepoMetadata.DiskLayoutVersion.CurrentMajorVersion)
            {
                this.FailMountAndExit(
                    "Error: On disk version ({0}) does not match current version ({1})",
                    majorVersion,
                    RepoMetadata.DiskLayoutVersion.CurrentMajorVersion);
            }

            try
            {
                if (!this.fileSystemCallbacks.TryStart(out error))
                {
                    this.FailMountAndExit("Error: {0}. \r\nPlease confirm that gvfs clone completed without error.", error);
                }
            }
            catch (Exception e)
            {
                this.FailMountAndExit("Failed to initialize src folder callbacks. {0}", e.ToString());
            }

            this.heartbeat = new HeartbeatThread(this.tracer, this.fileSystemCallbacks);
            this.heartbeat.Start();
        }
示例#9
0
        private FileSystemCallbacks CreateFileSystemCallbacks()
        {
            string error;

            if (!RepoMetadata.TryInitialize(this.Context.Tracer, this.Enlistment.DotGVFSRoot, out error))
            {
                throw new InvalidRepoException(error);
            }

            string gitObjectsRoot;

            if (!RepoMetadata.Instance.TryGetGitObjectsRoot(out gitObjectsRoot, out error))
            {
                throw new InvalidRepoException("Failed to determine git objects root from repo metadata: " + error);
            }

            string localCacheRoot;

            if (!RepoMetadata.Instance.TryGetLocalCacheRoot(out localCacheRoot, out error))
            {
                throw new InvalidRepoException("Failed to determine local cache path from repo metadata: " + error);
            }

            string blobSizesRoot;

            if (!RepoMetadata.Instance.TryGetBlobSizesRoot(out blobSizesRoot, out error))
            {
                throw new InvalidRepoException("Failed to determine blob sizes root from repo metadata: " + error);
            }

            this.Enlistment.InitializeCachePaths(localCacheRoot, gitObjectsRoot, blobSizesRoot);

            CacheServerInfo         cacheServer     = new CacheServerInfo(this.Context.Enlistment.RepoUrl, "None");
            GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(
                this.Context.Tracer,
                this.Context.Enlistment,
                cacheServer,
                new RetryConfig());

            this.gvfsDatabase = new GVFSDatabase(this.Context.FileSystem, this.Context.Enlistment.EnlistmentRoot, new SqliteDatabase());
            GVFSGitObjects gitObjects = new GVFSGitObjects(this.Context, objectRequestor);

            return(new FileSystemCallbacks(
                       this.Context,
                       gitObjects,
                       RepoMetadata.Instance,
                       blobSizes: null,
                       gitIndexProjection: null,
                       backgroundFileSystemTaskRunner: null,
                       fileSystemVirtualizer: null,
                       placeholderDatabase: new PlaceholderTable(this.gvfsDatabase),
                       sparseCollection: new SparseTable(this.gvfsDatabase),
                       gitStatusCache: null));
        }
示例#10
0
        private Result TryClone(JsonEtwTracer tracer, GVFSEnlistment enlistment, CacheServerInfo cacheServer, RetryConfig retryConfig)
        {
            Result pipeResult;

            using (NamedPipeServer pipeServer = this.StartNamedPipe(tracer, enlistment, out pipeResult))
            {
                if (!pipeResult.Success)
                {
                    return(pipeResult);
                }

                using (GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(tracer, enlistment, cacheServer, retryConfig))
                {
                    GitRefs refs = objectRequestor.QueryInfoRefs(this.SingleBranch ? this.Branch : null);

                    if (refs == null)
                    {
                        return(new Result("Could not query info/refs from: " + Uri.EscapeUriString(enlistment.RepoUrl)));
                    }

                    if (this.Branch == null)
                    {
                        this.Branch = refs.GetDefaultBranch();

                        EventMetadata metadata = new EventMetadata();
                        metadata.Add("Branch", this.Branch);
                        tracer.RelatedEvent(EventLevel.Informational, "CloneDefaultRemoteBranch", metadata);
                    }
                    else
                    {
                        if (!refs.HasBranch(this.Branch))
                        {
                            EventMetadata metadata = new EventMetadata();
                            metadata.Add("Branch", this.Branch);
                            tracer.RelatedEvent(EventLevel.Warning, "CloneBranchDoesNotExist", metadata);

                            string errorMessage = string.Format("Remote branch {0} not found in upstream origin", this.Branch);
                            return(new Result(errorMessage));
                        }
                    }

                    if (!enlistment.TryCreateEnlistmentFolders())
                    {
                        string error = "Could not create enlistment directory";
                        tracer.RelatedError(error);
                        return(new Result(error));
                    }

                    CloneHelper cloneHelper = new CloneHelper(tracer, enlistment, objectRequestor);
                    return(cloneHelper.CreateClone(refs, this.Branch));
                }
            }
        }
        private void MountAndStartWorkingDirectoryCallbacks(CacheServerInfo cache)
        {
            string error;

            if (!this.context.Enlistment.Authentication.TryRefreshCredentials(this.context.Tracer, out error))
            {
                this.FailMountAndExit("Failed to obtain git credentials: " + error);
            }

            GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(this.context.Tracer, this.context.Enlistment, cache, this.retryConfig);

            this.gitObjects = new GVFSGitObjects(this.context, objectRequestor);
            FileSystemVirtualizer virtualizer = this.CreateOrReportAndExit(() => GVFSPlatformLoader.CreateFileSystemVirtualizer(this.context, this.gitObjects), "Failed to create src folder virtualizer");

            this.fileSystemCallbacks = this.CreateOrReportAndExit(() => new FileSystemCallbacks(this.context, this.gitObjects, RepoMetadata.Instance, virtualizer), "Failed to create src folder callback listener");

            if (!this.context.Unattended)
            {
                this.prefetcher = this.CreateOrReportAndExit(() => new BackgroundPrefetcher(this.tracer, this.enlistment, this.context.FileSystem, this.gitObjects), "Failed to start background prefetcher");
            }

            int majorVersion;
            int minorVersion;

            if (!RepoMetadata.Instance.TryGetOnDiskLayoutVersion(out majorVersion, out minorVersion, out error))
            {
                this.FailMountAndExit("Error: {0}", error);
            }

            if (majorVersion != RepoMetadata.DiskLayoutVersion.CurrentMajorVersion)
            {
                this.FailMountAndExit(
                    "Error: On disk version ({0}) does not match current version ({1})",
                    majorVersion,
                    RepoMetadata.DiskLayoutVersion.CurrentMajorVersion);
            }

            try
            {
                if (!this.fileSystemCallbacks.TryStart(out error))
                {
                    this.FailMountAndExit("Error: {0}. \r\nPlease confirm that gvfs clone completed without error.", error);
                }
            }
            catch (Exception e)
            {
                this.FailMountAndExit("Failed to initialize src folder callbacks. {0}", e.ToString());
            }

            this.heartbeat = new HeartbeatThread(this.tracer, this.fileSystemCallbacks);
            this.heartbeat.Start();
        }
示例#12
0
        public void ParsesUserSuppliedFriendlyName()
        {
            string          error;
            CacheServerInfo output;

            CacheServerInfo.TryDetermineCacheServer(
                UserSuppliedCacheName,
                gitProcess: null,
                enlistment: this.enlistment,
                knownCaches: KnownCaches,
                output: out output,
                error: out error).ShouldBeTrue(error);
            output.Url.ShouldEqual(UserSuppliedUrl);
        }
示例#13
0
        public void FailsToParseInvalidUserSuppliedFriendlyName()
        {
            string          error;
            CacheServerInfo output;

            CacheServerInfo.TryDetermineCacheServer(
                "invalidCacheName",
                gitProcess: null,
                enlistment: this.enlistment,
                knownCaches: KnownCaches,
                output: out output,
                error: out error).ShouldBeFalse();
            output.ShouldBeNull();
        }
示例#14
0
        private void MountAndStartWorkingDirectoryCallbacks(GVFSContext context, CacheServerInfo cache)
        {
            string error;

            if (!context.Enlistment.Authentication.TryRefreshCredentials(context.Tracer, out error))
            {
                this.FailMountAndExit("Failed to obtain git credentials: " + error);
            }

            // Checking the disk layout version is done before this point in GVFS.CommandLine.MountVerb
            RepoMetadata            repoMetadata    = new RepoMetadata(this.enlistment.DotGVFSRoot);
            GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(context.Tracer, context.Enlistment, cache, this.retryConfig);

            this.gitObjects     = new GVFSGitObjects(context, objectRequestor);
            this.gvfltCallbacks = this.CreateOrReportAndExit(() => new GVFltCallbacks(context, this.gitObjects, repoMetadata), "Failed to create src folder callbacks");

            int persistedVersion;

            if (!repoMetadata.TryGetOnDiskLayoutVersion(out persistedVersion, out error))
            {
                this.FailMountAndExit("Error: {0}", error);
            }

            try
            {
                if (!this.gvfltCallbacks.TryStart(out error))
                {
                    this.FailMountAndExit("Error: {0}. \r\nPlease confirm that gvfs clone completed without error.", error);
                }
            }
            catch (Exception e)
            {
                this.FailMountAndExit("Failed to initialize src folder callbacks. {0}", e.ToString());
            }

            try
            {
                repoMetadata.SaveCurrentDiskLayoutVersion();
            }
            catch (Exception ex)
            {
                this.FailMountAndExit("Failed to update repo disk layout version: {0}", ex.ToString());
            }

            this.AcquireFolderLocks(context);

            this.heartbeat = new HeartbeatThread(this.tracer, this.gvfltCallbacks);
            this.heartbeat.Start();
        }
示例#15
0
        public void Execute()
        {
            GVFSEnlistment enlistment = this.CreateEnlistment(this.EnlistmentRootPath);

            EventLevel verbosity;
            Keywords   keywords;

            this.ParseEnumArgs(out verbosity, out keywords);

            JsonEtwTracer tracer = this.CreateTracer(enlistment, verbosity, keywords);

            CacheServerInfo cacheServer = CacheServerResolver.GetCacheServerFromConfig(enlistment);

            tracer.WriteStartEvent(
                enlistment.EnlistmentRoot,
                enlistment.RepoUrl,
                cacheServer.Url,
                enlistment.GitObjectsRoot,
                new EventMetadata
            {
                { "IsElevated", ProcessHelper.IsAdminElevated() },
            });

            AppDomain.CurrentDomain.UnhandledException += (object sender, UnhandledExceptionEventArgs e) =>
            {
                this.UnhandledGVFSExceptionHandler(tracer, sender, e);
            };

            RetryConfig retryConfig;
            string      error;

            if (!RetryConfig.TryLoadFromGitConfig(tracer, enlistment, out retryConfig, out error))
            {
                this.ReportErrorAndExit("Failed to determine GVFS timeout and max retries: " + error);
            }

            InProcessMount mountHelper = new InProcessMount(tracer, enlistment, cacheServer, retryConfig, this.ShowDebugWindow);

            try
            {
                mountHelper.Mount(verbosity, keywords);
            }
            catch (Exception ex)
            {
                tracer.RelatedError("Failed to mount: {0}", ex.ToString());
                this.ReportErrorAndExit("Failed to mount: {0}", ex.Message);
            }
        }
示例#16
0
        private bool TryDownloadGitObjects(ITracer tracer, GVFSEnlistment enlistment)
        {
            string errorMessage = null;

            if (!this.ShowStatusWhileRunning(
                    () =>
            {
                RetryConfig retryConfig;
                if (!RetryConfig.TryLoadFromGitConfig(tracer, enlistment, out retryConfig, out errorMessage))
                {
                    errorMessage = "Failed to determine GVFS timeout and max retries: " + errorMessage;
                    return(false);
                }

                CacheServerInfo cacheServer = new CacheServerInfo(enlistment.RepoUrl, null);
                using (GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(tracer, enlistment, cacheServer, retryConfig))
                {
                    PhysicalFileSystem fileSystem = new PhysicalFileSystem();
                    GitRepo gitRepo = new GitRepo(tracer, enlistment, fileSystem);
                    GVFSGitObjects gitObjects = new GVFSGitObjects(new GVFSContext(tracer, fileSystem, gitRepo, enlistment), objectRequestor);

                    GitProcess.Result revParseResult = enlistment.CreateGitProcess().RevParse("HEAD");
                    if (revParseResult.HasErrors)
                    {
                        errorMessage = "Unable to determine HEAD commit id: " + revParseResult.Errors;
                        return(false);
                    }

                    string headCommit = revParseResult.Output.TrimEnd('\n');

                    if (!this.TryDownloadCommit(headCommit, enlistment, objectRequestor, gitObjects, gitRepo, out errorMessage) ||
                        !this.TryDownloadRootGitAttributes(enlistment, gitObjects, gitRepo, out errorMessage))
                    {
                        return(false);
                    }
                }

                return(true);
            },
                    "Downloading git objects",
                    suppressGvfsLogMessage: true))
            {
                this.WriteMessage(tracer, errorMessage);
                return(false);
            }

            return(true);
        }
示例#17
0
        private void InitializeServerConnection(
            ITracer tracer,
            ScalarEnlistment enlistment,
            string cacheServerUrl,
            out GitObjectsHttpRequestor objectRequestor,
            out CacheServerInfo cacheServer)
        {
            if (!enlistment.UsesGvfsProtocol)
            {
                objectRequestor = null;
                cacheServer     = null;
                return;
            }

            RetryConfig retryConfig = this.GetRetryConfig(tracer, enlistment, TimeSpan.FromMinutes(RetryConfig.FetchAndCloneTimeoutMinutes));

            cacheServer = this.ResolvedCacheServer;
            ServerScalarConfig serverScalarConfig = this.ServerScalarConfig;

            if (!this.SkipVersionCheck)
            {
                string authErrorMessage;
                if (!this.TryAuthenticate(tracer, enlistment, out authErrorMessage))
                {
                    this.ReportErrorAndExit(tracer, "Unable to fetch because authentication failed: " + authErrorMessage);
                }

                if (serverScalarConfig == null)
                {
                    serverScalarConfig = this.QueryScalarConfig(tracer, enlistment, retryConfig);
                }

                if (cacheServer == null)
                {
                    CacheServerResolver cacheServerResolver = new CacheServerResolver(tracer, enlistment);
                    cacheServer = cacheServerResolver.ResolveNameFromRemote(cacheServerUrl, serverScalarConfig);
                }

                this.ValidateClientVersions(tracer, enlistment, serverScalarConfig, showWarnings: false);

                this.Output.WriteLine("Configured cache server: " + cacheServer);
            }

            this.InitializeCachePaths(tracer, enlistment);
            objectRequestor = new GitObjectsHttpRequestor(tracer, enlistment, cacheServer, retryConfig);
        }
示例#18
0
        public void CanParseAndResolveDefault()
        {
            CacheServerResolver resolver = this.CreateResolver();

            CacheServerInfo parsedCacheServer = resolver.ParseUrlOrFriendlyName(null);

            parsedCacheServer.Url.ShouldEqual(null);
            parsedCacheServer.Name.ShouldEqual(CacheServerInfo.ReservedNames.Default);

            CacheServerInfo resolvedCacheServer;
            string          error;

            resolver.TryResolveUrlFromRemote(parsedCacheServer.Name, this.CreateGVFSConfig(), out resolvedCacheServer, out error);

            resolvedCacheServer.Url.ShouldEqual(CacheServerUrl);
            resolvedCacheServer.Name.ShouldEqual(CacheServerName);
        }
示例#19
0
        private void MountAndStartWorkingDirectoryCallbacks(GVFSContext context, CacheServerInfo cache)
        {
            string error;

            if (!context.Enlistment.Authentication.TryRefreshCredentials(context.Tracer, out error))
            {
                this.FailMountAndExit("Failed to obtain git credentials: " + error);
            }

            GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(context.Tracer, context.Enlistment, cache, this.retryConfig);

            this.gitObjects     = new GVFSGitObjects(context, objectRequestor);
            this.gvfltCallbacks = this.CreateOrReportAndExit(() => new GVFltCallbacks(context, this.gitObjects, RepoMetadata.Instance), "Failed to create src folder callbacks");

            int persistedVersion;

            if (!RepoMetadata.Instance.TryGetOnDiskLayoutVersion(out persistedVersion, out error))
            {
                this.FailMountAndExit("Error: {0}", error);
            }

            if (persistedVersion != RepoMetadata.DiskLayoutVersion.CurrentDiskLayoutVersion)
            {
                this.FailMountAndExit(
                    "Error: On disk version ({0}) does not match current version ({1})",
                    persistedVersion,
                    RepoMetadata.DiskLayoutVersion.CurrentDiskLayoutVersion);
            }

            try
            {
                if (!this.gvfltCallbacks.TryStart(out error))
                {
                    this.FailMountAndExit("Error: {0}. \r\nPlease confirm that gvfs clone completed without error.", error);
                }
            }
            catch (Exception e)
            {
                this.FailMountAndExit("Failed to initialize src folder callbacks. {0}", e.ToString());
            }

            this.AcquireFolderLocks(context);

            this.heartbeat = new HeartbeatThread(this.tracer, this.gvfltCallbacks);
            this.heartbeat.Start();
        }
示例#20
0
        public void ParsesConfiguredCacheName()
        {
            MockGitProcess git = new MockGitProcess();

            git.SetExpectedCommandResult("config gvfs.cache-server", () => new GitProcess.Result(UserSuppliedCacheName, string.Empty, GitProcess.Result.SuccessCode));

            string          error;
            CacheServerInfo output;

            CacheServerInfo.TryDetermineCacheServer(
                userUrlish: null,
                gitProcess: git,
                enlistment: this.enlistment,
                knownCaches: KnownCaches,
                output: out output,
                error: out error).ShouldBeTrue(error);
            output.Url.ShouldEqual(UserSuppliedUrl);
        }
示例#21
0
        public void ResolvesUrlIntoFriendlyName()
        {
            MockGitProcess git = new MockGitProcess();

            string          error;
            CacheServerInfo output;

            CacheServerInfo.TryDetermineCacheServer(
                userUrlish: UserSuppliedUrl,
                gitProcess: git,
                enlistment: this.enlistment,
                knownCaches: KnownCaches,
                output: out output,
                error: out error).ShouldBeTrue(error);

            output.Name.ShouldEqual(UserSuppliedCacheName);
            output.Url.ShouldEqual(UserSuppliedUrl);
        }
示例#22
0
        private static CacheInitParams GetInitParams(ref ToolArgs toolArgs)
        {
            CacheInitParams initParams = new CacheInitParams();
            string          ip         = "";

            if (string.IsNullOrEmpty(toolArgs.Server))
            {
                return(initParams);
            }
            else
            {
                int port = toolArgs.Port != 0 ? toolArgs.Port : 9800;
                CacheServerInfo[] cacheServerInfos = new CacheServerInfo[1];
                cacheServerInfos[0]   = new CacheServerInfo(ip, port);
                initParams.ServerList = cacheServerInfos;
                return(initParams);
            }
        }
示例#23
0
        private FileSystemCallbacks CreateFileSystemCallbacks()
        {
            string error;

            if (!RepoMetadata.TryInitialize(this.Context.Tracer, this.Enlistment.DotGVFSRoot, out error))
            {
                throw new InvalidRepoException(error);
            }

            string gitObjectsRoot;

            if (!RepoMetadata.Instance.TryGetGitObjectsRoot(out gitObjectsRoot, out error))
            {
                throw new InvalidRepoException("Failed to determine git objects root from repo metadata: " + error);
            }

            string localCacheRoot;

            if (!RepoMetadata.Instance.TryGetLocalCacheRoot(out localCacheRoot, out error))
            {
                throw new InvalidRepoException("Failed to determine local cache path from repo metadata: " + error);
            }

            string blobSizesRoot;

            if (!RepoMetadata.Instance.TryGetBlobSizesRoot(out blobSizesRoot, out error))
            {
                throw new InvalidRepoException("Failed to determine blob sizes root from repo metadata: " + error);
            }

            this.Enlistment.InitializeCachePaths(localCacheRoot, gitObjectsRoot, blobSizesRoot);

            CacheServerInfo         cacheServer     = new CacheServerInfo(this.Context.Enlistment.RepoUrl, "None");
            GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(
                this.Context.Tracer,
                this.Context.Enlistment,
                cacheServer,
                new RetryConfig());

            GVFSGitObjects gitObjects = new GVFSGitObjects(this.Context, objectRequestor);

            return(new FileSystemCallbacks(this.Context, gitObjects, RepoMetadata.Instance, fileSystemVirtualizer: null));
        }
示例#24
0
        public void FallsBackToDeprecatedConfigSetting()
        {
            MockGitProcess git = new MockGitProcess();

            git.SetExpectedCommandResult(@"config gvfs.mock:\repourl.cache-server-url", () => new GitProcess.Result(UserSuppliedUrl, string.Empty, GitProcess.Result.SuccessCode));
            git.SetExpectedCommandResult(@"config --local  gvfs.cache-server " + UserSuppliedUrl, () => new GitProcess.Result(string.Empty, string.Empty, GitProcess.Result.SuccessCode));
            string          error;
            CacheServerInfo output;

            CacheServerInfo.TryDetermineCacheServer(
                userUrlish: null,
                gitProcess: git,
                enlistment: this.enlistment,
                knownCaches: null,
                output: out output,
                error: out error).ShouldBeTrue(error);

            output.Url.ShouldEqual(UserSuppliedUrl);
        }
示例#25
0
        public void Execute()
        {
            GVFSEnlistment enlistment = this.CreateEnlistment(this.EnlistmentRootPath);

            EventLevel verbosity;
            Keywords   keywords;

            this.ParseEnumArgs(out verbosity, out keywords);

            JsonEtwTracer tracer = this.CreateTracer(enlistment, verbosity, keywords);

            RetryConfig retryConfig;
            string      error;

            if (!RetryConfig.TryLoadFromGitConfig(tracer, enlistment, out retryConfig, out error))
            {
                this.ReportErrorAndExit("Failed to determine GVFS timeout and max retries: " + error);
            }

            CacheServerInfo cacheServer;

            if (!CacheServerInfo.TryDetermineCacheServer(null, tracer, enlistment, retryConfig, out cacheServer, out error))
            {
                this.ReportErrorAndExit(error);
            }

            tracer.WriteStartEvent(
                enlistment.EnlistmentRoot,
                enlistment.RepoUrl,
                cacheServer.Url);

            InProcessMount mountHelper = new InProcessMount(tracer, enlistment, cacheServer, retryConfig, this.ShowDebugWindow);

            try
            {
                mountHelper.Mount(verbosity, keywords);
            }
            catch (Exception ex)
            {
                tracer.RelatedError("Failed to mount: {0}", ex.ToString());
                this.ReportErrorAndExit("Failed to mount: {0}", ex.Message);
            }
        }
示例#26
0
        public void FallsBackToDefaultCache()
        {
            MockGitProcess git = new MockGitProcess();

            git.SetExpectedCommandResult(@"config gvfs.mock:\repourl.cache-server-url", () => new GitProcess.Result(string.Empty, string.Empty, GitProcess.Result.GenericFailureCode));

            string          error;
            CacheServerInfo output;

            CacheServerInfo.TryDetermineCacheServer(
                userUrlish: null,
                gitProcess: git,
                enlistment: this.enlistment,
                knownCaches: KnownCaches,
                output: out output,
                error: out error).ShouldBeTrue(error);

            output.Name.ShouldEqual(DefaultCacheName);
        }
示例#27
0
        private void MountAndStartWorkingDirectoryCallbacks(CacheServerInfo cache)
        {
            string error;

            if (!this.context.Enlistment.Authentication.TryInitialize(this.context.Tracer, this.context.Enlistment, out error))
            {
                this.FailMountAndExit("Failed to obtain git credentials: " + error);
            }

            GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(this.context.Tracer, this.context.Enlistment, cache, this.retryConfig);

            this.gitObjects = new GSDGitObjects(this.context, objectRequestor);

            GitStatusCache gitStatusCache = (!this.context.Unattended && GSDPlatform.Instance.IsGitStatusCacheSupported()) ? new GitStatusCache(this.context, this.gitStatusCacheConfig) : null;

            if (gitStatusCache != null)
            {
                this.tracer.RelatedInfo("Git status cache enabled. Backoff time: {0}ms", this.gitStatusCacheConfig.BackoffTime.TotalMilliseconds);
            }
            else
            {
                this.tracer.RelatedInfo("Git status cache is not enabled");
            }

            this.maintenanceScheduler = this.CreateOrReportAndExit(() => new GitMaintenanceScheduler(this.context, this.gitObjects), "Failed to start maintenance scheduler");

            int majorVersion;
            int minorVersion;

            if (!RepoMetadata.Instance.TryGetOnDiskLayoutVersion(out majorVersion, out minorVersion, out error))
            {
                this.FailMountAndExit("Error: {0}", error);
            }

            if (majorVersion != GSDPlatform.Instance.DiskLayoutUpgrade.Version.CurrentMajorVersion)
            {
                this.FailMountAndExit(
                    "Error: On disk version ({0}) does not match current version ({1})",
                    majorVersion,
                    GSDPlatform.Instance.DiskLayoutUpgrade.Version.CurrentMajorVersion);
            }
        }
示例#28
0
        private GVFltCallbacks CreateGVFltCallbacks()
        {
            string error;

            if (!RepoMetadata.TryInitialize(this.Context.Tracer, this.Enlistment.DotGVFSRoot, out error))
            {
                throw new InvalidRepoException(error);
            }

            CacheServerInfo         cacheServer     = new CacheServerInfo(this.Context.Enlistment.RepoUrl, "None");
            GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(
                this.Context.Tracer,
                this.Context.Enlistment,
                cacheServer,
                new RetryConfig());

            GVFSGitObjects gitObjects = new GVFSGitObjects(this.Context, objectRequestor);

            return(new GVFltCallbacks(this.Context, gitObjects, RepoMetadata.Instance));
        }
示例#29
0
        private bool TryDetermineLocalCacheAndInitializePaths(
            ITracer tracer,
            GVFSEnlistment enlistment,
            ServerGVFSConfig serverGVFSConfig,
            CacheServerInfo currentCacheServer,
            string localCacheRoot,
            out string errorMessage)
        {
            errorMessage = null;
            LocalCacheResolver localCacheResolver = new LocalCacheResolver(enlistment);

            string error;
            string localCacheKey;

            if (!localCacheResolver.TryGetLocalCacheKeyFromLocalConfigOrRemoteCacheServers(
                    tracer,
                    serverGVFSConfig,
                    currentCacheServer,
                    localCacheRoot,
                    localCacheKey: out localCacheKey,
                    errorMessage: out error))
            {
                errorMessage = "Error determining local cache key: " + error;
                return(false);
            }

            EventMetadata metadata = new EventMetadata();

            metadata.Add("localCacheRoot", localCacheRoot);
            metadata.Add("localCacheKey", localCacheKey);
            metadata.Add(TracingConstants.MessageKey.InfoMessage, "Initializing cache paths");
            tracer.RelatedEvent(EventLevel.Informational, "CloneVerb_TryDetermineLocalCacheAndInitializePaths", metadata);

            enlistment.InitializeCachePathsFromKey(localCacheRoot, localCacheKey);

            return(true);
        }
示例#30
0
            protected void InitializeLocalCacheAndObjectsPaths(
                ITracer tracer,
                GVFSEnlistment enlistment,
                RetryConfig retryConfig,
                ServerGVFSConfig serverGVFSConfig,
                CacheServerInfo cacheServer)
            {
                string error;

                if (!RepoMetadata.TryInitialize(tracer, Path.Combine(enlistment.EnlistmentRoot, GVFSConstants.DotGVFS.Root), out error))
                {
                    this.ReportErrorAndExit(tracer, "Failed to initialize repo metadata: " + error);
                }

                this.InitializeCachePathsFromRepoMetadata(tracer, enlistment);

                // Note: Repos cloned with a version of GVFS that predates the local cache will not have a local cache configured
                if (!string.IsNullOrWhiteSpace(enlistment.LocalCacheRoot))
                {
                    this.EnsureLocalCacheIsHealthy(tracer, enlistment, retryConfig, serverGVFSConfig, cacheServer);
                }

                RepoMetadata.Shutdown();
            }