[autotest] Destroy container when test using SSP is aborted.

The logic to abort a test was changed in following CL:
https://chromium-review.googlesource.com/230323
drone utility sends a SIGKILL directly to autoserv process to kill the test job.
This prevents autoserv from run the code in SIGTERM handler, where container can
be destroyed.

This CL also make sure results folder has the right permission after the test is
finished in several code path:
1. Test completed without being aborted.
2. Test was aborted
3. scheduler queues a write_to_file call in drone to write to status.log
indicating the action to abort the test.

BUG=chromium:474011
TEST=local test
1. run a test with SSP, abort, make sure container is destroyed and status.log
has the complete information about job being aborted.
2. run a test without SSP, abort, confirm everything behaves as usual.
3. run test with/without SSP, let the job finish. Confirm there is no error.

Change-Id: If6e70dd8c72bf10f6d81a528cfd4a70541e1593e
Reviewed-on: https://chromium-review.googlesource.com/266732
Tested-by: Dan Shi <dshi@chromium.org>
Reviewed-by: Simran Basi <sbasi@chromium.org>
Commit-Queue: Dan Shi <dshi@chromium.org>
diff --git a/server/autoserv b/server/autoserv
index 1489799..60ee3d4 100755
--- a/server/autoserv
+++ b/server/autoserv
@@ -198,6 +198,25 @@
         test_container.destroy()
 
 
+def correct_results_folder_permission(results):
+    """Make sure the results folder has the right permission settings.
+
+    For tests running with server-side packaging, the results folder has the
+    owner of root. This must be changed to the user running the autoserv
+    process, so parsing job can access the results folder.
+    TODO(dshi): crbug.com/459344 Remove this function when test container can be
+    unprivileged container.
+
+    @param results: Path to the results folder.
+
+    """
+    if not results:
+        return
+
+    lxc.run('chown -R %s "%s"' % (os.getuid(), results))
+    lxc.run('chgrp -R %s "%s"' % (os.getgid(), results))
+
+
 def run_autoserv(pid_file_manager, results, parser, ssp_url, use_ssp):
     """Run server job with given options.
 
@@ -235,6 +254,12 @@
         if pid_file_manager:
             pid_file_manager.close_file(1, signal.SIGTERM)
         logging.debug('Finished writing to pid_file. Killing process.')
+
+        # Update results folder's file permission. This needs to be done ASAP
+        # before the parsing process tries to access the log.
+        if use_ssp and results:
+            correct_results_folder_permission(results)
+
         # TODO (sbasi) - remove the time.sleep when crbug.com/302815 is solved.
         # This sleep allows the pending output to be logged before the kill
         # signal is sent.
@@ -242,17 +267,29 @@
         if use_ssp:
             logging.debug('Destroy container %s before aborting the autoserv '
                           'process.', container_name)
+            metadata = {'drone': socket.gethostname(),
+                        'job_id': job_or_task_id,
+                        'container_name': container_name,
+                        'action': 'abort',
+                        'success': True}
             try:
                 bucket = lxc.ContainerBucket()
                 container = bucket.get(container_name)
                 if container:
                     container.destroy()
                 else:
+                    metadata['success'] = False
+                    metadata['error'] = 'container not found'
                     logging.debug('Container %s is not found.', container_name)
             except:
+                metadata['success'] = False
+                metadata['error'] = 'Exception: %s' % sys.exc_info()
                 # Handle any exception so the autoserv process can be aborted.
                 logging.error('Failed to destroy container %s. Error: %s',
                               container_name, sys.exc_info())
+            autotest_es.post(use_http=True,
+                             type_str=lxc.CONTAINER_RUN_TEST_METADB_TYPE,
+                             metadata=metadata)
 
         os.killpg(os.getpgrp(), signal.SIGKILL)
 
@@ -375,11 +412,7 @@
                                       parser, ssp_url)
                     finally:
                         # Update the ownership of files in result folder.
-                        # TODO(dshi): crbug.com/459344 Skip following action
-                        # when test container can be unprivileged container.
-                        if results:
-                            lxc.run('chown -R %s %s' % (os.getuid(), results))
-                            lxc.run('chgrp -R %s %s' % (os.getgid(), results))
+                        correct_results_folder_permission(results)
                 else:
                     job.run(install_before, install_after,
                             verify_job_repo_url=verify_job_repo_url,
@@ -503,6 +536,8 @@
             os.makedirs(log_dir)
     else:
         log_dir = results
+        correct_results_folder_permission(results)
+
     logging_manager.configure_logging(
             server_logging_config.ServerLoggingConfig(),
             results_dir=log_dir,