Repository: juju/python-libjuju

Issue:
Local resources in sidecar charms do not work
Hello,

Deploying a bundle with local resources do not work.

Steps to reproduce:

The bundle:

```

bundle: kubernetes
applications:
  onos2:
    charm: "../charms/onos.charm"
    scale: 1
    options:
      admin-password: admin
    resources:
      onos-image: onosproject/onos:2.6.0
```

```python
"""
This example:

1. Connects to the current model
2. Deploy a bundle and waits until it reports itself active
3. Destroys the units and applications

"""
from juju import loop
from juju.model import Model


async def main():
    model = Model()
    print('Connecting to model')
    # Connect to current model with current user, per Juju CLI
    await model.connect()

    try:
        print('Deploying bundle')
        applications = await model.deploy(
            './examples/k8s-local-bundle/bundle.yaml',
        )

        print('Waiting for active')
        await model.block_until(
            lambda: all(unit.workload_status == 'active'
                        for application in applications for unit in application.units))
        print("Successfully deployed!")
        print('Removing bundle')
        for application in applications:
            await application.remove()
    finally:
        print('Disconnecting from model')
        await model.disconnect()
        print("Success")


if __name__ == '__main__':
    loop.run(main())
```

juju status:

```
Model         Controller  Cloud/Region        Version  SLA          Timestamp
test-libjuju  osm-vca     microk8s/localhost  2.9.9    unsupported  17:42:13+02:00

App    Version  Status   Scale  Charm  Store  Channel  Rev  OS          Address  Message
onos2           waiting    0/1  onos   local             0  kubernetes           installing agent

Unit     Workload  Agent       Address  Ports  Message
onos2/0  waiting   allocating                  installing agent
```

juju debug-log:

```
controller-0: 17:29:40 ERROR juju.worker.caasapplicationprovisioner.runner exited "onos2": getting OCI image resources: unable to fetch OCI image resources for onos2: resource#onos2/onos-image not found
controller-0: 17:29:40 INFO juju.worker.caasapplicationprovisioner.runner restarting "onos2" in 3s
controller-0: 17:29:43 INFO juju.worker.caasapplicationprovisioner.runner start "onos2"
controller-0: 17:29:43 INFO juju.worker.caasapplicationprovisioner.runner stopped "onos2", err: restart immediately
controller-0: 17:29:43 ERROR juju.worker.caasapplicationprovisioner.runner exited "onos2": restart immediately
controller-0: 17:29:43 INFO juju.worker.caasapplicationprovisioner.runner restarting "onos2" in 3s
controller-0: 17:29:46 INFO juju.worker.caasapplicationprovisioner.runner start "onos2"
controller-0: 17:29:46 INFO juju.worker.caasapplicationprovisioner.runner stopped "onos2", err: restart immediately
controller-0: 17:29:46 ERROR juju.worker.caasapplicationprovisioner.runner exited "onos2": restart immediately
controller-0: 17:29:46 INFO juju.worker.caasapplicationprovisioner.runner restarting "onos2" in 3s
controller-0: 17:29:49 INFO juju.worker.caasapplicationprovisioner.runner start "onos2"
controller-0: 17:29:49 INFO juju.worker.caasapplicationprovisioner.runner stopped "onos2", err: restart immediately
controller-0: 17:29:49 ERROR juju.worker.caasapplicationprovisioner.runner exited "onos2": restart immediately
controller-0: 17:29:49 INFO juju.worker.caasapplicationprovisioner.runner restarting "onos2" in 3s
controller-0: 17:29:52 INFO juju.worker.caasapplicationprovisioner.runner start "onos2"
controller-0: 17:29:52 INFO juju.worker.caasapplicationprovisioner.runner stopped "onos2", err: getting OCI image resources: unable to fetch OCI image resources for onos2: resource#onos2/onos-image not found
controller-0: 17:29:52 ERROR juju.worker.caasapplicationprovisioner.runner exited "onos2": getting OCI image resources: unable to fetch OCI image resources for onos2: resource#onos2/onos-image not found
controller-0: 17:29:52 INFO juju.worker.caasapplicationprovisioner.runner restarting "onos2" in 3s
controller-0: 17:29:55 INFO juju.worker.caasapplicationprovisioner.runner start "onos2"
controller-0: 17:29:55 INFO juju.worker.caasapplicationprovisioner.runner stopped "onos2", err: restart immediately
controller-0: 17:29:55 ERROR juju.worker.caasapplicationprovisioner.runner exited "onos2": restart immediately
controller-0: 17:29:55 INFO juju.worker.caasapplicationprovisioner.runner restarting "onos2" in 3s
controller-0: 17:29:58 INFO juju.worker.caasapplicationprovisioner.runner start "onos2"
controller-0: 17:29:59 INFO juju.worker.caasapplicationprovisioner.runner stopped "onos2", err: getting OCI image resources: unable to fetch OCI image resources for onos2: resource#onos2/onos-image not found
controller-0: 17:29:59 ERROR juju.worker.caasapplicationprovisioner.runner exited "onos2": getting OCI image resources: unable to fetch OCI image resources for onos2: resource#onos2/onos-image not found
controller-0: 17:29:59 INFO juju.worker.caasapplicationprovisioner.runner restarting "onos2" in 3s
controller-0: 17:30:02 INFO juju.worker.caasapplicationprovisioner.runner start "onos2"
controller-0: 17:30:02 INFO juju.worker.caasapplicationprovisioner.runner stopped "onos2", err: getting OCI image resources: unable to fetch OCI image resources for onos2: resource#onos2/onos-image not found
controller-0: 17:30:02 ERROR juju.worker.caasapplicationprovisioner.runner exited "onos2": getting OCI image resources: unable to fetch OCI image resources for onos2: resource#onos2/onos-image not found
controller-0: 17:30:02 INFO juju.worker.caasapplicationprovisioner.runner restarting "onos2" in 3s
controller-0: 17:30:05 INFO juju.worker.caasapplicationprovisioner.runner start "onos2"
controller-0: 17:30:05 INFO juju.worker.caasapplicationprovisioner.runner stopped "onos2", err: restart immediately
controller-0: 17:30:05 ERROR juju.worker.caasapplicationprovisioner.runner exited "onos2": restart immediately
controller-0: 17:30:05 INFO juju.worker.caasapplicationprovisioner.runner restarting "onos2" in 3s
controller-0: 17:30:08 INFO juju.worker.caasapplicationprovisioner.runner start "onos2"
controller-0: 17:30:08 INFO juju.worker.caasapplicationprovisioner.runner stopped "onos2", err: restart immediately
controller-0: 17:30:08 ERROR juju.worker.caasapplicationprovisioner.runner exited "onos2": restart immediately
controller-0: 17:30:08 INFO juju.worker.caasapplicationprovisioner.runner restarting "onos2" in 3s
controller-0: 17:30:11 INFO juju.worker.caasapplicationprovisioner.runner start "onos2"
controller-0: 17:30:11 INFO juju.worker.caasapplicationprovisioner.runner stopped "onos2", err: restart immediately
controller-0: 17:30:11 ERROR juju.worker.caasapplicationprovisioner.runner exited "onos2": restart immediately
controller-0: 17:30:11 INFO juju.worker.caasapplicationprovisioner.runner restarting "onos2" in 3s
controller-0: 17:30:14 INFO juju.worker.caasapplicationprovisioner.runner start "onos2"
controller-0: 17:30:14 INFO juju.worker.caasapplicationprovisioner.runner stopped "onos2", err: getting OCI image resources: unable to fetch OCI image resources for onos2: resource#onos2/onos-image not found
controller-0: 17:30:14 ERROR juju.worker.caasapplicationprovisioner.runner exited "onos2": getting OCI image resources: unable to fetch OCI image resources for onos2: resource#onos2/onos-image not found
controller-0: 17:30:14 INFO juju.worker.caasapplicationprovisioner.runner restarting "onos2" in 3s
controller-0: 17:30:17 INFO juju.worker.caasapplicationprovisioner.runner start "onos2"
controller-0: 17:30:17 INFO juju.worker.caasapplicationprovisioner.runner stopped "onos2", err: restart immediately
```

