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