toolkit: chown and chmod on-the-fly when copying files

Since root is always able to read anything, we don't have to chown to
root when sudo is asked. We just have to tell rsync to chown and chmod
on-the-fly when copying files.

Should not affect the case that sudo is not present.

BUG=b/33094336
TEST=Unit test && manually tested:
    1. BOARD=gru make toolkit
    2. [sudo] build/install_factory_toolkit.run chromiumos_test_image.bin
    3. saw it succeeded and temp files were removed
    4. mount stateful partition and check /usr/local/factory, saw the
       right owner, group, and permission

Change-Id: I564d4c6d4e8c17d3e9d9220163b6f73a3ccff7a8
Reviewed-on: https://chromium-review.googlesource.com/414685
Commit-Ready: Mao Huang <littlecvr@chromium.org>
Tested-by: Mao Huang <littlecvr@chromium.org>
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
diff --git a/py/toolkit/installer.py b/py/toolkit/installer.py
index b2cf9e1..f4c645f 100755
--- a/py/toolkit/installer.py
+++ b/py/toolkit/installer.py
@@ -281,30 +281,18 @@
 
   def Install(self):
     print '*** Installing factory toolkit...'
-    for src, dest in ((self._usr_local_src, self._usr_local_dest),):
-      # Change the source directory to root, and add group/world read
-      # permissions.  This is necessary because when the toolkit was
-      # unpacked, the user may not have been root so the permessions
-      # may be hosed.  This is skipped for testing.
-      # --force is necessary to allow goofy directory from prior
-      # toolkit installations to be overwritten by the goofy symlink.
-      try:
-        if self._sudo:
-          Spawn(['chown', '-R', 'root', src],
-                sudo=True, log=True, check_call=True)
-          Spawn(['chmod', '-R', 'go+rX', src],
-                sudo=True, log=True, check_call=True)
-        print '***   %s -> %s' % (src, dest)
-        Spawn(['rsync', '-a', '--force'] + SERVER_FILE_MASK +
-              [src + '/', dest], sudo=self._sudo, log=True,
-              check_output=True, cwd=src)
-      finally:
-        # Need to change the source directory back to the original user, or the
-        # script in makeself will fail to remove the temporary source directory.
-        if self._sudo:
-          myuser = os.environ.get('USER')
-          Spawn(['chown', '-R', myuser, src],
-                sudo=True, log=True, check_call=True)
+
+    # --no-owner and --no-group will set owner/group to the current user/group
+    # running the command. This is important if we're running with sudo, so
+    # the destination will be changed to root/root instead of the user/group
+    # before sudo (doesn't matter if sudo is not present). --force is also
+    # necessary to allow goofy directory from prior toolkit installations to
+    # be overwritten by the goofy symlink.
+    print '***   %s -> %s' % (self._usr_local_src, self._usr_local_dest)
+    Spawn(['rsync', '-a', '--no-owner', '--no-group', '--chmod=ugo+rX',
+           '--force'] + SERVER_FILE_MASK + [self._usr_local_src + '/',
+                                            self._usr_local_dest],
+          sudo=self._sudo, log=True, check_output=True, cwd=self._usr_local_src)
 
     print '*** Ensure SSH keys file permission...'
     sshkeys_dir = os.path.join(self._usr_local_dest, 'factory/misc/sshkeys')