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

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

            return(gvfsConfig);
        }
Ejemplo n.º 2
0
        protected ServerScalarConfig QueryScalarConfig(ITracer tracer, ScalarEnlistment enlistment, RetryConfig retryConfig)
        {
            ServerScalarConfig serverScalarConfig = null;
            string             errorMessage       = null;

            if (!this.ShowStatusWhileRunning(
                    () =>
            {
                using (ConfigHttpRequestor configRequestor = new ConfigHttpRequestor(tracer, enlistment, retryConfig))
                {
                    const bool LogErrors = true;
                    return(configRequestor.TryQueryScalarConfig(LogErrors, out serverScalarConfig, out _, out errorMessage));
                }
            },
                    "Querying remote for config"))
            {
                tracer.RelatedWarning("Unable to query /gvfs/config" + Environment.NewLine + errorMessage);
            }

            return(serverScalarConfig);
        }
Ejemplo n.º 3
0
        protected ServerGVFSConfig QueryGVFSConfig(ITracer tracer, GVFSEnlistment enlistment, RetryConfig retryConfig)
        {
            ServerGVFSConfig serverGVFSConfig = null;
            string           errorMessage     = null;

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

            return(serverGVFSConfig);
        }
Ejemplo n.º 4
0
        private bool TryAnonymousQuery(ITracer tracer, Enlistment enlistment, out bool isAnonymous)
        {
            bool querySucceeded;

            using (ITracer anonymousTracer = tracer.StartActivity("AttemptAnonymousAuth", EventLevel.Informational))
            {
                HttpStatusCode?httpStatus;

                using (ConfigHttpRequestor configRequestor = new ConfigHttpRequestor(anonymousTracer, enlistment, new RetryConfig()))
                {
                    ServerScalarConfig scalarConfig;
                    const bool         LogErrors = false;
                    if (configRequestor.TryQueryScalarConfig(LogErrors, out scalarConfig, out httpStatus, out _))
                    {
                        querySucceeded = true;
                        isAnonymous    = true;
                    }
                    else if (httpStatus == HttpStatusCode.Unauthorized)
                    {
                        querySucceeded = true;
                        isAnonymous    = false;
                    }
                    else
                    {
                        querySucceeded = false;
                        isAnonymous    = false;
                    }
                }

                anonymousTracer.Stop(new EventMetadata
                {
                    { "HttpStatus", httpStatus.HasValue ? ((int)httpStatus).ToString() : "None" },
                    { "QuerySucceeded", querySucceeded },
                    { "IsAnonymous", isAnonymous },
                });
            }

            return(querySucceeded);
        }
Ejemplo n.º 5
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));
        }
Ejemplo n.º 6
0
        private bool RequestMount(GVFSEnlistment enlistment, out string errorMessage)
        {
            this.CheckGitVersion(enlistment);
            this.CheckGVFSHooksVersion(enlistment, null);
            this.CheckAntiVirusExclusion(enlistment);

            string mountExeLocation = Path.Combine(ProcessHelper.GetCurrentProcessLocation(), MountExeName);

            if (!File.Exists(mountExeLocation))
            {
                errorMessage = "Could not find GVFS.Mount.exe. You may need to reinstall GVFS.";
                return(false);
            }

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

            const string ParamPrefix = "--";

            ProcessHelper.StartBackgroundProcess(
                mountExeLocation,
                string.Join(
                    " ",
                    enlistment.EnlistmentRoot,
                    ParamPrefix + MountParameters.Verbosity,
                    this.Verbosity,
                    ParamPrefix + MountParameters.Keywords,
                    this.KeywordsCsv,
                    this.ShowDebugWindow ? ParamPrefix + MountParameters.DebugWindow : string.Empty),
                createWindow: this.ShowDebugWindow);

            return(this.WaitForMountToComplete(enlistment, out errorMessage));
        }
Ejemplo n.º 7
0
        private Result TryClone(JsonEtwTracer tracer, GVFSEnlistment enlistment)
        {
            this.CheckVolumeSupportsDeleteNotifications(tracer, enlistment);
            this.CheckGitVersion(enlistment);

            Result pipeResult;

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

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

                using (GitObjectsHttpRequestor objectRequestor = new GitObjectsHttpRequestor(tracer, enlistment))
                {
                    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));
                }
            }
        }
