Skip to content

Commit

Permalink
Add support for testing image in shared gallery
Browse files Browse the repository at this point in the history
  • Loading branch information
dsrivastavv committed Jul 17, 2021
1 parent 4bebeb1 commit 5d10831
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 5 deletions.
18 changes: 16 additions & 2 deletions lisa/sut_orchestrator/azure/arm_template.json
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@
"linuxConfiguration": "[if(empty(parameters('admin_key_data')), json('null'), lisa.getLinuxConfiguration(concat('/home/', parameters('admin_username'), '/.ssh/authorized_keys'), parameters('admin_key_data')))]"
},
"storageProfile": {
"imageReference": "[if(not(empty(parameters('nodes')[copyIndex('vmCopy')]['vhd'])), lisa.getOsDiskVhd(parameters('nodes')[copyIndex('vmCopy')]['name']), lisa.getOsDiskMarketplace(parameters('nodes')[copyIndex('vmCopy')]))]",
"imageReference": "[if(not(empty(parameters('nodes')[copyIndex('vmCopy')]['vhd'])), lisa.getOsDiskVhd(parameters('nodes')[copyIndex('vmCopy')]['name']), if(not(empty(parameters('nodes')[copyIndex('vmCopy')]['shared_gallery'])), lisa.getOsDiskSharedGallery(parameters('nodes')[copyIndex('vmCopy')]['shared_gallery']), lisa.getOsDiskMarketplace(parameters('nodes')[copyIndex('vmCopy')])))]",
"osDisk": {
"name": "[concat(parameters('nodes')[copyIndex('vmCopy')]['name'], '-osDisk')]",
"managedDisk": {
Expand Down Expand Up @@ -327,6 +327,20 @@
"value": "[parameters('node')['marketplace']]"
}
},
"getOsDiskSharedGallery": {
"parameters": [
{
"name": "node",
"type": "object"
}
],
"output": {
"type": "object",
"value": {
"id": "[resourceId(parameters('node')['subscription_id'], 'None', 'Microsoft.Compute/galleries/images/versions', parameters('node')['image_gallery'], parameters('node')['image_definition'], parameters('node')['image_version'])]"
}
}
},
"getOsDiskVhd": {
"parameters": [
{
Expand Down Expand Up @@ -371,4 +385,4 @@
}
}
]
}
}
88 changes: 88 additions & 0 deletions lisa/sut_orchestrator/azure/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,40 @@ class AzureVmMarketplaceSchema:
version: str = "Latest"


@dataclass_json()
@dataclass
class SharedImageGallerySchema:
subscription_id: str = ""
image_gallery: str = ""
image_definition: str = ""
image_version: str = ""


@dataclass_json()
@dataclass
class AzureNodeSchema:
name: str = ""
vm_size: str = ""
location: str = ""
# Required by shared gallery images which are present in
# subscription different from where LISA is run
subscription_id: str = ""
marketplace_raw: Optional[Union[Dict[Any, Any], str]] = field(
default=None, metadata=schema.metadata(data_key="marketplace")
)
shared_gallery_raw: Optional[Union[Dict[Any, Any], str]] = field(
default=None, metadata=schema.metadata(data_key="shared_gallery")
)
vhd: str = ""
nic_count: int = 1

# for marketplace image, which need to accept terms
purchase_plan: Optional[AzureVmPurchasePlanSchema] = None

_marketplace: InitVar[Optional[AzureVmMarketplaceSchema]] = None

_shared_gallery: InitVar[Optional[SharedImageGallerySchema]] = None

@property
def marketplace(self) -> Optional[AzureVmMarketplaceSchema]:
# this is a safe guard and prevent mypy error on typing
Expand Down Expand Up @@ -132,10 +150,80 @@ def marketplace(self, value: Optional[AzureVmMarketplaceSchema]) -> None:
else:
self.marketplace_raw = value.to_dict() # type: ignore

