Set CROS_ARTIFACTS_TMP_DIR for ebuilds.

For a given package, CROS_ARTIFACTS_TMP_DIR is set to a directory
where ebuild artifacts can be stored. During merging, these
are moved to "/var/lib/chromeos/package-artifacts/${CATEGORY}/${PF}"
if merging succeeds, or to
"/var/lib/chromeos/package-artifacts/${CATEGORY}/${PF}-failed"
otherwise.

BUG=b:187795688
TEST=CQ

Change-Id: I74eeb68695d9bfb492a53589ca2d5a38dae4f99c
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/portage_tool/+/3625991
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Tested-by: Michael Benfield <mbenfield@google.com>
Commit-Queue: Mike Frysinger <vapier@chromium.org>
diff --git a/lib/portage/dbapi/vartree.py b/lib/portage/dbapi/vartree.py
index 087061b..8b7df6c 100644
--- a/lib/portage/dbapi/vartree.py
+++ b/lib/portage/dbapi/vartree.py
@@ -5466,6 +5466,24 @@
 		fd_pipes=fd_pipes)
 	merge_task.start()
 	retcode = merge_task.wait()
+
+	# Move the temporary artifacts to a permanent location.
+	artifacts_tmp = settings['CROS_ARTIFACTS_TMP_DIR']
+	try:
+		os.rmdir(artifacts_tmp)
+		is_empty = True
+	except OSError as e:
+		if e.errno != errno.ENOTEMPTY:
+			raise
+		is_empty = False
+	artifacts_dir = os.path.join(
+		'/var/lib/chromeos/package-artifacts',
+		settings['CATEGORY'],
+		settings['PF'] + ('-failed' if retcode else ''))
+	shutil.rmtree(artifacts_dir, ignore_errors=True)
+	if not is_empty:
+		os.rename(artifacts_tmp, artifacts_dir)
+
 	return retcode
 
 def unmerge(cat, pkg, myroot=None, settings=None,
diff --git a/lib/portage/package/ebuild/doebuild.py b/lib/portage/package/ebuild/doebuild.py
index 849705f..a338a33 100644
--- a/lib/portage/package/ebuild/doebuild.py
+++ b/lib/portage/package/ebuild/doebuild.py
@@ -404,6 +404,8 @@
 			mysettings["BUILD_PREFIX"],
 			mysettings["CATEGORY"], mysettings["PF"])
 
+	mysettings["CROS_ARTIFACTS_TMP_DIR"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "cros-artifacts")
+
 	mysettings["HOME"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "homedir")
 	mysettings["WORKDIR"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "work")
 	mysettings["D"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "image") + os.sep
@@ -838,6 +840,12 @@
 					builddir_lock.scheduler.run_until_complete(
 						builddir_lock.async_unlock())
 
+			shutil.rmtree(mysettings["CROS_ARTIFACTS_TMP_DIR"], ignore_errors=True)
+			# Create the directory, making it world readable and writable, to avoid any
+			# problems with writing and reading by different users.
+			os.makedirs(mysettings["CROS_ARTIFACTS_TMP_DIR"], exist_ok=True)
+			os.chmod(mysettings["CROS_ARTIFACTS_TMP_DIR"], 0o777)
+
 		# get possible slot information from the deps file
 		if mydo == "depend":
 			writemsg("!!! DEBUG: dbkey: %s\n" % str(dbkey), 2)