예제 #1
0
        private GSDEnlistment CreateEnlistment(string enlistmentRootPath)
        {
            string gitBinPath = GSDPlatform.Instance.GitInstallation.GetInstalledGitBinPath();

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

            GSDEnlistment enlistment = null;

            try
            {
                enlistment = GSDEnlistment.CreateFromDirectory(enlistmentRootPath, gitBinPath, ProcessHelper.GetCurrentProcessLocation(), authentication: null);
            }
            catch (InvalidRepoException e)
            {
                this.ReportErrorAndExit(
                    "Error: '{0}' is not a valid GSD enlistment. {1}",
                    enlistmentRootPath,
                    e.Message);
            }

            return(enlistment);
        }
예제 #2
0
        private bool PerformPreMountValidation(ITracer tracer, GSDEnlistment enlistment, out string mountExecutableLocation, out string errorMessage)
        {
            errorMessage            = string.Empty;
            mountExecutableLocation = string.Empty;

            // 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);

            mountExecutableLocation = Path.Combine(ProcessHelper.GetCurrentProcessLocation(), GSDPlatform.Instance.Constants.MountExecutableName);
            if (!File.Exists(mountExecutableLocation))
            {
                errorMessage = $"Could not find {GSDPlatform.Instance.Constants.MountExecutableName}. You may need to reinstall GSD.";
                return(false);
            }

            GitProcess git = new GitProcess(enlistment);

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

            return(true);
        }
예제 #3
0
        protected ReturnCode Execute <TVerb>(
            GSDEnlistment enlistment,
            Action <TVerb> configureVerb = null)
            where TVerb : GSDVerb.ForExistingEnlistment, new()
        {
            TVerb verb = new TVerb();

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

            if (configureVerb != null)
            {
                configureVerb(verb);
            }

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

            return(verb.ReturnCode);
        }
예제 #4
0
        protected override void OnSessionChange(SessionChangeDescription changeDescription)
        {
            try
            {
                base.OnSessionChange(changeDescription);

                if (!GSDEnlistment.IsUnattended(tracer: null))
                {
                    if (changeDescription.Reason == SessionChangeReason.SessionLogon)
                    {
                        this.tracer.RelatedInfo("SessionLogon detected, sessionId: {0}", changeDescription.SessionId);
                        using (ITracer activity = this.tracer.StartActivity("LogonAutomount", EventLevel.Informational))
                        {
                            this.repoRegistry.AutoMountRepos(
                                GSDPlatform.Instance.GetUserIdFromLoginSessionId(changeDescription.SessionId, this.tracer),
                                changeDescription.SessionId);
                            this.repoRegistry.TraceStatus();
                        }
                    }
                    else if (changeDescription.Reason == SessionChangeReason.SessionLogoff)
                    {
                        this.tracer.RelatedInfo("SessionLogoff detected");
                    }
                }
            }
            catch (Exception e)
            {
                this.LogExceptionAndExit(e, nameof(this.OnSessionChange));
            }
        }
예제 #5
0
        private bool TryMount(ITracer tracer, GSDEnlistment enlistment, string mountExecutableLocation, out string errorMessage)
        {
            if (!GSDVerb.TrySetRequiredGitConfigSettings(enlistment))
            {
                errorMessage = "Unable to configure git repo";
                return(false);
            }

            const string ParamPrefix = "--";

            tracer.RelatedInfo($"{nameof(this.TryMount)}: Launching background process('{mountExecutableLocation}') for {enlistment.EnlistmentRoot}");

            GSDPlatform.Instance.StartBackgroundVFS4GProcess(
                tracer,
                mountExecutableLocation,
                new[]
            {
                enlistment.EnlistmentRoot,
                ParamPrefix + GSDConstants.VerbParameters.Mount.Verbosity,
                this.Verbosity,
                ParamPrefix + GSDConstants.VerbParameters.Mount.Keywords,
                this.KeywordsCsv,
                ParamPrefix + GSDConstants.VerbParameters.Mount.StartedByService,
                this.StartedByService.ToString(),
                ParamPrefix + GSDConstants.VerbParameters.Mount.StartedByVerb,
                true.ToString()
            });

            tracer.RelatedInfo($"{nameof(this.TryMount)}: Waiting for repo to be mounted");
            return(GSDEnlistment.WaitUntilMounted(tracer, enlistment.EnlistmentRoot, this.Unattended, out errorMessage));
        }