Ejemplo n.º 8
0
        protected override void Execute(GVFSEnlistment enlistment)
        {
            string errorMessage = null;

            if (!HooksInstaller.InstallHooks(enlistment, out errorMessage))
            {
                this.ReportErrorAndExit("Error installing hooks: " + errorMessage);
            }

            if (!enlistment.TryConfigureAlternate(out errorMessage))
            {
                this.ReportErrorAndExit("Error configuring alternate: " + errorMessage);
            }

            using (JsonEtwTracer tracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "PreMount"))
            {
                tracer.AddLogFileEventListener(
                    GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Mount),
                    EventLevel.Verbose,
                    Keywords.Any);

                if (!this.SkipVersionCheck)
                {
                    string authErrorMessage = null;
                    if (!this.ShowStatusWhileRunning(
                            () => enlistment.Authentication.TryRefreshCredentials(tracer, out authErrorMessage),
                            "Authenticating"))
                    {
                        this.Output.WriteLine("    WARNING: " + authErrorMessage);
                        this.Output.WriteLine("    Mount will proceed, but new files cannot be accessed until GVFS can authenticate.");
                    }
                }

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

                GVFSConfig      gvfsConfig;
                CacheServerInfo cacheServer;
                using (ConfigHttpRequestor configRequestor = new ConfigHttpRequestor(tracer, enlistment, retryConfig))
                {
                    gvfsConfig = configRequestor.QueryGVFSConfig();
                }

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

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

                if (!GvFltFilter.TryAttach(tracer, enlistment.EnlistmentRoot, out errorMessage))
                {
                    if (!this.ShowStatusWhileRunning(
                            () => { return(this.AttachGvFltThroughService(enlistment, out errorMessage)); },
                            "Attaching GvFlt to volume"))
                    {
                        this.ReportErrorAndExit(errorMessage);
                    }
                }

                this.ValidateClientVersions(tracer, enlistment, gvfsConfig);
            }

            if (!this.ShowStatusWhileRunning(
                    () => { return(this.TryMount(enlistment, out errorMessage)); },
                    "Mounting"))
            {
                this.ReportErrorAndExit(errorMessage);
            }

            if (!this.ShowStatusWhileRunning(
                    () => { return(this.RegisterMount(enlistment, out errorMessage)); },
                    "Registering for automount"))
            {
                this.Output.WriteLine("    WARNING: " + errorMessage);
            }
        }
Ejemplo n.º 9
0
        public override void Execute()
        {
            int exitCode = 0;

            this.EnlistmentRootPath = this.GetCloneRoot();

            this.CheckGVFltHealthy();
            this.CheckNotInsideExistingRepo();

            try
            {
                GVFSEnlistment enlistment;
                Result         cloneResult = new Result(false);

                using (JsonEtwTracer tracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "GVFSClone"))
                {
                    cloneResult = this.TryCreateEnlistment(out enlistment);
                    if (cloneResult.Success)
                    {
                        tracer.AddLogFileEventListener(
                            GVFSEnlistment.GetNewGVFSLogFileName(enlistment.GVFSLogsRoot, GVFSConstants.LogFileTypes.Clone),
                            EventLevel.Informational,
                            Keywords.Any);

                        string authErrorMessage = null;
                        if (!this.ShowStatusWhileRunning(
                                () => enlistment.Authentication.TryRefreshCredentials(tracer, out authErrorMessage),
                                "Authenticating"))
                        {
                            this.ReportErrorAndExit("Unable to clone because authentication failed");
                        }

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

                        retryConfig.Timeout = TimeSpan.FromMinutes(RetryConfig.FetchAndCloneTimeoutMinutes);

                        GVFSConfig      gvfsConfig;
                        CacheServerInfo cacheServer;
                        using (ConfigHttpRequestor configRequestor = new ConfigHttpRequestor(tracer, enlistment, retryConfig))
                        {
                            gvfsConfig = configRequestor.QueryGVFSConfig();
                        }

                        if (!CacheServerInfo.TryDetermineCacheServer(this.CacheServerUrl, enlistment, gvfsConfig.CacheServers, out cacheServer, out error))
                        {
                            this.ReportErrorAndExit(error);
                        }

                        tracer.WriteStartEvent(
                            enlistment.EnlistmentRoot,
                            enlistment.RepoUrl,
                            cacheServer.Url,
                            new EventMetadata
                        {
                            { "Branch", this.Branch },
                            { "SingleBranch", this.SingleBranch },
                            { "NoMount", this.NoMount },
                            { "NoPrefetch", this.NoPrefetch }
                        });

                        this.Output.WriteLine("Clone parameters:");
                        this.Output.WriteLine("  Repo URL:     " + enlistment.RepoUrl);
                        this.Output.WriteLine("  Cache Server: " + cacheServer);
                        this.Output.WriteLine("  Destination:  " + enlistment.EnlistmentRoot);

                        this.ValidateClientVersions(tracer, enlistment, gvfsConfig);

                        this.ShowStatusWhileRunning(
                            () =>
                        {
                            cloneResult = this.TryClone(tracer, enlistment, cacheServer, retryConfig);
                            return(cloneResult.Success);
                        },
                            "Cloning");
                    }

                    if (!cloneResult.Success)
                    {
                        tracer.RelatedError(cloneResult.ErrorMessage);
                    }
                }

                if (cloneResult.Success)
                {
                    if (!this.NoPrefetch)
                    {
                        PrefetchVerb prefetch = new PrefetchVerb();
                        prefetch.EnlistmentRootPath = this.EnlistmentRootPath;
                        prefetch.Commits            = true;
                        prefetch.Execute();
                    }

                    if (this.NoMount)
                    {
                        this.Output.WriteLine("\r\nIn order to mount, first cd to within your enlistment, then call: ");
                        this.Output.WriteLine("gvfs mount");
                    }
                    else
                    {
                        MountVerb mount = new MountVerb();
                        mount.EnlistmentRootPath = this.EnlistmentRootPath;
                        mount.SkipMountedCheck   = true;
                        mount.SkipVersionCheck   = true;
                        mount.ServiceName        = this.ServiceName;

                        mount.Execute();
                    }
                }
                else
                {
                    this.Output.WriteLine("\r\nCannot clone @ {0}", this.EnlistmentRootPath);
                    this.Output.WriteLine("Error: {0}", cloneResult.ErrorMessage);
                    exitCode = (int)ReturnCode.GenericError;
                }
            }
            catch (AggregateException e)
            {
                this.Output.WriteLine("Cannot clone @ {0}:", this.EnlistmentRootPath);
                foreach (Exception ex in e.Flatten().InnerExceptions)
                {
                    this.Output.WriteLine("Exception: {0}", ex.ToString());
                }

                exitCode = (int)ReturnCode.GenericError;
            }
            catch (VerbAbortedException)
            {
                throw;
            }
            catch (Exception e)
            {
                this.ReportErrorAndExit("Cannot clone @ {0}: {1}", this.EnlistmentRootPath, e.ToString());
            }

            Environment.Exit(exitCode);
        }
