Skip to content

Commit 6ad1a82

Browse files
Bhautik-ValaBhautik Vala
andauthored
[minor] Support AI Service upgrade functionality (#120)
Co-authored-by: Bhautik Vala <bhautikvala@ibm.com>
1 parent cee9976 commit 6ad1a82

3 files changed

Lines changed: 119 additions & 0 deletions

File tree

src/mas/devops/mas.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,26 @@ def verifyMasInstance(dynClient: DynamicClient, instanceId: str) -> bool:
179179
return False
180180

181181

182+
def verifyAiServiceInstance(dynClient: DynamicClient, instanceId: str) -> bool:
183+
"""
184+
Validate that the chosen AI Service instance exists
185+
"""
186+
try:
187+
aiserviceAPI = dynClient.resources.get(api_version="aiservice.ibm.com/v1", kind="AIServiceApp")
188+
aiserviceAPI.get(name=instanceId, namespace=f"aiservice-{instanceId}")
189+
return True
190+
except NotFoundError:
191+
print("NOT FOUND")
192+
return False
193+
except ResourceNotFoundError:
194+
# The AIServiceApp CRD has not even been installed in the cluster
195+
print("RESOURCE NOT FOUND")
196+
return False
197+
except UnauthorizedError as e:
198+
logger.error(f"Error: Unable to verify AI Service instance due to failed authorization: {e}")
199+
return False
200+
201+
182202
def verifyAppInstance(dynClient: DynamicClient, instanceId: str, applicationId: str) -> bool:
183203
"""
184204
Validate that the chosen app instance exists
@@ -260,6 +280,17 @@ def getAppsSubscriptionChannel(dynClient: DynamicClient, instanceId: str) -> lis
260280
return []
261281

262282

283+
def getAiserviceChannel(dynClient: DynamicClient, instanceId: str) -> str:
284+
"""
285+
Get the AI Service channel from the subscription
286+
"""
287+
aiserviceSubscription = getSubscription(dynClient, f"aiservice-{instanceId}", "ibm-aiservice")
288+
if aiserviceSubscription is None:
289+
return None
290+
else:
291+
return aiserviceSubscription.spec.channel
292+
293+
263294
def updateIBMEntitlementKey(dynClient: DynamicClient, namespace: str, icrUsername: str, icrPassword: str, artifactoryUsername: str = None, artifactoryPassword: str = None, secretName: str = "ibm-entitlement") -> ResourceInstance:
264295
if secretName is None:
265296
secretName = "ibm-entitlement"

src/mas/devops/tekton.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,3 +462,35 @@ def launchAiServiceInstallPipeline(dynClient: DynamicClient, params: dict) -> st
462462

463463
pipelineURL = f"{getConsoleURL(dynClient)}/k8s/ns/aiservice-{instanceId}-pipelines/tekton.dev~v1beta1~PipelineRun/{instanceId}-install-{timestamp}"
464464
return pipelineURL
465+
466+
467+
def launchAiServiceUpgradePipeline(dynClient: DynamicClient,
468+
aiserviceInstanceId: str,
469+
skipPreCheck: bool = False,
470+
aiserviceChannel: str = "",
471+
params: dict = {}) -> str:
472+
"""
473+
Create a PipelineRun to upgrade the chosen AI Service instance
474+
"""
475+
pipelineRunsAPI = dynClient.resources.get(api_version="tekton.dev/v1beta1", kind="PipelineRun")
476+
namespace = f"aiservice-{aiserviceInstanceId}-pipelines"
477+
timestamp = datetime.now().strftime("%y%m%d-%H%M")
478+
# Create the PipelineRun
479+
templateDir = path.join(path.abspath(path.dirname(__file__)), "templates")
480+
env = Environment(
481+
loader=FileSystemLoader(searchpath=templateDir)
482+
)
483+
template = env.get_template("pipelinerun-aiservice-upgrade.yml.j2")
484+
renderedTemplate = template.render(
485+
timestamp=timestamp,
486+
aiservice_instance_id=aiserviceInstanceId,
487+
skip_pre_check=skipPreCheck,
488+
aiservice_channel=aiserviceChannel,
489+
**params
490+
)
491+
logger.debug(renderedTemplate)
492+
pipelineRun = yaml.safe_load(renderedTemplate)
493+
pipelineRunsAPI.apply(body=pipelineRun, namespace=namespace)
494+
495+
pipelineURL = f"{getConsoleURL(dynClient)}/k8s/ns/aiservice-{aiserviceInstanceId}-pipelines/tekton.dev~v1beta1~PipelineRun/{aiserviceInstanceId}-upgrade-{timestamp}"
496+
return pipelineURL
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
apiVersion: tekton.dev/v1beta1
3+
kind: PipelineRun
4+
metadata:
5+
name: "{{ aiservice_instance_id }}-upgrade-{{ timestamp }}"
6+
labels:
7+
tekton.dev/pipeline: aiservice-upgrade
8+
spec:
9+
pipelineRef:
10+
name: aiservice-upgrade
11+
12+
serviceAccountName: "{{ service_account_name | default('pipeline', True) }}"
13+
timeouts:
14+
pipeline: "0"
15+
16+
params:
17+
# Target AI Service Instance
18+
# -------------------------------------------------------------------------
19+
- name: aiservice_instance_id
20+
value: "{{ aiservice_instance_id }}"
21+
- name: aiservice_channel
22+
value: "{{ aiservice_channel }}"
23+
24+
# IBM Entitlement Key
25+
# -------------------------------------------------------------------------
26+
- name: ibm_entitlement_key
27+
value: "{{ ibm_entitlement_key }}"
28+
29+
{%- if skip_pre_check is defined and skip_pre_check != "" %}
30+
# Skip pre-check
31+
# -------------------------------------------------------------------------
32+
- name: skip_pre_check
33+
value: "{{ skip_pre_check }}"
34+
{%- endif %}
35+
{%- if artifactory_username is defined and artifactory_username != "" %}
36+
37+
# Enable development catalogs
38+
# -------------------------------------------------------------------------
39+
- name: artifactory_username
40+
value: "{{ artifactory_username }}"
41+
- name: artifactory_token
42+
value: "{{ artifactory_token }}"
43+
{%- endif %}
44+
45+
workspaces:
46+
# The generated configuration files
47+
# -------------------------------------------------------------------------
48+
- name: shared-configs
49+
persistentVolumeClaim:
50+
claimName: config-pvc
51+
52+
# PodTemplates configurations
53+
# -------------------------------------------------------------------------
54+
- name: shared-pod-templates
55+
secret:
56+
secretName: pipeline-pod-templates

0 commit comments

Comments
 (0)