@@ -1595,10 +1595,13 @@ async def deploy(
15951595 # XXX: we're dropping local resources here, but we don't
15961596 # actually support them yet anyway
15971597 if not res .is_local :
1598- await self ._add_charm (identifier , res .origin )
1598+ add_charm_res = await self ._add_charm (identifier , res .origin )
1599+
1600+ if Schema .CHARM_HUB .matches (url .schema ):
1601+ resources = await self ._add_charmhub_resources (res .app_name ,
1602+ identifier ,
1603+ add_charm_res .charm_origin )
15991604
1600- # TODO (stickupkid): Handle charmhub charms, for now we'll only
1601- # handle charmstore charms.
16021605 if Schema .CHARM_STORE .matches (url .schema ):
16031606 resources = await self ._add_store_resources (res .app_name ,
16041607 identifier )
@@ -1632,6 +1635,7 @@ async def deploy(
16321635 num_units = num_units ,
16331636 placement = parse_placement (to ),
16341637 devices = devices ,
1638+ charm_origin = add_charm_res .charm_origin ,
16351639 )
16361640
16371641 async def _add_charm (self , charm_url , origin ):
@@ -1684,6 +1688,50 @@ async def _resolve_architecture(self, url):
16841688
16851689 return DEFAULT_ARCHITECTURE
16861690
1691+ async def _add_charmhub_resources (self , application ,
1692+ entity_url ,
1693+ origin ,
1694+ overrides = None ):
1695+ charm_facade = client .CharmsFacade .from_connection (self .connection ())
1696+ res = await charm_facade .CharmInfo (entity_url )
1697+
1698+ resources = []
1699+ for resource in res .meta .resources .values ():
1700+ resources .append ({
1701+ 'description' : resource .description ,
1702+ 'name' : resource .name ,
1703+ 'path' : resource .path ,
1704+ 'type_' : resource .type_ ,
1705+ 'origin' : 'store' ,
1706+ 'revision' : - 1 ,
1707+ })
1708+
1709+ if overrides :
1710+ names = {r ['name' ] for r in resources }
1711+ unknown = overrides .keys () - names
1712+ if unknown :
1713+ raise JujuError ('Unrecognized resource{}: {}' .format (
1714+ 's' if len (unknown ) > 1 else '' ,
1715+ ', ' .join (unknown )))
1716+ for resource in resources :
1717+ if resource ['name' ] in overrides :
1718+ resource ['revision' ] = overrides [resource ['name' ]]
1719+
1720+
1721+ resources_facade = client .ResourcesFacade .from_connection (
1722+ self .connection ())
1723+ response = await resources_facade .AddPendingResources (
1724+ application_tag = tag .application (application ),
1725+ charm_url = entity_url ,
1726+ charm_origin = origin ,
1727+ resources = [client .CharmResource (** resource ) for resource in resources ],
1728+ )
1729+
1730+ resource_map = {resource ['name' ]: pid
1731+ for resource , pid
1732+ in zip (resources , response .pending_ids )}
1733+ return resource_map
1734+
16871735 async def _add_store_resources (self , application , entity_url ,
16881736 overrides = None ):
16891737 entity = await self .charmstore .entity (entity_url ,
@@ -1729,7 +1777,7 @@ async def _add_store_resources(self, application, entity_url,
17291777 async def _deploy (self , charm_url , application , series , config ,
17301778 constraints , endpoint_bindings , resources , storage ,
17311779 channel = None , num_units = None , placement = None ,
1732- devices = None ):
1780+ devices = None , charm_origin = None ):
17331781 """Logic shared between `Model.deploy` and `BundleHandler.deploy`.
17341782 """
17351783 log .info ('Deploying %s' , charm_url )
@@ -1747,6 +1795,7 @@ async def _deploy(self, charm_url, application, series, config,
17471795 application = application ,
17481796 series = series ,
17491797 channel = channel ,
1798+ charm_origin = charm_origin ,
17501799 config_yaml = config ,
17511800 constraints = parse_constraints (constraints ),
17521801 endpoint_bindings = endpoint_bindings ,
0 commit comments