Ejemplo n.º 1
0
        protected ServerGVFSConfig QueryGVFSConfig(ITracer tracer, GVFSEnlistment enlistment, RetryConfig retryConfig)
        {
            ServerGVFSConfig serverGVFSConfig = null;

            if (!this.ShowStatusWhileRunning(
                    () =>
            {
                using (ConfigHttpRequestor configRequestor = new ConfigHttpRequestor(tracer, enlistment, retryConfig))
                {
                    const bool LogErrors = true;
                    return(configRequestor.TryQueryGVFSConfig(LogErrors, out serverGVFSConfig, out _));
                }
            },
                    "Querying remote for config",
                    suppressGvfsLogMessage: true))
            {
                this.ReportErrorAndExit(tracer, "Unable to query /gvfs/config");
            }

            return(serverGVFSConfig);
        }
Ejemplo n.º 2
0
        protected bool TryDownloadCommit(
            string commitId,
            GVFSEnlistment enlistment,
            GitObjectsHttpRequestor objectRequestor,
            GVFSGitObjects gitObjects,
            GitRepo repo,
            out string error,
            bool checkLocalObjectCache = true)
        {
            if (!checkLocalObjectCache || !repo.CommitAndRootTreeExists(commitId))
            {
                if (!gitObjects.TryDownloadCommit(commitId))
                {
                    error = "Could not download commit " + commitId + " from: " + Uri.EscapeUriString(objectRequestor.CacheServer.ObjectsEndpointUrl);
                    return(false);
                }
            }

            error = null;
            return(true);
        }
Ejemplo n.º 3
0
        private bool TryPrefetchCommitsAndTrees(ITracer tracer, GVFSEnlistment enlistment, GitObjectsHttpRequestor objectRequestor)
        {
            PhysicalFileSystem fileSystem = new PhysicalFileSystem();
            GitRepo            repo       = new GitRepo(tracer, enlistment, fileSystem);
            GVFSContext        context    = new GVFSContext(tracer, fileSystem, repo, enlistment);
            GitObjects         gitObjects = new GVFSGitObjects(context, objectRequestor);

            string[] packs = gitObjects.ReadPackFileNames(GVFSConstants.PrefetchPackPrefix);
            long     max   = -1;

            foreach (string pack in packs)
            {
                long?timestamp = this.GetTimestamp(pack);
                if (timestamp.HasValue && timestamp > max)
                {
                    max = timestamp.Value;
                }
            }

            return(gitObjects.TryDownloadPrefetchPacks(max));
        }
        private void CheckGitStatus(ITracer tracer, GVFSEnlistment enlistment, HashSet <string> sparseFolders)
        {
            GitProcess.Result statusResult = null;
            if (!this.ShowStatusWhileRunning(
                    () =>
            {
                GitProcess git = new GitProcess(enlistment);
                statusResult = git.StatusPorcelain();
                if (statusResult.ExitCodeIsFailure)
                {
                    return(false);
                }

                if (this.ContainsPathNotCoveredBySparseFolders(statusResult.Output, sparseFolders))
                {
                    return(false);
                }

                return(true);
            },
                    "Running git status",
                    suppressGvfsLogMessage: true))
            {
                this.Output.WriteLine();

                if (statusResult.ExitCodeIsFailure)
                {
                    this.WriteMessage(tracer, "Failed to run git status: " + statusResult.Errors);
                }
                else
                {
                    this.WriteMessage(tracer, statusResult.Output);
                    this.WriteMessage(tracer, "git status reported that you have dirty files");
                    this.WriteMessage(tracer, "Either commit your changes or reset and clean");
                }

                this.Output.WriteLine();
                this.ReportErrorAndExit(tracer, "Sparse was aborted.");
            }
        }