예제 #6
0
        protected bool TrySetGitConfig(ITracer tracer, string enlistmentRoot, Dictionary <string, string> configSettings)
        {
            GSDEnlistment enlistment;

            try
            {
                enlistment = GSDEnlistment.CreateFromDirectory(
                    enlistmentRoot,
                    GSDPlatform.Instance.GitInstallation.GetInstalledGitBinPath(),
                    ProcessHelper.GetCurrentProcessLocation(),
                    authentication: null);
            }
            catch (InvalidRepoException e)
            {
                EventMetadata metadata = new EventMetadata();
                metadata.Add("Exception", e.ToString());
                metadata.Add(nameof(enlistmentRoot), enlistmentRoot);
                tracer.RelatedError(metadata, $"{nameof(this.TrySetGitConfig)}: Failed to create GSDEnlistment from directory");
                return(false);
            }

            GitProcess git = enlistment.CreateGitProcess();

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

            return(true);
        }
예제 #7
0
 public RepairJob(ITracer tracer, TextWriter output, GSDEnlistment enlistment)
 {
     this.Tracer     = tracer;
     this.Output     = output;
     this.Enlistment = enlistment;
     this.fileSystem = new PhysicalFileSystem();
 }
예제 #8
0
        protected override void Execute(GSDEnlistment enlistment)
        {
            using (NamedPipeClient pipeClient = new NamedPipeClient(enlistment.NamedPipeName))
            {
                if (!pipeClient.Connect())
                {
                    this.ReportErrorAndExit("Unable to connect to GSD.  Try running 'gvfs mount'");
                }

                try
                {
                    pipeClient.SendRequest(NamedPipeMessages.GetStatus.Request);
                    NamedPipeMessages.GetStatus.Response getStatusResponse =
                        NamedPipeMessages.GetStatus.Response.FromJson(pipeClient.ReadRawResponse());

                    this.Output.WriteLine("Enlistment root: " + getStatusResponse.EnlistmentRoot);
                    this.Output.WriteLine("Repo URL: " + getStatusResponse.RepoUrl);
                    this.Output.WriteLine("Cache Server: " + getStatusResponse.CacheServer);
                    this.Output.WriteLine("Local Cache: " + getStatusResponse.LocalCacheRoot);
                    this.Output.WriteLine("Mount status: " + getStatusResponse.MountStatus);
                    this.Output.WriteLine("GSD Lock: " + getStatusResponse.LockStatus);
                    this.Output.WriteLine("Background operations: " + getStatusResponse.BackgroundOperationCount);
                    this.Output.WriteLine("Disk layout version: " + getStatusResponse.DiskLayoutVersion);
                }
                catch (BrokenPipeException e)
                {
                    this.ReportErrorAndExit("Unable to communicate with GSD: " + e.ToString());
                }
            }
        }
예제 #9
0
        private void GetLocalCachePaths(GSDEnlistment enlistment, out string localCacheRoot, out string gitObjectsRoot)
        {
            localCacheRoot = null;
            gitObjectsRoot = null;

            try
            {
                using (ITracer tracer = new JsonTracer(GSDConstants.GSDEtwProviderName, "DiagnoseVerb"))
                {
                    string error;
                    if (RepoMetadata.TryInitialize(tracer, Path.Combine(enlistment.EnlistmentRoot, GSDPlatform.Instance.Constants.DotGSDRoot), out error))
                    {
                        RepoMetadata.Instance.TryGetLocalCacheRoot(out localCacheRoot, out error);
                        RepoMetadata.Instance.TryGetGitObjectsRoot(out gitObjectsRoot, out error);
                    }
                    else
                    {
                        this.WriteMessage("Failed to determine local cache path and git objects root, RepoMetadata error: " + error);
                    }
                }
            }
            catch (Exception e)
            {
                this.WriteMessage(string.Format("Failed to determine local cache path and git objects root, Exception: {0}", e));
            }
            finally
            {
                RepoMetadata.Shutdown();
            }
        }
