Skip to content

Commit 6443dd2

Browse files
committed
Add --attach-storage parameter to model.deploy
1 parent b17d015 commit 6443dd2

2 files changed

Lines changed: 52 additions & 3 deletions

File tree

juju/model.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,7 +1670,7 @@ async def deploy(
16701670
self, entity_url, application_name=None, bind=None,
16711671
channel=None, config=None, constraints=None, force=False,
16721672
num_units=1, overlays=[], plan=None, resources=None, series=None,
1673-
storage=None, to=None, devices=None, trust=False):
1673+
storage=None, to=None, devices=None, trust=False, attach_storage=[]):
16741674
"""Deploy a new service or bundle.
16751675
16761676
:param str entity_url: Charm or bundle url
@@ -1700,6 +1700,8 @@ async def deploy(
17001700
with access to trusted credentials. Hooks run by the charm can access
17011701
cloud credentials and other trusted access credentials.
17021702
1703+
:param str[] attach_storage: Existing storage to attach to the deployed unit
1704+
(not available on k8s models)
17031705
TODO::
17041706
17051707
- support local file resources
@@ -1713,6 +1715,9 @@ async def deploy(
17131715
if trust and (self.info.agent_version < client.Number.from_json('2.4.0')):
17141716
raise NotImplementedError("trusted is not supported on model version {}".format(self.info.agent_version))
17151717

1718+
if not all([type(st) == str for st in attach_storage]):
1719+
raise JujuError("Expected attach_storage to be a list of strings, given {}".format(attach_storage))
1720+
17161721
# Ensure what we pass in, is a string.
17171722
entity_url = str(entity_url)
17181723
if is_local_charm(entity_url) and not entity_url.startswith("local:"):
@@ -1820,7 +1825,8 @@ async def deploy(
18201825
num_units=num_units,
18211826
placement=parse_placement(to),
18221827
devices=devices,
1823-
charm_origin=charm_origin
1828+
charm_origin=charm_origin,
1829+
attach_storage=attach_storage,
18241830
)
18251831

18261832
async def _add_charm(self, charm_url, origin):
@@ -2037,7 +2043,7 @@ async def add_local_resources(self, application, entity_url, metadata, resources
20372043
async def _deploy(self, charm_url, application, series, config,
20382044
constraints, endpoint_bindings, resources, storage,
20392045
channel=None, num_units=None, placement=None,
2040-
devices=None, charm_origin=None):
2046+
devices=None, charm_origin=None, attach_storage=[]):
20412047
"""Logic shared between `Model.deploy` and `BundleHandler.deploy`.
20422048
"""
20432049
log.info('Deploying %s', charm_url)
@@ -2064,6 +2070,7 @@ async def _deploy(self, charm_url, application, series, config,
20642070
storage=storage,
20652071
placement=placement,
20662072
devices=devices,
2073+
attach_storage=attach_storage,
20672074
)
20682075
result = await app_facade.Deploy(applications=[app])
20692076
errors = [r.error.message for r in result.results if r.error]

tests/integration/test_model.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,48 @@ async def test_add_storage(event_loop):
10771077
assert any([tag.storage("pgdata") in s for s in ret])
10781078

10791079

1080+
@base.bootstrapped
1081+
@pytest.mark.asyncio
1082+
async def test_model_attach_storage_at_deploy(event_loop):
1083+
pytest.skip('detach/attach_storage inconsistent on Juju side, unable to test')
1084+
async with base.CleanModel() as model:
1085+
# The attach_storage needs to be an existing storage,
1086+
# so the plan is to:
1087+
# - Deploy postgresql
1088+
# - Create and attach a storage
1089+
# - Detach storage
1090+
# - Remove app
1091+
# - Re-deploy with attach_storage parameter
1092+
# - Make sure the storage is there
1093+
app = await model.deploy('postgresql')
1094+
await model.wait_for_idle(status="active")
1095+
1096+
unit = app.units[0]
1097+
ret = await unit.add_storage("pgdata")
1098+
assert any([tag.storage("pgdata") in s for s in ret])
1099+
storage_id = ret[0]
1100+
1101+
await unit.detach_storage(storage_id, force=True)
1102+
await jasyncio.sleep(10)
1103+
1104+
storages1 = await model.list_storage()
1105+
assert any([storage_id in s['storage-tag'] for s in storages1])
1106+
1107+
# juju remove-application
1108+
# actually removes the storage even though the destroy_storage=false
1109+
await app.destroy(destroy_storage=False)
1110+
await jasyncio.sleep(10)
1111+
1112+
storages2 = await model.list_storage()
1113+
assert any([storage_id in s['storage-tag'] for s in storages2])
1114+
1115+
await model.deploy('postgresql', attach_storage=[storage_id])
1116+
await model.wait_for_idle(status="active")
1117+
1118+
storages3 = await model.list_storage()
1119+
assert any([storage_id in s['storage-tag'] for s in storages3])
1120+
1121+
10801122
@base.bootstrapped
10811123
@pytest.mark.asyncio
10821124
async def test_detach_storage(event_loop):

0 commit comments

Comments
 (0)