Ejemplo n.º 5
0
        public bool TryWriteMultiPackIndex(ITracer tracer, GVFSEnlistment enlistment, PhysicalFileSystem fileSystem)
        {
            using (ITracer activity = tracer.StartActivity(nameof(this.TryWriteMultiPackIndex), EventLevel.Informational, Keywords.Telemetry, metadata: null))
            {
                GitProcess        process = new GitProcess(enlistment);
                GitProcess.Result result  = process.WriteMultiPackIndex(enlistment.GitPackRoot);

                if (!result.HasErrors)
                {
                    string midxHash = result.Output.Trim();
                    activity.RelatedInfo("Updated midx-head to hash {0}", midxHash);

                    string expectedMidxHead = Path.Combine(enlistment.GitPackRoot, "midx-" + midxHash + ".midx");

                    List <string> midxFiles = new List <string>();

                    midxFiles.AddRange(fileSystem.GetFiles(enlistment.GitPackRoot, "midx-*.midx"));
                    midxFiles.AddRange(fileSystem.GetFiles(enlistment.GitPackRoot, "tmp_midx_*"));

                    foreach (string midxFile in midxFiles)
                    {
                        if (!midxFile.Equals(expectedMidxHead, StringComparison.OrdinalIgnoreCase) && !fileSystem.TryDeleteFile(midxFile))
                        {
                            activity.RelatedWarning("Failed to delete MIDX file {0}", midxFile);
                        }
                    }
                }
                else
                {
                    EventMetadata errorMetadata = new EventMetadata();
                    errorMetadata.Add("Operation", nameof(this.TryWriteMultiPackIndex));
                    errorMetadata.Add("packDir", enlistment.GitPackRoot);
                    errorMetadata.Add("Errors", result.Errors);
                    errorMetadata.Add("Output", result.Output.Length > 1024 ? result.Output.Substring(1024) : result.Output);
                    activity.RelatedError(errorMetadata, result.Errors, Keywords.Telemetry);
                }

                return(!result.HasErrors);
            }
        }
Ejemplo n.º 6
0
            private void InitializeCachePathsFromRepoMetadata(
                ITracer tracer,
                GVFSEnlistment enlistment)
            {
                string error;
                string gitObjectsRoot;

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

                if (string.IsNullOrWhiteSpace(gitObjectsRoot))
                {
                    this.ReportErrorAndExit(tracer, "Invalid git objects root (empty or whitespace)");
                }

                string localCacheRoot;

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

                // Note: localCacheRoot is allowed to be empty, this can occur when upgrading from disk layout version 11 to 12

                string blobSizesRoot;

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

                if (string.IsNullOrWhiteSpace(blobSizesRoot))
                {
                    this.ReportErrorAndExit(tracer, "Invalid blob sizes root (empty or whitespace)");
                }

                enlistment.InitializeCachePaths(localCacheRoot, gitObjectsRoot, blobSizesRoot);
            }
Ejemplo n.º 7
0
        private bool IsValidRepo(string repoRoot)
        {
            if (!Directory.Exists(repoRoot))
            {
                return(false);
            }

            string gitBinPath = GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath();

            string hooksVersion = null;
            string error        = null;

            if (GVFSPlatform.Instance.TryGetGVFSHooksVersion(out hooksVersion, out error))
            {
                try
                {
                    GVFSEnlistment enlistment = GVFSEnlistment.CreateFromDirectory(
                        repoRoot,
                        gitBinPath,
                        authentication: null);
                }
                catch (InvalidRepoException e)
                {
                    EventMetadata metadata = new EventMetadata();
                    metadata.Add(nameof(repoRoot), repoRoot);
                    metadata.Add(nameof(gitBinPath), gitBinPath);
                    metadata.Add("Exception", e.ToString());
                    this.tracer.RelatedInfo(metadata, $"{nameof(this.IsValidRepo)}: Found invalid repo");

                    return(false);
                }
            }
            else
            {
                this.tracer.RelatedError($"{nameof(this.IsValidRepo)}: {nameof(GVFSPlatform.Instance.TryGetGVFSHooksVersion)} failed. {error}");
                return(false);
            }

            return(true);
        }