예제 #10
0
        protected void ValidateClientVersions(ITracer tracer, GSDEnlistment enlistment, ServerGSDConfig gvfsConfig, bool showWarnings)
        {
            this.CheckGitVersion(tracer, enlistment, out string gitVersion);
            enlistment.SetGitVersion(gitVersion);

            this.GetGSDHooksPathAndCheckVersion(tracer, out string hooksVersion);
            enlistment.SetGSDHooksVersion(hooksVersion);

            string errorMessage = null;
            bool   errorIsFatal = false;

            if (!this.TryValidateGSDVersion(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();
                }
            }
        }
예제 #11
0
        private void PrefetchCommits(ITracer tracer, GSDEnlistment enlistment, GitObjectsHttpRequestor objectRequestor, CacheServerInfo cacheServer)
        {
            bool               success;
            string             error      = string.Empty;
            PhysicalFileSystem fileSystem = new PhysicalFileSystem();
            GitRepo            repo       = new GitRepo(tracer, enlistment, fileSystem);
            GSDContext         context    = new GSDContext(tracer, fileSystem, repo, enlistment);
            GitObjects         gitObjects = new GSDGitObjects(context, objectRequestor);

            if (this.Verbose)
            {
                success = new PrefetchStep(context, gitObjects, requireCacheLock: false).TryPrefetchCommitsAndTrees(out error);
            }
            else
            {
                success = this.ShowStatusWhileRunning(
                    () => new PrefetchStep(context, gitObjects, requireCacheLock: false).TryPrefetchCommitsAndTrees(out error),
                    "Fetching commits and trees " + this.GetCacheServerDisplay(cacheServer, enlistment.RepoUrl));
            }

            if (!success)
            {
                this.ReportErrorAndExit(tracer, "Prefetching commits and trees failed: " + error);
            }
        }
예제 #12
0
        protected override void Execute(GSDEnlistment enlistment)
        {
            this.BlockEmptyCacheServerUrl(this.CacheToSet);

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

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

                ServerGSDConfig serverGSDConfig = this.QueryGSDConfig(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, serverGSDConfig);

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

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

                    if (cacheServers != null && cacheServers.Any())
                    {
                        this.Output.WriteLine();
                        this.Output.WriteLine("Available cache servers for: " + enlistment.RepoUrl);
                        foreach (CacheServerInfo cacheServer in cacheServers)
                        {
                            this.Output.WriteLine(cacheServer);
                        }
                    }
                    else
                    {
                        this.Output.WriteLine("There are no available cache servers for: " + enlistment.RepoUrl);
                    }
                }
                else
                {
                    string          cacheServerUrl = CacheServerResolver.GetUrlFromConfig(enlistment);
                    CacheServerInfo cacheServer    = cacheServerResolver.ResolveNameFromRemote(cacheServerUrl, serverGSDConfig);

                    this.Output.WriteLine("Using cache server: " + cacheServer);
                }
            }
        }
예제 #13
0
            public void Execute(GitAuthentication authentication)
            {
                this.ValidatePathParameter(this.EnlistmentRootPathParameter);

                this.PreCreateEnlistment();
                GSDEnlistment enlistment = this.CreateEnlistment(this.EnlistmentRootPathParameter, authentication);

                this.Execute(enlistment);
            }
