[autotest] Generalize container host mounts.

- Generalize the host mount so it doesn't just enable mounting
  content into the /usr/local/autotest directory in the container.
- Factor out code for copying files into the container.
- Use the new host mount to implement copying files
  into the zygote.
- Reimplement control file installation and config deployment
  using the new copy method.
- Add tests.

BUG=chromium:720219
TEST=sudo python container_unittest.py -v
TEST=sudo python container_bucket_unittest.py -v
TEST=sudo python zygote_unittest.py -v
TEST=sudo python lxc_config_unittest.py -v
TEST=sudo python lxc_functional_test.py -v

Change-Id: I7f2fa48760337fe9d20cc6518879adf90d72ead0
Reviewed-on: https://chromium-review.googlesource.com/586049
Commit-Ready: Ben Kwa <[email protected]>
Tested-by: Ben Kwa <[email protected]>
Reviewed-by: Aviv Keshet <[email protected]>
diff --git a/site_utils/lxc/config.py b/site_utils/lxc/config.py
index 4093e2f..833ed06 100644
--- a/site_utils/lxc/config.py
+++ b/site_utils/lxc/config.py
@@ -107,7 +107,7 @@
                                              'ssp_deploy_shadow_config.json')
 # A temp folder used to store files to be appended to the files inside
 # container.
-APPEND_FOLDER = 'usr/local/ssp_append'
+_APPEND_FOLDER = '/usr/local/ssp_append'
 
 DeployConfig = collections.namedtuple(
         'DeployConfig', ['source', 'target', 'append', 'permission'])
@@ -228,10 +228,11 @@
                                if 'append' in c]
         self.mount_configs = [self.validate_mount(c) for c in deploy_configs
                               if 'mount' in c]
-        self.tmp_append = os.path.join(self.container.rootfs, APPEND_FOLDER)
-        if lxc_utils.path_exists(self.tmp_append):
-            utils.run('sudo rm -rf "%s"' % self.tmp_append)
-        utils.run('sudo mkdir -p "%s"' % self.tmp_append)
+        tmp_append = os.path.join(self.container.rootfs,
+                                  _APPEND_FOLDER.lstrip(os.path.sep))
+        if lxc_utils.path_exists(tmp_append):
+            utils.run('sudo rm -rf "%s"' % tmp_append)
+        utils.run('sudo mkdir -p "%s"' % tmp_append)
 
 
     def _deploy_config_pre_start(self, deploy_config):
@@ -242,28 +243,17 @@
         function.
 
         @param deploy_config: Config to be deployed.
-
         """
         if not lxc_utils.path_exists(deploy_config.source):
             return
         # Path to the target file relative to host.
         if deploy_config.append:
-            target = os.path.join(self.tmp_append,
+            target = os.path.join(_APPEND_FOLDER,
                                   os.path.basename(deploy_config.target))
         else:
-            target = os.path.join(self.container.rootfs,
-                                  deploy_config.target[1:])
-        # Recursively copy files/folder to the target. `-L` to always follow
-        # symbolic links in source.
-        target_dir = os.path.dirname(target)
-        if not lxc_utils.path_exists(target_dir):
-            utils.run('sudo mkdir -p "%s"' % target_dir)
-        source = deploy_config.source
-        # Make sure the source ends with `/.` if it's a directory. Otherwise
-        # command cp will not work.
-        if os.path.isdir(source) and source[-1] != '.':
-            source += '/.' if source[-1] != '/' else '.'
-        utils.run('sudo cp -RL "%s" "%s"' % (source, target))
+            target = deploy_config.target
+
+        self.container.copy(deploy_config.source, target)
 
 
     def _deploy_config_post_start(self, deploy_config):
@@ -279,7 +269,7 @@
 
         """
         if deploy_config.append:
-            source = os.path.join('/', APPEND_FOLDER,
+            source = os.path.join(_APPEND_FOLDER,
                                   os.path.basename(deploy_config.target))
             self.container.attach_run('cat \'%s\' >> \'%s\'' %
                                       (source, deploy_config.target))