Ejemplo n.º 8
0
        public CommonRepoSetup()
        {
            MockTracer tracer = new MockTracer();

            string         enlistmentRoot = Path.Combine("mock:", "GVFS", "UnitTests", "Repo");
            GVFSEnlistment enlistment     = new GVFSEnlistment(enlistmentRoot, "fake://repoUrl", "fake://gitBinPath", null);

            enlistment.InitializeCachePathsFromKey("fake:\\gvfsSharedCache", "fakeCacheKey");

            this.GitParentPath    = enlistment.WorkingDirectoryRoot;
            this.GVFSMetadataPath = enlistment.DotGVFSRoot;

            MockDirectory enlistmentDirectory = new MockDirectory(
                enlistmentRoot,
                new MockDirectory[]
            {
                new MockDirectory(this.GitParentPath, folders: null, files: null),
            },
                null);

            enlistmentDirectory.CreateFile(Path.Combine(this.GitParentPath, ".git", "config"), ".git config Contents", createDirectories: true);
            enlistmentDirectory.CreateFile(Path.Combine(this.GitParentPath, ".git", "HEAD"), ".git HEAD Contents", createDirectories: true);
            enlistmentDirectory.CreateFile(Path.Combine(this.GitParentPath, ".git", "logs", "HEAD"), "HEAD Contents", createDirectories: true);
            enlistmentDirectory.CreateFile(Path.Combine(this.GitParentPath, ".git", "info", "always_exclude"), "always_exclude Contents", createDirectories: true);
            enlistmentDirectory.CreateDirectory(Path.Combine(this.GitParentPath, ".git", "objects", "pack"));

            MockFileSystem fileSystem = new MockFileSystem(enlistmentDirectory);

            this.Repository = new MockGitRepo(
                tracer,
                enlistment,
                fileSystem);
            CreateStandardGitTree(this.Repository);

            this.Context = new GVFSContext(tracer, fileSystem, this.Repository, enlistment);

            this.HttpObjects = new MockHttpGitObjects(tracer, enlistment);
            this.GitObjects  = new MockGVFSGitObjects(this.Context, this.HttpObjects);
        }
Ejemplo n.º 9
0
        private bool IsValidRepo(string repoRoot)
        {
            string         gitBinPath = GitProcess.GetInstalledGitBinPath();
            string         hooksPath  = ProcessHelper.WhereDirectory(GVFSConstants.GVFSHooksExecutableName);
            GVFSEnlistment enlistment = null;

            try
            {
                enlistment = GVFSEnlistment.CreateFromDirectory(repoRoot, gitBinPath, hooksPath);
            }
            catch (InvalidRepoException)
            {
                return(false);
            }

            if (enlistment == null)
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 10
0
        private bool IsValidRepo(string repoRoot)
        {
            string         gitBinPath = GitProcess.GetInstalledGitBinPath();
            string         hooksPath  = this.GetGVFSHooksPathAndCheckVersion(tracer: null);
            GVFSEnlistment enlistment = null;

            try
            {
                enlistment = GVFSEnlistment.CreateFromDirectory(repoRoot, gitBinPath, hooksPath);
            }
            catch (InvalidRepoException)
            {
                return(false);
            }

            if (enlistment == null)
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 11
0
        private static bool TryInstallGitCommandHooks(GVFSEnlistment enlistment, string hookName, string commandHookPath, out string errorMessage)
        {
            // The GitHooksLoader requires the following setup to invoke a hook:
            //      Copy GithooksLoader.exe to hook-name.exe
            //      Create a text file named hook-name.hooks that lists the applications to execute for the hook, one application per line

            string gitHooksloaderPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), GVFSConstants.DotGit.Hooks.LoaderExecutable);

            if (!TryAction(() => CopyGitHooksLoader(gitHooksloaderPath, commandHookPath), out errorMessage))
            {
                errorMessage = "Failed to copy " + GVFSConstants.DotGit.Hooks.LoaderExecutable + " to " + commandHookPath + GVFSConstants.ExecutableExtension + "\n" + errorMessage;
                return(false);
            }

            if (!TryAction(() => CreateHookCommandConfig(enlistment, hookName, commandHookPath), out errorMessage))
            {
                errorMessage = "Failed to create " + commandHookPath + GVFSConstants.DotGit.Hooks.ConfigExtension + "\n" + errorMessage;
                return(false);
            }

            return(true);
        }
