acloud create: If setup was skipped, tell the user to do it, nicely.
We can tell if the user needs a config file or host setup based on the
create action they specified so instead of raising an exception
somewhere and confusing them, point them to run acloud setup.
Bug: 110383583
Test: acloud create with no ~/.config/acloud/acloud.config
Change-Id: Id0aabbea821f9d9f6f5fc3c5d0ea277284e5bdd7
diff --git a/create/create.py b/create/create.py
index 81710f4..d7ae932 100644
--- a/create/create.py
+++ b/create/create.py
@@ -20,6 +20,10 @@
image artifacts.
"""
+from __future__ import print_function
+
+import sys
+
from acloud import errors
from acloud.create import avd_spec
from acloud.create import local_image_local_instance
@@ -27,6 +31,10 @@
from acloud.create import remote_image_remote_instance
from acloud.create import remote_image_local_instance
from acloud.internal import constants
+from acloud.internal.lib import utils
+from acloud.setup import setup
+from acloud.setup import gcp_setup_runner
+from acloud.setup import host_setup_runner
def GetAvdCreatorClass(instance_type, image_source):
@@ -60,12 +68,53 @@
(instance_type, image_source))
+def PreRunCheck(args):
+ """Check that host is setup to run the create commands.
+
+ We'll check we have the necessary bits setup to do what the user wants, and
+ if not, tell them what they need to do before running create again.
+
+ Args:
+ args: Namespace object from argparse.parse_args.
+ """
+ run_setup = False
+ # Need to set all these so if we need to run setup, it won't barf on us
+ # because of some missing fields.
+ args.gcp_init = False
+ args.host = False
+ args.force = False
+ # Remote image/instance requires the GCP config setup.
+ if not args.local_instance or args.local_image == "":
+ gcp_setup = gcp_setup_runner.GcpTaskRunner(args.config_file)
+ if gcp_setup.ShouldRun():
+ args.gcp_init = True
+ run_setup = True
+
+ # Local instance requires host to be setup.
+ if args.local_instance:
+ host_pkg_setup = host_setup_runner.AvdPkgInstaller()
+ host_env_setup = host_setup_runner.CuttlefishHostSetup()
+ if host_pkg_setup.ShouldRun() or host_env_setup.ShouldRun():
+ args.host = True
+ run_setup = True
+
+ if run_setup:
+ answer = utils.InteractWithQuestion("Missing necessary acloud setup, "
+ "would you like to run setup[y]?")
+ if answer in constants.USER_ANSWER_YES:
+ setup.Run(args)
+ else:
+ print("Please run '#acloud setup' so we can get your host setup")
+ sys.exit()
+
+
def Run(args):
"""Run create.
Args:
args: Namespace object from argparse.parse_args.
"""
+ PreRunCheck(args)
spec = avd_spec.AVDSpec(args)
avd_creator_class = GetAvdCreatorClass(spec.instance_type,
spec.image_source)
diff --git a/setup/gcp_setup_runner.py b/setup/gcp_setup_runner.py
index f50b2c0..30074a5 100644
--- a/setup/gcp_setup_runner.py
+++ b/setup/gcp_setup_runner.py
@@ -198,11 +198,7 @@
self.storage_bucket_name = cfg.storage_bucket_name
self.ssh_private_key_path = cfg.ssh_private_key_path
self.ssh_public_key_path = cfg.ssh_public_key_path
-
- # Write default stable_host_image_name with dummy value.
- # TODO(113091773): An additional step to create the host image.
- if not cfg.stable_host_image_name:
- UpdateConfigFile(self.config_path, "stable_host_image_name", "")
+ self.stable_host_image_name = cfg.stable_host_image_name
def ShouldRun(self):
"""Check if we actually need to run GCP setup.
@@ -236,9 +232,18 @@
google_sdk_runner = GoogleSDKBins(google_sdk_init.GetSDKBinPath())
self._SetupProject(google_sdk_runner)
self._EnableGcloudServices(google_sdk_runner)
+ self._CreateStableHostImage()
finally:
google_sdk_init.CleanUp()
+ def _CreateStableHostImage(self):
+ """Create the stable host image."""
+ # Write default stable_host_image_name with dummy value.
+ # TODO(113091773): An additional step to create the host image.
+ if not self.stable_host_image_name:
+ UpdateConfigFile(self.config_path, "stable_host_image_name", "")
+
+
def _NeedProjectSetup(self):
"""Confirm project setup should run or not.