예제 #14
0
        private bool TryInitializeUpgrader(out string error)
        {
            if (this.DryRun && this.Confirmed)
            {
                error = $"{DryRunOption} and {ConfirmOption} arguments are not compatible.";
                return(false);
            }

            if (GSDPlatform.Instance.UnderConstruction.SupportsGSDUpgrade)
            {
                error = null;
                if (this.upgrader == null)
                {
                    this.productUpgraderPlatformStrategy = GSDPlatform.Instance.CreateProductUpgraderPlatformInteractions(this.fileSystem, tracer: null);
                    if (!this.productUpgraderPlatformStrategy.TryPrepareLogDirectory(out error))
                    {
                        return(false);
                    }

                    JsonTracer jsonTracer  = new JsonTracer(GSDConstants.GSDEtwProviderName, "UpgradeVerb");
                    string     logFilePath = GSDEnlistment.GetNewGSDLogFileName(
                        ProductUpgraderInfo.GetLogDirectoryPath(),
                        GSDConstants.LogFileTypes.UpgradeVerb);
                    jsonTracer.AddLogFileEventListener(logFilePath, EventLevel.Informational, Keywords.Any);

                    this.tracer        = jsonTracer;
                    this.prerunChecker = new InstallerPreRunChecker(this.tracer, this.Confirmed ? GSDConstants.UpgradeVerbMessages.GSDUpgradeConfirm : GSDConstants.UpgradeVerbMessages.GSDUpgrade);

                    string gitBinPath = GSDPlatform.Instance.GitInstallation.GetInstalledGitBinPath();
                    if (string.IsNullOrEmpty(gitBinPath))
                    {
                        error = $"nameof(this.TryInitializeUpgrader): Unable to locate git installation. Ensure git is installed and try again.";
                        return(false);
                    }

                    ICredentialStore credentialStore = new GitProcess(gitBinPath, workingDirectoryRoot: null, gvfsHooksRoot: null);

                    ProductUpgrader upgrader;
                    if (ProductUpgrader.TryCreateUpgrader(this.tracer, this.fileSystem, new LocalGSDConfig(), credentialStore, this.DryRun, this.NoVerify, out upgrader, out error))
                    {
                        this.upgrader = upgrader;
                    }
                    else
                    {
                        error = $"ERROR: {error}";
                    }
                }

                return(this.upgrader != null);
            }
            else
            {
                error = $"ERROR: {GSDConstants.UpgradeVerbMessages.GSDUpgrade} is not supported on this operating system.";
                return(false);
            }
        }
예제 #15
0
 public InProcessMount(ITracer tracer, GSDEnlistment enlistment, CacheServerInfo cacheServer, RetryConfig retryConfig, GitStatusCacheConfig gitStatusCacheConfig, bool showDebugWindow)
 {
     this.tracer               = tracer;
     this.retryConfig          = retryConfig;
     this.gitStatusCacheConfig = gitStatusCacheConfig;
     this.cacheServer          = cacheServer;
     this.enlistment           = enlistment;
     this.showDebugWindow      = showDebugWindow;
     this.unmountEvent         = new ManualResetEvent(false);
 }
예제 #16
0
        public override IssueType HasIssue(List <string> messages)
        {
            GitProcess git = new GitProcess(this.Enlistment);

            GitProcess.ConfigResult originResult = git.GetOriginUrl();
            string error;
            string originUrl;

            if (!originResult.TryParseAsString(out originUrl, out error))
            {
                if (error.Contains("--local"))
                {
                    // example error: '--local can only be used inside a git repository'
                    // Corrupting the git config does not cause git to not recognize the current folder as "not a git repository".
                    // This is a symptom of deeper issues such as missing HEAD file or refs folders.
                    messages.Add("An issue was found that may be a side-effect of other issues. Fix them with 'gvfs repair --confirm' then 'gvfs repair' again.");
                    return(IssueType.CantFix);
                }

                messages.Add("Could not read origin url: " + error);
                return(IssueType.Fixable);
            }

            if (originUrl == null)
            {
                messages.Add("Remote 'origin' is not configured for this repo. You can fix this by running 'git remote add origin <repourl>'");
                return(IssueType.CantFix);
            }

            // We've validated the repo URL, so now make sure we can authenticate
            try
            {
                GSDEnlistment enlistment = GSDEnlistment.CreateFromDirectory(
                    this.Enlistment.EnlistmentRoot,
                    this.Enlistment.GitBinPath,
                    this.Enlistment.GSDHooksRoot,
                    authentication: null);

                string authError;
                if (!enlistment.Authentication.TryInitialize(this.Tracer, enlistment, out authError))
                {
                    messages.Add("Authentication failed. Run 'gvfs log' for more info.");
                    messages.Add(".git\\config is valid and remote 'origin' is set, but may have a typo:");
                    messages.Add(originUrl.Trim());
                    return(IssueType.CantFix);
                }
            }
            catch (InvalidRepoException)
            {
                messages.Add("An issue was found that may be a side-effect of other issues. Fix them with 'gvfs repair --confirm' then 'gvfs repair' again.");
                return(IssueType.CantFix);
            }

            return(IssueType.None);
        }