Ejemplo n.º 12
0
        public static bool InstallHooks(GVFSEnlistment enlistment, out string error)
        {
            error = string.Empty;
            try
            {
                string installedReadObjectHookPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), GVFSConstants.GVFSReadObjectHookExecutableName);
                TryActionAndThrow(() => CopyReadObjectHook(enlistment, installedReadObjectHookPath), "Failed to copy" + installedReadObjectHookPath);

                string precommandHookPath = Path.Combine(enlistment.WorkingDirectoryRoot, GVFSConstants.DotGit.Hooks.PreCommandPath);
                InstallGitCommandHooks(enlistment, GVFSConstants.DotGit.Hooks.PreCommandHookName, precommandHookPath);

                string postcommandHookPath = Path.Combine(enlistment.WorkingDirectoryRoot, GVFSConstants.DotGit.Hooks.PostCommandPath);
                InstallGitCommandHooks(enlistment, GVFSConstants.DotGit.Hooks.PostCommandHookName, postcommandHookPath);
            }
            catch (Exception e)
            {
                error = e.ToString();
                return(false);
            }

            return(true);
        }
Ejemplo n.º 13
0
        protected void CheckAntiVirusExclusion(GVFSEnlistment enlistment)
        {
            bool isExcluded;

            if (AntiVirusExclusions.TryGetIsPathExcluded(enlistment.EnlistmentRoot, out isExcluded))
            {
                if (!isExcluded)
                {
                    if (ProcessHelper.IsAdminElevated())
                    {
                        AntiVirusExclusions.AddAntiVirusExclusion(enlistment.EnlistmentRoot);

                        if (!AntiVirusExclusions.TryGetIsPathExcluded(enlistment.EnlistmentRoot, out isExcluded) ||
                            !isExcluded)
                        {
                            this.ReportErrorAndExit(
                                "This repo is not excluded from antivirus and we were unable to add it.  Add '{0}' to your exclusion list and then run {1} again.",
                                enlistment.EnlistmentRoot,
                                this.VerbName);
                        }
                    }
                    else
                    {
                        this.ReportErrorAndExit(
                            "This repo is not excluded from antivirus.  Either re-run {1} with elevated privileges, or add '{0}' to your exclusion list and then run {1} again.",
                            enlistment.EnlistmentRoot,
                            this.VerbName);
                    }
                }
            }
            else
            {
                this.Output.WriteLine();
                this.Output.WriteLine(
                    "WARNING: Unable to determine if this repo is excluded from antivirus.  Please check to ensure that '{0}' is excluded.",
                    enlistment.EnlistmentRoot);
                this.Output.WriteLine();
            }
        }
Ejemplo n.º 14
0
        private void InitializeServerConnection(
            ITracer tracer,
            GVFSEnlistment enlistment,
            string cacheServerUrl,
            out GitObjectsHttpRequestor objectRequestor,
            out CacheServerInfo cacheServer)
        {
            RetryConfig retryConfig = this.GetRetryConfig(tracer, enlistment, TimeSpan.FromMinutes(RetryConfig.FetchAndCloneTimeoutMinutes));

            cacheServer = this.ResolvedCacheServer;
            ServerGVFSConfig serverGVFSConfig = this.ServerGVFSConfig;

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

                if (serverGVFSConfig == null)
                {
                    serverGVFSConfig = this.QueryGVFSConfig(tracer, enlistment, retryConfig);
                }

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

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

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

            this.InitializeLocalCacheAndObjectsPaths(tracer, enlistment, retryConfig, serverGVFSConfig, cacheServer);
            objectRequestor = new GitObjectsHttpRequestor(tracer, enlistment, cacheServer, retryConfig);
        }
