[autotest] Pass current user into container for RPC usage

RPC is called using current OS user if not specified (frontend.py). This causes
an issue for autoserv running inside container, as the OS user is always root.
The root user may fail check_for_acl_violation_hosts if a host has special ACL
that does not allow `everyone`.

This CL add an SSP/user config in global config, lxc related code is updated so
that the OS user of autoserv running in host will be passed into the container
through shadow_config.ini. And frontend will use such user to make RPC.

BUG=chromium:480525,chromium:502897
TEST=local
sudo python site_utils/lxc_functional_test.py -v -s
attach to the container
update SSP/user with a user name (existing one should be root as the process
site_utils/lxc_functional_test.py is executed with sudo)
update frontend.py with code in this CL (this means only newer builds won't
be hit by this bug.)
run some RPC:
import common
from autotest_lib.server.cros.dynamic_suite import frontend_wrappers
_AFE = frontend_wrappers.RetryingAFE()
print _AFE.run('get_stable_version')

Also make sure afe in the host still works.

Change-Id: I9ba924e2652fadffa71d6298f74c5b82e8e26b4e
Reviewed-on: https://chromium-review.googlesource.com/281062
Trybot-Ready: Dan Shi <dshi@chromium.org>
Tested-by: Dan Shi <dshi@chromium.org>
Reviewed-by: Simran Basi <sbasi@chromium.org>
Commit-Queue: Dan Shi <dshi@chromium.org>
diff --git a/client/common_lib/site_utils.py b/client/common_lib/site_utils.py
index 3be5d4e..48c7175 100644
--- a/client/common_lib/site_utils.py
+++ b/client/common_lib/site_utils.py
@@ -542,3 +542,15 @@
     except error.CmdError:
         logging.warn('sudo command requires password.')
         return True
+
+
+def is_in_container():
+    """Check if the process is running inside a container.
+
+    @return: True if the process is running inside a container, otherwise False.
+    """
+    try:
+        base_utils.run('cat /proc/1/cgroup | grep "/lxc/" || false')
+        return True
+    except error.CmdError:
+        return False
\ No newline at end of file
diff --git a/global_config.ini b/global_config.ini
index e87cb00..d0abb88 100644
--- a/global_config.ini
+++ b/global_config.ini
@@ -315,3 +315,10 @@
 # commands: build_externals test_importer etc
 # Set this with service names that should be restarted after every update.
 # services:
+
+[SSP]
+# Section for configuration needed for server-side packaging.
+# User that runs the autoserv process in the host of the container.
+# The user is passed to a container through global config file so a process
+# running inside the container can use the same user to make RPC.
+user:
\ No newline at end of file
diff --git a/server/autoserv b/server/autoserv
index 7b7165f..fcd1dce 100755
--- a/server/autoserv
+++ b/server/autoserv
@@ -562,7 +562,7 @@
 
         # wait until now to perform this check, so it get properly logged
         if (parser.options.use_existing_results and not resultdir_exists and
-            not lxc_utils.is_in_container()):
+            not utils.is_in_container()):
             logging.error("No existing results directory found: %s", results)
             sys.exit(1)
 
diff --git a/server/frontend.py b/server/frontend.py
index 8b1f549..bca99f8 100644
--- a/server/frontend.py
+++ b/server/frontend.py
@@ -61,6 +61,8 @@
             print_log: pring a logging message to stdout on every operation
             debug: print out all RPC traffic
         """
+        if not user and utils.is_in_container():
+            user = GLOBAL_CONFIG.get_config_value('SSP', 'user', default=None)
         if not user:
             user = getpass.getuser()
         if not server:
diff --git a/server/site_tests/ssp_PackageInstall/ssp_PackageInstall.py b/server/site_tests/ssp_PackageInstall/ssp_PackageInstall.py
index 86d0474..732e40e 100644
--- a/server/site_tests/ssp_PackageInstall/ssp_PackageInstall.py
+++ b/server/site_tests/ssp_PackageInstall/ssp_PackageInstall.py
@@ -8,7 +8,6 @@
 from autotest_lib.client.common_lib import error
 from autotest_lib.server import test
 from autotest_lib.site_utils import lxc
-from autotest_lib.site_utils import lxc_utils
 
 
 class ssp_PackageInstall(test.test):
@@ -49,7 +48,7 @@
                 any of the given packages failed to be installed.
 
         """
-        if not lxc_utils.is_in_container():
+        if not utils.is_in_container():
             raise error.TestError('Install OS package is only supported in '
                                   'server-side packaging.')
         # Test OS package can be used.
diff --git a/site_utils/lxc.py b/site_utils/lxc.py
index c564f40..2cb60e0 100644
--- a/site_utils/lxc.py
+++ b/site_utils/lxc.py
@@ -305,7 +305,7 @@
     if not install_package_precheck(package):
         return
 
-    if not lxc_utils.is_in_container():
+    if not utils.is_in_container():
         raise error.ContainerError('Package installation is only supported '
                                    'when test is running inside container.')
     # Always run apt-get update before installing any container. The base
diff --git a/site_utils/lxc_config.py b/site_utils/lxc_config.py
index b66689d..d6b331c 100644
--- a/site_utils/lxc_config.py
+++ b/site_utils/lxc_config.py
@@ -51,6 +51,7 @@
 """
 
 import collections
+import getpass
 import json
 import os
 import socket
@@ -219,6 +220,9 @@
         2. Update AUTOTEST_WEB/host and SERVER/hostname to be the IP of the host
            if any is set to localhost or 127.0.0.1. Otherwise, set it to be the
            FQDN of the config value.
+        3. Update SSP/user, which is used as the user makes RPC inside the
+           container. This allows the RPC to pass ACL check as if the call is
+           made in the host.
 
         """
         shadow_config = os.path.join(CONTAINER_AUTOTEST_DIR,
@@ -249,6 +253,11 @@
         self.container.attach_run('echo $\'\n[SERVER]\nhostname: %s\n\' >> %s' %
                                   (new_host, shadow_config))
 
+        # Update SSP/user
+        self.container.attach_run(
+                'echo $\'\n[SSP]\nuser: %s\n\' >> %s' %
+                (getpass.getuser(), shadow_config))
+
 
     def _modify_ssh_config(self):
         """Modify ssh config for it to work inside container.
diff --git a/site_utils/lxc_utils.py b/site_utils/lxc_utils.py
index 192d2f5..4368013 100644
--- a/site_utils/lxc_utils.py
+++ b/site_utils/lxc_utils.py
@@ -12,18 +12,6 @@
 from autotest_lib.client.common_lib import error
 
 
-def is_in_container():
-    """Check if the process is running inside a container.
-
-    @return: True if the process is running inside a container, otherwise False.
-    """
-    try:
-        utils.run('cat /proc/1/cgroup | grep "/lxc/" || false')
-        return True
-    except error.CmdError:
-        return False
-
-
 def path_exists(path):
     """Check if path exists.