예제 #17
0
        private bool TryValidateGSDVersion(GSDEnlistment enlistment, ITracer tracer, ServerGSDConfig config, out string errorMessage, out bool errorIsFatal)
        {
            errorMessage = null;
            errorIsFatal = false;

            using (ITracer activity = tracer.StartActivity("ValidateGSDVersion", EventLevel.Informational))
            {
                Version currentVersion = new Version(ProcessHelper.GetCurrentProcessVersion());

                IEnumerable <ServerGSDConfig.VersionRange> allowedGvfsClientVersions =
                    config != null
                    ? config.AllowedGSDClientVersions
                    : null;

                if (allowedGvfsClientVersions == null || !allowedGvfsClientVersions.Any())
                {
                    errorMessage = "WARNING: Unable to validate your GSD version" + Environment.NewLine;
                    if (config == null)
                    {
                        errorMessage += "Could not query valid GSD versions from: " + Uri.EscapeUriString(enlistment.RepoUrl);
                    }
                    else
                    {
                        errorMessage += "Server not configured to provide supported GSD versions";
                    }

                    return(false);
                }

                foreach (ServerGSDConfig.VersionRange versionRange in config.AllowedGSDClientVersions)
                {
                    if (currentVersion >= versionRange.Min &&
                        (versionRange.Max == null || currentVersion <= versionRange.Max))
                    {
                        activity.RelatedEvent(
                            EventLevel.Informational,
                            "GSDVersionValidated",
                            new EventMetadata
                        {
                            { "SupportedVersionRange", versionRange },
                        });

                        enlistment.SetGSDVersion(currentVersion.ToString());
                        return(true);
                    }
                }

                activity.RelatedError("GSD version {0} is not supported", currentVersion);
            }

            errorMessage = "ERROR: Your GSD version is no longer supported.  Install the latest and try again.";
            errorIsFatal = true;
            return(false);
        }
예제 #18
0
        private bool RegisterMount(GSDEnlistment enlistment, out string errorMessage)
        {
            errorMessage = string.Empty;

            NamedPipeMessages.RegisterRepoRequest request = new NamedPipeMessages.RegisterRepoRequest();
            request.EnlistmentRoot = enlistment.EnlistmentRoot;

            request.OwnerSID = GSDPlatform.Instance.GetCurrentUser();

            using (NamedPipeClient client = new NamedPipeClient(this.ServicePipeName))
            {
                if (!client.Connect())
                {
                    errorMessage = "Unable to register repo because GSD.Service is not responding.";
                    return(false);
                }

                try
                {
                    client.SendRequest(request.ToMessage());
                    NamedPipeMessages.Message response = client.ReadResponse();
                    if (response.Header == NamedPipeMessages.RegisterRepoRequest.Response.Header)
                    {
                        NamedPipeMessages.RegisterRepoRequest.Response message = NamedPipeMessages.RegisterRepoRequest.Response.FromMessage(response);

                        if (!string.IsNullOrEmpty(message.ErrorMessage))
                        {
                            errorMessage = message.ErrorMessage;
                            return(false);
                        }

                        if (message.State != NamedPipeMessages.CompletionState.Success)
                        {
                            errorMessage = "Unable to register repo. " + errorMessage;
                            return(false);
                        }
                        else
                        {
                            return(true);
                        }
                    }
                    else
                    {
                        errorMessage = string.Format("GSD.Service responded with unexpected message: {0}", response);
                        return(false);
                    }
                }
                catch (BrokenPipeException e)
                {
                    errorMessage = "Unable to communicate with GSD.Service: " + e.ToString();
                    return(false);
                }
            }
        }
예제 #19
0
        public GSDVerb(bool validateOrigin = true)
        {
            this.Output            = Console.Out;
            this.ReturnCode        = ReturnCode.Success;
            this.validateOriginURL = validateOrigin;
            this.ServiceName       = GSDConstants.Service.ServiceName;
            this.StartedByService  = false;
            this.Unattended        = GSDEnlistment.IsUnattended(tracer: null);

            this.InitializeDefaultParameterValues();
        }