Ejemplo n.º 15
0
        private void CheckGitStatus(ITracer tracer, GVFSEnlistment enlistment)
        {
            GitProcess.Result statusResult = null;
            if (!this.ShowStatusWhileRunning(
                    () =>
            {
                GitProcess git = new GitProcess(enlistment);
                statusResult = git.Status(allowObjectDownloads: false, useStatusCache: false, showUntracked: true);
                if (statusResult.ExitCodeIsFailure)
                {
                    return(false);
                }

                if (!statusResult.Output.Contains("nothing to commit, working tree clean"))
                {
                    return(false);
                }

                return(true);
            },
                    "Running git status",
                    suppressGvfsLogMessage: true))
            {
                this.Output.WriteLine();

                if (statusResult.ExitCodeIsFailure)
                {
                    this.WriteMessage(tracer, "Failed to run git status: " + statusResult.Errors);
                }
                else
                {
                    this.WriteMessage(tracer, statusResult.Output);
                    this.WriteMessage(tracer, "git status reported that you have dirty files");
                    this.WriteMessage(tracer, "Either commit your changes or reset and clean");
                }

                this.ReportErrorAndExit(tracer, SparseVerbName + " was aborted");
            }
        }
Ejemplo n.º 16
0
        public void Execute()
        {
            GVFSEnlistment enlistment = this.CreateEnlistment(this.EnlistmentRootPath);

            EventLevel verbosity;
            Keywords   keywords;

            this.ParseEnumArgs(out verbosity, out keywords);

            ITracer        tracer      = this.CreateTracer(enlistment, verbosity, keywords);
            InProcessMount mountHelper = new InProcessMount(tracer, enlistment, 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);
            }
        }
Ejemplo n.º 17
0
        protected bool TrySetGitConfig(ITracer tracer, string enlistmentRoot, Dictionary <string, string> configSettings, out string errorMessage)
        {
            errorMessage = null;

            GVFSEnlistment enlistment = GVFSEnlistment.CreateFromDirectory(
                enlistmentRoot,
                GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath(),
                ProcessHelper.GetCurrentProcessLocation());
            GitProcess git = enlistment.CreateGitProcess();

            foreach (string key in configSettings.Keys)
            {
                GitProcess.Result result = git.SetInLocalConfig(key, configSettings[key]);
                if (result.HasErrors)
                {
                    tracer.RelatedError("Could not set git config setting {0}. Error: {1}", key, result.Errors);
                    return(false);
                }
            }

            return(true);
        }
        protected override void OnStart(string[] args)
        {
            if (this.serviceThread != null)
            {
                throw new InvalidOperationException("Cannot start service twice in a row.");
            }

            // TODO: 865304 Used for functional tests and development only. Replace with a smarter appConfig-based solution
            string serviceName = args.FirstOrDefault(arg => arg.StartsWith(ServiceNameArgPrefix));

            if (serviceName != null)
            {
                this.serviceName = serviceName.Substring(ServiceNameArgPrefix.Length);
            }

            string serviceLogsDirectoryPath = Path.Combine(
                GVFSPlatform.Instance.GetDataRootForGVFSComponent(this.serviceName),
                GVFSConstants.Service.LogDirectory);

            // Create the logs directory explicitly *before* creating a log file event listener to ensure that it
            // and its ancestor directories are created with the correct ACLs.
            this.CreateServiceLogsDirectory(serviceLogsDirectoryPath);
            this.tracer.AddLogFileEventListener(
                GVFSEnlistment.GetNewGVFSLogFileName(serviceLogsDirectoryPath, GVFSConstants.LogFileTypes.Service),
                EventLevel.Verbose,
                Keywords.Any);

            try
            {
                this.serviceDataLocation = GVFSPlatform.Instance.GetDataRootForGVFSComponent(this.serviceName);
                this.CreateAndConfigureProgramDataDirectories();
                this.Start();
            }
            catch (Exception e)
            {
                this.LogExceptionAndExit(e, nameof(this.OnStart));
            }
        }
