diff --git a/conjureup/controllers/deploy/gui.py b/conjureup/controllers/deploy/gui.py
index 66958e6..54f872c 100644
--- a/conjureup/controllers/deploy/gui.py
+++ b/conjureup/controllers/deploy/gui.py
@@ -24,13 +24,22 @@ class DeployController:
         self.assignments = defaultdict(list)
         self.deployed_juju_machines = {}
         self.maas_machine_map = {}
-        self.sync_with_bundle()
+        self.init_machines_assignments()
 
-    def sync_with_bundle(self):
-        # If no machines are specified, add a machine for each app:
+    def init_machines_assignments(self):
+        """Initialize the controller's machines and assignments.
+
+        If no machines are specified, or we are deploying to a LXD
+        controller, add a top-level machine for each app - assumes
+        that no placement directives exist in the bundle, and logs any
+        it finds.
+
+        Otherwise, syncs assignments from the bundle's applications'
+        placement specs.
+        """
         bundle = app.metadata_controller.bundle
 
-        if len(bundle.machines) == 0:
+        if len(bundle.machines) == 0 or app.current_cloud == "localhost":
             self.generate_juju_machines()
         else:
             self.sync_assignments()
@@ -112,9 +121,16 @@ class DeployController:
         for bundle_application in sorted(bundle.services,
                                          key=attrgetter('service_name')):
             if bundle_application.placement_spec:
-                app.log.warning("Ignoring placement spec because no machines "
-                                "were set in the bundle: {}".format(
-                                    bundle.application.placement_spec))
+                if app.current_cloud == "localhost":
+                    app.log.info("Ignoring placement spec because we are "
+                                 "deploying to LXD: {}".format(
+                                     bundle_application.placement_spec))
+                else:
+                    app.log.warning("Ignoring placement spec because no "
+                                    "machines were set in the "
+                                    "bundle: {}".format(
+                                        bundle_application.placement_spec))
+
             for n in range(bundle_application.num_units):
                 bundle.add_machine(dict(series=bundle.series),
                                    str(midx))

deploying kubernetes-core onto LXD breaks due to nested LXDs
Since adding the placement-sync code, deploying kubernetes-core attempts to put easyrsa onto a LXD container inside the LXD container 0. There's no reason to do this, LXD deploys can be flat.
diff --git a/test/test_controllers_deploy_gui.py b/test/test_controllers_deploy_gui.py
index 1b72ad3..eac49e8 100644
--- a/test/test_controllers_deploy_gui.py
+++ b/test/test_controllers_deploy_gui.py
@@ -14,7 +14,7 @@ from conjureup.controllers.deploy.gui import DeployController
 class DeployGUIRenderTestCase(unittest.TestCase):
 
     def setUp(self):
-        with patch.object(DeployController, 'sync_with_bundle'):
+        with patch.object(DeployController, 'init_machines_assignments'):
             self.controller = DeployController()
 
         self.utils_patcher = patch(
@@ -74,7 +74,7 @@ class DeployGUIRenderTestCase(unittest.TestCase):
 class DeployGUIFinishTestCase(unittest.TestCase):
 
     def setUp(self):
-        with patch.object(DeployController, 'sync_with_bundle'):
+        with patch.object(DeployController, 'init_machines_assignments'):
             self.controller = DeployController()
 
         self.controllers_patcher = patch(

pip install -e .
parse_log_pytest
requirements.txt
nose tox pytest
apt-get update apt-get install -y gcc
3.5
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
bson==0.5.10
certifi==2021.5.30
charset-normalizer==2.0.12
-e git+https://github.com/conjure-up/conjure-up.git@26386751eb6c0e696609582128cd6b872f27f49c#egg=conjure_up
distlib==0.3.9
filelock==3.4.1
idna==3.10
importlib-metadata==4.8.3
importlib-resources==5.4.0
iniconfig==1.1.1
Jinja2==3.0.3
juju-wait==2.8.4
MarkupSafe==2.0.1
nose==1.3.7
oauthlib==3.2.2
packaging==21.3
petname==2.6
platformdirs==2.4.0
pluggy==1.0.0
prettytable==2.5.0
progressbar2==3.55.0
py==1.11.0
pyparsing==3.1.4
pytest==7.0.1
python-dateutil==2.9.0.post0
python-utils==3.5.2
PyYAML==6.0.1
q==2.7
requests==2.27.1
requests-oauthlib==2.0.0
requests-unixsocket==0.3.0
six==1.17.0
termcolor==1.1.0
toml==0.10.2
tomli==1.2.3
tox==3.28.0
typing_extensions==4.1.1
urllib3==1.26.20
urwid==2.1.2
virtualenv==20.17.1
wcwidth==0.2.13
ws4py==0.3.4
zipp==3.6.0

name: conjure-up
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - bson==0.5.10
      - charset-normalizer==2.0.12
      - distlib==0.3.9
      - filelock==3.4.1
      - idna==3.10
      - importlib-metadata==4.8.3
      - importlib-resources==5.4.0
      - iniconfig==1.1.1
      - jinja2==3.0.3
      - juju-wait==2.8.4
      - markupsafe==2.0.1
      - nose==1.3.7
      - oauthlib==3.2.2
      - packaging==21.3
      - petname==2.6
      - platformdirs==2.4.0
      - pluggy==1.0.0
      - prettytable==2.5.0
      - progressbar2==3.55.0
      - py==1.11.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - python-dateutil==2.9.0.post0
      - python-utils==3.5.2
      - pyyaml==6.0.1
      - q==2.7
      - requests==2.27.1
      - requests-oauthlib==2.0.0
      - requests-unixsocket==0.3.0
      - six==1.17.0
      - termcolor==1.1.0
      - toml==0.10.2
      - tomli==1.2.3
      - tox==3.28.0
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - urwid==2.1.2
      - virtualenv==20.17.1
      - wcwidth==0.2.13
      - ws4py==0.3.4
      - zipp==3.6.0
prefix: /opt/conda/envs/conjure-up

test/test_controllers_deploy_gui.py::DeployGUIRenderTestCase::test_queue_predeploy_once test/test_controllers_deploy_gui.py::DeployGUIFinishTestCase::test_show_bootstrap_wait test/test_controllers_deploy_gui.py::DeployGUIFinishTestCase::test_skip_bootstrap_wait
conjureup/controllers/deploy/gui.py
conjureup/controllers/deploy/gui.py