예제 #20
0
        protected bool TryAuthenticate(ITracer tracer, GSDEnlistment enlistment, out string authErrorMessage)
        {
            string authError = null;

            bool result = this.ShowStatusWhileRunning(
                () => enlistment.Authentication.TryInitialize(tracer, enlistment, out authError),
                "Authenticating",
                enlistment.EnlistmentRoot);

            authErrorMessage = authError;
            return(result);
        }
예제 #21
0
 private NamedPipeServer StartNamedPipe(ITracer tracer, GSDEnlistment enlistment, out Result errorResult)
 {
     try
     {
         errorResult = new Result(true);
         return(AllowAllLocksNamedPipeServer.Create(tracer, enlistment));
     }
     catch (PipeNameLengthException)
     {
         errorResult = new Result("Failed to clone. Path exceeds the maximum number of allowed characters");
         return(null);
     }
 }
예제 #22
0
        private GSDGitObjects CreateTestableGSDGitObjects(MockHttpGitObjects httpObjects, MockFileSystemWithCallbacks fileSystem)
        {
            MockTracer    tracer     = new MockTracer();
            GSDEnlistment enlistment = new GSDEnlistment(TestEnlistmentRoot, "https://fakeRepoUrl", "fakeGitBinPath", gvfsHooksRoot: null, authentication: null);

            enlistment.InitializeCachePathsFromKey(TestLocalCacheRoot, TestObjectRoot);
            GitRepo repo = new GitRepo(tracer, enlistment, fileSystem, () => new MockLibGit2Repo(tracer));

            GSDContext    context = new GSDContext(tracer, fileSystem, repo, enlistment);
            GSDGitObjects dut     = new GSDGitObjects(context, httpObjects);

            return(dut);
        }
예제 #23
0
        private static void StartLogFile(string enlistmentRoot, JsonTracer tracer)
        {
            if (!tracer.HasLogFileEventListener)
            {
                tracer.AddLogFileEventListener(
                    GSDEnlistment.GetNewGSDLogFileName(
                        Path.Combine(enlistmentRoot, GSDPlatform.Instance.Constants.DotGSDRoot, GSDConstants.DotGSD.LogName),
                        GSDConstants.LogFileTypes.MountUpgrade),
                    EventLevel.Informational,
                    Keywords.Any);

                tracer.WriteStartEvent(enlistmentRoot, repoUrl: "N/A", cacheServerUrl: "N/A");
            }
        }
예제 #24
0
        private JsonTracer CreateTracer(GSDEnlistment enlistment, EventLevel verbosity, Keywords keywords)
        {
            JsonTracer tracer = new JsonTracer(GSDConstants.GSDEtwProviderName, "GSDMount", enlistment.GetEnlistmentId(), enlistment.GetMountId());

            tracer.AddLogFileEventListener(
                GSDEnlistment.GetNewGSDLogFileName(enlistment.GSDLogsRoot, GSDConstants.LogFileTypes.MountProcess),
                verbosity,
                keywords);
            if (this.ShowDebugWindow)
            {
                tracer.AddDiagnosticConsoleEventListener(verbosity, keywords);
            }

            return(tracer);
        }
예제 #25
0
        public static void Main(string[] args)
        {
            try
            {
                if (args.Length < 2)
                {
                    ExitWithError("Usage: gvfs.hooks.exe --git-pid=<pid> <hook> <git verb> [<other arguments>]");
                }

                bool unattended = GSDEnlistment.IsUnattended(tracer: null);

                string errorMessage;
                string normalizedCurrentDirectory;
                if (!GSDHooksPlatform.TryGetNormalizedPath(Environment.CurrentDirectory, out normalizedCurrentDirectory, out errorMessage))
                {
                    ExitWithError($"Failed to determine final path for current directory {Environment.CurrentDirectory}. Error: {errorMessage}");
                }

                if (!GSDHooksPlatform.TryGetGSDEnlistmentRoot(Environment.CurrentDirectory, out enlistmentRoot, out errorMessage))
                {
                    // Nothing to hook when being run outside of a GSD repo.
                    // This is also the path when run with --git-dir outside of a GSD directory, see Story #949665
                    Environment.Exit(0);
                }

                enlistmentPipename = GSDHooksPlatform.GetNamedPipeName(enlistmentRoot);

                switch (GetHookType(args))
                {
                case PreCommandHook:
                    CheckForLegalCommands(args);
                    RunPreCommands(args);
                    break;

                case PostCommandHook:
                    RunPostCommands(args, unattended);
                    break;

                default:
                    ExitWithError("Unrecognized hook: " + string.Join(" ", args));
                    break;
                }
            }
            catch (Exception ex)
            {
                ExitWithError("Unexpected exception: " + ex.ToString());
            }
        }