Ejemplo n.º 19
0
            private GVFSEnlistment CreateEnlistment(string enlistmentRootPath)
            {
                string gitBinPath = GitProcess.GetInstalledGitBinPath();

                if (string.IsNullOrWhiteSpace(gitBinPath))
                {
                    this.ReportErrorAndExit("Error: " + GVFSConstants.GitIsNotInstalledError);
                }

                string hooksPath = ProcessHelper.WhereDirectory(GVFSConstants.GVFSHooksExecutableName);

                if (hooksPath == null)
                {
                    this.ReportErrorAndExit("Could not find " + GVFSConstants.GVFSHooksExecutableName);
                }

                GVFSEnlistment enlistment = null;

                try
                {
                    enlistment = GVFSEnlistment.CreateFromDirectory(enlistmentRootPath, gitBinPath, hooksPath);
                    if (enlistment == null)
                    {
                        this.ReportErrorAndExit(
                            "Error: '{0}' is not a valid GVFS enlistment",
                            enlistmentRootPath);
                    }
                }
                catch (InvalidRepoException e)
                {
                    this.ReportErrorAndExit(
                        "Error: '{0}' is not a valid GVFS enlistment. {1}",
                        enlistmentRootPath,
                        e.Message);
                }

                return(enlistment);
            }
Ejemplo n.º 20
0
        public static bool TryPrefetchCommitsAndTrees(
            ITracer tracer,
            GVFSEnlistment enlistment,
            PhysicalFileSystem fileSystem,
            GitObjects gitObjects,
            out string error)
        {
            List <string> packIndexes;

            using (FileBasedLock prefetchLock = GVFSPlatform.Instance.CreateFileBasedLock(
                       fileSystem,
                       tracer,
                       Path.Combine(enlistment.GitPackRoot, PrefetchCommitsAndTreesLock)))
            {
                WaitUntilLockIsAcquired(tracer, prefetchLock);
                long maxGoodTimeStamp;

                gitObjects.DeleteStaleTempPrefetchPackAndIdxs();

                if (!TryGetMaxGoodPrefetchTimestamp(tracer, enlistment, fileSystem, gitObjects, out maxGoodTimeStamp, out error))
                {
                    return(false);
                }

                if (!gitObjects.TryDownloadPrefetchPacks(maxGoodTimeStamp, out packIndexes))
                {
                    error = "Failed to download prefetch packs";
                    return(false);
                }
            }

            if (packIndexes?.Count > 0)
            {
                TrySchedulePostFetchJob(tracer, enlistment.NamedPipeName, packIndexes);
            }

            return(true);
        }
Ejemplo n.º 21
0
        protected ReturnCode Execute <TVerb>(
            GVFSEnlistment enlistment,
            Action <TVerb> configureVerb = null)
            where TVerb : GVFSVerb.ForExistingEnlistment, new()
        {
            TVerb verb = new TVerb();

            verb.EnlistmentRootPathParameter = enlistment.EnlistmentRoot;
            verb.ServiceName = this.ServiceName;
            verb.Unattended  = this.Unattended;

            configureVerb?.Invoke(verb);

            try
            {
                verb.Execute(enlistment.Authentication);
            }
            catch (VerbAbortedException)
            {
            }

            return(verb.ReturnCode);
        }
Ejemplo n.º 22
0
        public GVFSService(JsonTracer tracer)
        {
            string logFilePath = Path.Combine(
                GVFSPlatform.Instance.GetDataRootForGVFSComponent(GVFSConstants.Service.ServiceName),
                GVFSConstants.Service.LogDirectory);

            Directory.CreateDirectory(logFilePath);

            this.tracer = tracer;
            this.tracer.AddLogFileEventListener(
                GVFSEnlistment.GetNewGVFSLogFileName(logFilePath, GVFSConstants.LogFileTypes.Service),
                EventLevel.Verbose,
                Keywords.Any);

            this.serviceName    = GVFSConstants.Service.ServiceName;
            this.serviceStopped = new ManualResetEvent(false);
            this.serviceThread  = new Thread(this.ServiceThreadMain);
            this.repoRegistry   = new RepoRegistry(
                this.tracer,
                new PhysicalFileSystem(),
                GVFSPlatform.Instance.GetDataRootForGVFSComponent(this.serviceName));
            this.requestHandler = new RequestHandler(this.tracer, EtwArea, this.repoRegistry);
        }
