Allow run_command to run as user

This commit is contained in:
Melissa LeBlanc-Williams 2023-09-12 11:48:45 -07:00
parent 205d2faf9d
commit 4e2a55651d
2 changed files with 24 additions and 3 deletions

View file

@ -396,4 +396,4 @@ min-public-methods=1
# Exceptions that will emit a warning when being caught. Defaults to # Exceptions that will emit a warning when being caught. Defaults to
# "Exception" # "Exception"
overgeneral-exceptions=Exception overgeneral-exceptions=builtins.Exception

View file

@ -29,6 +29,7 @@ import fcntl
import platform import platform
import fileinput import fileinput
import re import re
import pwd
from datetime import datetime from datetime import datetime
from clint.textui import colored, prompt from clint.textui import colored, prompt
import adafruit_platformdetect import adafruit_platformdetect
@ -65,7 +66,9 @@ class Shell:
) )
return prompt.options(message, options) return prompt.options(message, options)
def run_command(self, cmd, suppress_message=False, return_output=False): def run_command(
self, cmd, suppress_message=False, return_output=False, run_as_user=None
):
""" """
Run a shell command and show the output as it runs Run a shell command and show the output as it runs
""" """
@ -79,13 +82,31 @@ class Shell:
except TypeError: except TypeError:
return "" return ""
# Allow running as a different user if we are root
if self.is_root() and run_as_user is not None:
pw_record = pwd.getpwnam(run_as_user)
env = os.environ.copy()
env["HOME"] = pw_record.pw_dir
env["LOGNAME"] = run_as_user
env["USER"] = pw_record.pw_name
def preexec():
os.setgid(pw_record.pw_gid)
os.setuid(pw_record.pw_uid)
else:
env = None
preexec = None
full_output = "" full_output = ""
with subprocess.Popen( with subprocess.Popen( # pylint: disable=subprocess-popen-preexec-fn
cmd, cmd,
shell=True, shell=True,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
universal_newlines=True, universal_newlines=True,
env=env,
preexec_fn=preexec,
) as proc: ) as proc:
while proc.poll() is None: while proc.poll() is None:
err = read_stream(proc.stderr) err = read_stream(proc.stderr)