예제 #26
0
        private JsonTracer CreateTracer()
        {
            string logFilePath = GSDEnlistment.GetNewGSDLogFileName(
                this.logDirectory,
                GSDConstants.LogFileTypes.UpgradeProcess,
                this.fileSystem);

            JsonTracer jsonTracer = new JsonTracer(GSDConstants.GSDEtwProviderName, "UpgradeProcess");

            jsonTracer.AddLogFileEventListener(
                logFilePath,
                DefaultEventLevel,
                Keywords.Any);

            return(jsonTracer);
        }
예제 #27
0
        private void TestSetup()
        {
            ITracer tracer = new MockTracer();

            this.enlistment = new MockGSDEnlistment();

            // We need to have the EnlistmentRoot and GitObjectsRoot available for jobs to run
            this.fileSystem = new ReadyFileSystem(new string[]
            {
                this.enlistment.EnlistmentRoot,
                this.enlistment.GitObjectsRoot
            });

            this.context    = new GSDContext(tracer, this.fileSystem, null, this.enlistment);
            this.gitObjects = new MockPhysicalGitObjects(tracer, this.fileSystem, this.enlistment, null);
        }
예제 #28
0
            private GSDEnlistment CreateEnlistment(string enlistmentRootPath, GitAuthentication authentication)
            {
                string gitBinPath = GSDPlatform.Instance.GitInstallation.GetInstalledGitBinPath();

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

                string hooksPath = null;

                if (GSDPlatform.Instance.UnderConstruction.RequiresDeprecatedGitHooksLoader)
                {
                    // On Windows, the soon-to-be deprecated GitHooksLoader tries to call out to the hooks process without
                    // its full path, so we have to pass the path along to our background git processes via the PATH
                    // environment variable. On Mac this is not needed because we just copy our own hook directly into
                    // the .git/hooks folder, and once Windows does the same, this hooksPath can be removed (from here
                    // and all the classes that handle it on the way to GitProcess)

                    hooksPath = ProcessHelper.GetProgramLocation(GSDPlatform.Instance.Constants.ProgramLocaterCommand, GSDPlatform.Instance.Constants.GSDHooksExecutableName);
                    if (hooksPath == null)
                    {
                        this.ReportErrorAndExit("Could not find " + GSDPlatform.Instance.Constants.GSDHooksExecutableName);
                    }
                }

                GSDEnlistment enlistment = null;

                try
                {
                    enlistment = GSDEnlistment.CreateFromDirectory(
                        enlistmentRootPath,
                        gitBinPath,
                        hooksPath,
                        authentication,
                        createWithoutRepoURL: !this.validateOriginURL);
                }
                catch (InvalidRepoException e)
                {
                    this.ReportErrorAndExit(
                        "Error: '{0}' is not a valid GSD enlistment. {1}",
                        enlistmentRootPath,
                        e.Message);
                }

                return(enlistment);
            }
예제 #29
0
        protected RetryConfig GetRetryConfig(ITracer tracer, GSDEnlistment enlistment, TimeSpan?timeoutOverride = null)
        {
            RetryConfig retryConfig;
            string      error;

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

            if (timeoutOverride.HasValue)
            {
                retryConfig.Timeout = timeoutOverride.Value;
            }

            return(retryConfig);
        }
예제 #30
0
        public void Start()
        {
            if (!GSDEnlistment.IsUnattended(this.tracer))
            {
                TimeSpan startTime = TimeSpan.Zero;

                this.tracer.RelatedInfo("Starting auto upgrade checks.");
                this.timer = new Timer(
                    this.TimerCallback,
                    state: null,
                    dueTime: startTime,
                    period: TimeInterval);
            }
            else
            {
                this.tracer.RelatedInfo("No upgrade checks scheduled, GSD is running in unattended mode.");
            }
        }