Ejemplo n.º 23
0
        protected bool TryCreateAlternatesFile(PhysicalFileSystem fileSystem, GVFSEnlistment enlistment, out string errorMessage)
        {
            try
            {
                string alternatesFilePath = this.GetAlternatesPath(enlistment);
                string tempFilePath       = alternatesFilePath + ".tmp";
                fileSystem.WriteAllText(tempFilePath, enlistment.GitObjectsRoot);
                fileSystem.MoveAndOverwriteFile(tempFilePath, alternatesFilePath);
            }
            catch (SecurityException e)
            {
                errorMessage = e.Message;
                return(false);
            }
            catch (IOException e)
            {
                errorMessage = e.Message;
                return(false);
            }

            errorMessage = null;
            return(true);
        }
Ejemplo n.º 24
0
        protected void ValidateClientVersions(ITracer tracer, GVFSEnlistment enlistment, GVFSConfig gvfsConfig, bool showWarnings)
        {
            this.CheckGitVersion(tracer, enlistment);
            this.GetGVFSHooksPathAndCheckVersion(tracer);
            this.CheckVolumeSupportsDeleteNotifications(tracer, enlistment);

            string errorMessage = null;
            bool   errorIsFatal = false;

            if (!this.TryValidateGVFSVersion(enlistment, tracer, gvfsConfig, out errorMessage, out errorIsFatal))
            {
                if (errorIsFatal)
                {
                    this.ReportErrorAndExit(tracer, errorMessage);
                }
                else if (showWarnings)
                {
                    this.Output.WriteLine();
                    this.Output.WriteLine(errorMessage);
                    this.Output.WriteLine();
                }
            }
        }