Discussion:

Patch:
diff --git a/examples/deploy_local_bundle_with_resources.py b/examples/deploy_local_bundle_with_resources.py
index 5dafd97..ed1e9b9 100644
--- a/examples/deploy_local_bundle_with_resources.py
+++ b/examples/deploy_local_bundle_with_resources.py
@@ -19,7 +19,7 @@ async def main():
     try:
         print('Deploying bundle')
         applications = await model.deploy(
-            'examples/k8s-local-bundle/bundle.yaml',
+            './examples/k8s-local-bundle/bundle.yaml',
         )
 
         print('Waiting for active')
diff --git a/juju/bundle.py b/juju/bundle.py
index 735592c..1901a8e 100644
--- a/juju/bundle.py
+++ b/juju/bundle.py
@@ -492,8 +492,11 @@ class AddApplicationChange(ChangeInfo):
         if Schema.CHARM_STORE.matches(url.schema):
             resources = await context.model._add_store_resources(
                 self.application, charm, overrides=self.resources)
+        elif Schema.CHARM_HUB.matches(url.schema):
+            resources = await context.model._add_charmhub_resources(
+                self.application, charm, 'store', overrides=self.resources)
         else:
-            resources = {}
+            resources = context.bundle.get("applications", {}).get(self.application, {}).get("resources", {})
 
         channel = None
         if self.channel is not None and self.channel != "":


Test patch:
diff --git a/tests/unit/test_bundle.py b/tests/unit/test_bundle.py
index acaa51c..a276650 100644
--- a/tests/unit/test_bundle.py
+++ b/tests/unit/test_bundle.py
@@ -236,7 +236,7 @@ class TestAddApplicationChangeRun:
 
         model = mock.Mock()
         model._deploy = base.AsyncMock(return_value=None)
-        model._add_store_resources = base.AsyncMock(return_value=["resource1"])
+        model._add_charmhub_resources = base.AsyncMock(return_value=["resource1"])
         model.applications = {}
 
         context = mock.Mock()
@@ -255,7 +255,7 @@ class TestAddApplicationChangeRun:
                                          config="options",
                                          constraints="constraints",
                                          endpoint_bindings="endpoint_bindings",
-                                         resources={},
+                                         resources=["resource1"],
                                          storage="storage",
                                          devices="devices",
                                          num_units="num_units")