Ejemplo n.º 10
0
        protected override void Execute(GVFSEnlistment enlistment)
        {
            using (ITracer tracer = new JsonEtwTracer(GVFSConstants.GVFSEtwProviderName, "CacheVerb"))
            {
                RetryConfig retryConfig;
                string      error;
                if (!RetryConfig.TryLoadFromGitConfig(tracer, enlistment, out retryConfig, out error))
                {
                    this.ReportErrorAndExit("Failed to determine GVFS timeout and max retries: " + error);
                }

                GVFSConfig config;
                using (ConfigHttpRequestor configRequestor = new ConfigHttpRequestor(tracer, enlistment, retryConfig))
                {
                    config = configRequestor.QueryGVFSConfig();
                    if (config == null)
                    {
                        this.ReportErrorAndExit("Could not query for available cache servers.");
                    }
                }

                CacheServerInfo cache;
                if (!string.IsNullOrWhiteSpace(this.CacheToSet))
                {
                    if (CacheServerInfo.TryParse(this.CacheToSet, enlistment, config.CacheServers, out cache))
                    {
                        if (!CacheServerInfo.TrySaveToConfig(new GitProcess(enlistment), cache, out error))
                        {
                            this.ReportErrorAndExit("Failed to save cache to config: " + error);
                        }
                    }
                    else
                    {
                        this.ReportErrorAndExit("Unrecognized or invalid cache name or url: " + this.CacheToSet);
                    }

                    this.OutputCacheInfo(cache);
                    this.Output.WriteLine("You must remount GVFS for this to take effect.");
                }
                else if (this.ListCacheServers)
                {
                    if (config.CacheServers.Any())
                    {
                        this.Output.WriteLine("Available cache servers for: " + enlistment.RepoUrl);
                        foreach (CacheServerInfo cacheServer in config.CacheServers)
                        {
                            this.Output.WriteLine("{0, -25} ({1})", cacheServer.Name, cacheServer.Url);
                        }
                    }
                    else
                    {
                        this.Output.WriteLine("There are no available cache servers for: " + enlistment.RepoUrl);
                    }
                }
                else
                {
                    if (!CacheServerInfo.TryDetermineCacheServer(null, enlistment, config.CacheServers, out cache, out error))
                    {
                        this.ReportErrorAndExit(error);
                    }

                    this.OutputCacheInfo(cache);
                }
            }
        }