Ejemplo n.º 25
0
        private bool IsValidRepo(string repoRoot)
        {
            WindowsGitInstallation windowsGitInstallation = new WindowsGitInstallation();
            string         gitBinPath = windowsGitInstallation.GetInstalledGitBinPath();
            string         hooksPath  = ProcessHelper.WhereDirectory(GVFSPlatform.Instance.Constants.GVFSHooksExecutableName);
            GVFSEnlistment enlistment = null;

            try
            {
                enlistment = GVFSEnlistment.CreateFromDirectory(repoRoot, gitBinPath, hooksPath, authentication: null);
            }
            catch (InvalidRepoException)
            {
                return(false);
            }

            if (enlistment == null)
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 26
0
        private Result TryCreateEnlistment(
            string fullEnlistmentRootPathParameter,
            string normalizedEnlistementRootPath,
            out GVFSEnlistment enlistment)
        {
            enlistment = null;

            // Check that EnlistmentRootPath is empty before creating a tracer and LogFileEventListener as
            // LogFileEventListener will create a file in EnlistmentRootPath
            if (Directory.Exists(normalizedEnlistementRootPath) && Directory.EnumerateFileSystemEntries(normalizedEnlistementRootPath).Any())
            {
                if (fullEnlistmentRootPathParameter.Equals(normalizedEnlistementRootPath, StringComparison.OrdinalIgnoreCase))
                {
                    return(new Result($"Clone directory '{fullEnlistmentRootPathParameter}' exists and is not empty"));
                }

                return(new Result($"Clone directory '{fullEnlistmentRootPathParameter}' ['{normalizedEnlistementRootPath}'] exists and is not empty"));
            }

            string gitBinPath = GVFSPlatform.Instance.GitInstallation.GetInstalledGitBinPath();

            if (string.IsNullOrWhiteSpace(gitBinPath))
            {
                return(new Result(GVFSConstants.GitIsNotInstalledError));
            }

            string hooksPath = this.GetGVFSHooksPathAndCheckVersion(tracer: null, hooksVersion: out _);

            enlistment = new GVFSEnlistment(
                normalizedEnlistementRootPath,
                this.RepositoryURL,
                gitBinPath,
                hooksPath,
                authentication: null);

            return(new Result(true));
        }
Ejemplo n.º 27
0
        public bool Mount(string repoRoot)
        {
            string error;

            if (!GvFltFilter.IsHealthy(out error, this.tracer))
            {
                return(false);
            }

            // Ensure the repo is excluded from antivirus before calling 'gvfs mount'
            // to reduce chatter between GVFS.exe and GVFS.Service.exe
            string errorMessage;
            bool   isExcluded;

            ExcludeFromAntiVirusHandler.CheckAntiVirusExclusion(this.tracer, repoRoot, out isExcluded, out errorMessage);

            string unusedMessage;

            if (!GvFltFilter.TryAttach(this.tracer, repoRoot, out unusedMessage))
            {
                return(false);
            }

            if (!this.CallGVFSMount(repoRoot))
            {
                this.tracer.RelatedError("Unable to start the GVFS.exe process.");
                return(false);
            }

            if (!GVFSEnlistment.WaitUntilMounted(repoRoot, false, out errorMessage))
            {
                this.tracer.RelatedError(errorMessage);
                return(false);
            }

            return(true);
        }
        private void SendDehydrateMessage(ITracer tracer, GVFSEnlistment enlistment, List <string> folderErrors, string[] folders)
        {
            NamedPipeMessages.DehydrateFolders.Response response = null;

            try
            {
                using (NamedPipeClient pipeClient = new NamedPipeClient(enlistment.NamedPipeName))
                {
                    if (!pipeClient.Connect())
                    {
                        this.ReportErrorAndExit("Unable to connect to GVFS.  Try running 'gvfs mount'");
                    }

                    NamedPipeMessages.DehydrateFolders.Request request = new NamedPipeMessages.DehydrateFolders.Request(string.Join(FolderListSeparator, folders));
                    pipeClient.SendRequest(request.CreateMessage());
                    response = NamedPipeMessages.DehydrateFolders.Response.FromMessage(NamedPipeMessages.Message.FromString(pipeClient.ReadRawResponse()));
                }
            }
            catch (BrokenPipeException e)
            {
                this.ReportErrorAndExit("Unable to communicate with GVFS: " + e.ToString());
            }

            if (response != null)
            {
                foreach (string folder in response.SuccessfulFolders)
                {
                    this.WriteMessage(tracer, $"{folder} folder {this.ActionName} successful.");
                }

                foreach (string folder in response.FailedFolders)
                {
                    this.WriteMessage(tracer, $"{folder} folder failed to {this.ActionName}. You may need to reset the working directory by deleting {folder}, running `git reset --hard`, and retry the {this.ActionName}.");
                    folderErrors.Add(folder);
                }
            }
        }
Ejemplo n.º 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);
        }
Ejemplo n.º 30
0
        private bool RequestMount(GVFSEnlistment enlistment, out string errorMessage)
        {
            this.CheckGitVersion(enlistment);
            this.CheckGVFSHooksVersion(enlistment, null);

            if (!this.SkipVersionCheck)
            {
                using (ITracer mountTracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "Mount"))
                {
                    this.CheckVolumeSupportsDeleteNotifications(mountTracer, enlistment);

                    using (ConfigHttpRequestor configRequestor = new ConfigHttpRequestor(mountTracer, enlistment))
                    {
                        GVFSConfig config = configRequestor.QueryGVFSConfig();
                        this.ValidateGVFSVersion(enlistment, config, mountTracer);
                    }
                }
            }

            // We have to parse these parameters here to make sure they are valid before
            // handing them to the background process which cannot tell the user when they are bad
            EventLevel verbosity;
            Keywords   keywords;

            this.ParseEnumArgs(out verbosity, out keywords);

            GitProcess git = new GitProcess(enlistment);

            if (!git.IsValidRepo())
            {
                errorMessage = "The physical git repo is missing or invalid";
                return(false);
            }

            this.SetGitConfigSettings(git);
            return(this.SendMountRequest(enlistment, verbosity, keywords, out errorMessage));
        }