@property
def shared_gallery(self) -> Optional[SharedImageGallerySchema]:
# this is a safe guard and prevent mypy error on typing
if not hasattr(self, "_shared_gallery"):
self._shared_gallery: Optional[SharedImageGallerySchema] = None
shared_gallery: Optional[SharedImageGallerySchema] = self._shared_gallery
if shared_gallery:
return shared_gallery
if isinstance(self.shared_gallery_raw, dict):
# Users decide the cases of image names,
# the inconsistent cases cause the mismatched error in notifiers.
# The lower() normalizes the image names,
# it has no impact on deployment.
self.shared_gallery_raw = dict(
(k, v.lower()) for k, v in self.shared_gallery_raw.items()
)
shared_gallery = SharedImageGallerySchema.schema().load( # type: ignore
self.shared_gallery_raw
)
if not shared_gallery.subscription_id: # type: ignore
shared_gallery.subscription_id = self.subscription_id # type: ignore
# this step makes shared_gallery_raw is validated, and
# filter out any unwanted content.
self.shared_gallery_raw = shared_gallery.to_dict() # type: ignore
elif self.shared_gallery_raw:
assert isinstance(
self.shared_gallery_raw, str
), f"actual: {type(self.shared_gallery_raw)}"
# Users decide the cases of image names,
# the inconsistent cases cause the mismatched error in notifiers.
# The lower() normalizes the image names,
# it has no impact on deployment.
shared_gallery_strings = re.split(
r"[/]+", self.shared_gallery_raw.strip().lower()
)
if len(shared_gallery_strings) == 4:
shared_gallery = SharedImageGallerySchema(*shared_gallery_strings)
# shared_gallery_raw is used
self.shared_gallery_raw = shared_gallery.to_dict() # type: ignore
elif len(shared_gallery_strings) == 3:
shared_gallery = SharedImageGallerySchema(
self.subscription_id, *shared_gallery_strings
)
# shared_gallery_raw is used
self.shared_gallery_raw = shared_gallery.to_dict() # type: ignore
else:
raise LisaException(
f"Invalid value for the provided shared gallery "
f"parameter: '{self.shared_gallery_raw}'."
f"The shared gallery parameter should be in the format: "
f"'<subscription_id>/<image_gallery>/<image_definition>"
f"/<image_version>' or '<image_gallery>/<image_definition>"
f"/<image_version>'"
)
self._shared_gallery = shared_gallery
return shared_gallery

@shared_gallery.setter
def shared_gallery(self, value: Optional[SharedImageGallerySchema]) -> None:
self._shared_gallery = value
if value is None:
self.shared_gallery_raw = None
else:
self.shared_gallery_raw = value.to_dict() # type: ignore

def get_image_name(self) -> str:
result = ""
if self.vhd:
result = self.vhd
elif self.shared_gallery:
assert isinstance(
self.shared_gallery_raw, dict
), f"actual type: {type(self.shared_gallery_raw)}"
result = " ".join([x for x in self.shared_gallery_raw.values()])
elif self.marketplace:
assert isinstance(
self.marketplace_raw, dict
Expand Down
11 changes: 8 additions & 3 deletions lisa/sut_orchestrator/azure/platform_.py
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,7 @@ def _create_deployment_parameters(
azure_node_runbook = node_space.get_extended_runbook(
AzureNodeSchema, type_name=AZURE
)
azure_node_runbook.subscription_id = self.subscription_id

# init node
node = environment.nodes.from_requirement(
Expand All @@ -859,9 +860,13 @@ def _create_deployment_parameters(
if azure_node_runbook.vhd:
# vhd is higher priority
azure_node_runbook.marketplace = None
elif not azure_node_runbook.marketplace:
# set to default marketplace, if nothing specified
azure_node_runbook.marketplace = AzureVmMarketplaceSchema()
azure_node_runbook.shared_gallery = None
else:
if azure_node_runbook.shared_gallery:
azure_node_runbook.marketplace = None
elif not azure_node_runbook.marketplace:
# set to default marketplace, if nothing specified
azure_node_runbook.marketplace = AzureVmMarketplaceSchema()

if azure_node_runbook.marketplace:
# resolve Latest to specified version
Expand Down

0 comments on commit 5d10831

Please sign in to comment.