From 83058f5f4ecd5c7e703abb3fd0f6eb406f0ec7ad Mon Sep 17 00:00:00 2001 From: Mike Schinkel Date: Sun, 11 Aug 2024 21:49:26 -0400 Subject: [PATCH] Add `MUTAGEN_USE_SUDO` enviroment var - Allow `MUTAGEN_USE_SUDO=1` to cause `agent.connect()` calls to be prefixed with `sudo` and a prior check to ensure the executable exists. This allows an admin to pre-configure `visudo` to support access to specific directories that otherwise require enhanced privledges, i.e. Docker volumes at `/var/lib/docker/volumes/*/_data` - If the executable does not exist the value of the constant `notInstalledFlag` which is `"Agent not installed"` is written to the error log. - If `"Agent not installed"` is returned in the error output then `connect()` returns with `TryInstall` set to `true` to cause the installer to install the agent. --- pkg/agent/dial.go | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/pkg/agent/dial.go b/pkg/agent/dial.go index 62b80b55..9bdeb7f3 100644 --- a/pkg/agent/dial.go +++ b/pkg/agent/dial.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "os" "strings" "time" "unicode/utf8" @@ -26,6 +27,10 @@ const ( // agentErrorInMemoryCutoff is the maximum number of bytes that Mutagen will // capture in memory from the standard error output of an agent process. agentErrorInMemoryCutoff = 32 * 1024 + + // notExistsFlag will be returns to signal the agent does not exist + // and so should be installed + notInstalledFlag string = "Agent not installed" ) // connect connects to an agent-based endpoint using the specified transport, @@ -65,8 +70,14 @@ func connect(logger *logging.Logger, transport Transport, mode, prompter string, BaseName, }, pathSeparator) + // Add sudo if environment variable says to add sudo + var sudo string + if os.Getenv("MUTAGEN_USE_SUDO") == "1" { + sudo = fmt.Sprintf("test ! -f '%s' && printf '%s' >&2 || sudo ", agentInvocationPath, notInstalledFlag) + } + // Compute the command to invoke. - command := fmt.Sprintf("%s %s --%s=%s", agentInvocationPath, mode, FlagLogLevel, logger.Level()) + command := fmt.Sprintf("%s%s %s --%s=%s", sudo, agentInvocationPath, mode, FlagLogLevel, logger.Level()) // Set up (but do not start) an agent process. message := "Connecting to agent (POSIX)..." @@ -134,6 +145,12 @@ func connect(logger *logging.Logger, transport Transport, mode, prompter string, // whitespace (primarily trailing newlines), and neutralize any control // characters. errorOutput := errorBuffer.String() + + if errorOutput == notInstalledFlag { + // true=TryInstall + return nil, true, cmdExe, errors.New("agent not installed") + } + if !utf8.ValidString(errorOutput) { return nil, false, false, errors.New("remote did not return UTF-8 output") }