Skip to content

Commit

Permalink
Solved the issues after merge
Browse files Browse the repository at this point in the history
  • Loading branch information
ymao2 committed Dec 2, 2022
1 parent 806297d commit c925e99
Show file tree
Hide file tree
Showing 17 changed files with 70 additions and 201 deletions.
15 changes: 0 additions & 15 deletions controlpanel/api/cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -744,21 +744,6 @@ def get_deployment(self, id_token):

return deployments[0]

def get_installed_chart_version(self, id_token):
"""
Returns the installed helm chart version of the tool
This is extracted from the `chart` label in the corresponding
`Deployment`.
"""

try:
deployment = self.get_deployment(id_token)
_, chart_version = deployment.metadata.labels["chart"].rsplit("-", 1)
return chart_version
except ObjectDoesNotExist:
return None

def get_status(self, id_token, deployment=None):
try:
if deployment is None:
Expand Down
68 changes: 16 additions & 52 deletions controlpanel/api/helm.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,20 @@ def get_default_image_tag_from_helm_chart(chart_url, chart_name):


def get_helm_entries():
# Update and grab repository metadata.
repository = update_helm_repository()
# Update repository metadata.
update_helm_repository()
# Grab repository metadata.
repo_path = get_repo_path()
try:
with open(repo_path) as f:
repository = yaml.load(f, Loader=yaml.FullLoader)
except Exception as ex:
error = HelmError(ex)
error.detail = (
f"Error while opening/parsing helm repository cache: '{repo_path}'"
)
raise HelmError(error)

if not repository:
# Metadata not available, so bail with empty dictionary.
return {}
Expand Down Expand Up @@ -216,54 +228,6 @@ def delete(namespace, *args, dry_run=False):
log.info(stdout)


def get_chart_info(chart_name):
"""
Get information about the given chart.
Returns a dictionary with the chart versions as keys and instances of the
HelmChart class as associated values.
Returns an empty dictionary when the chart is not in the helm repository
index.
"""
chart_info = {} # The end result.
# Update
update_helm_repository()
# Grab repository metadata.
repo_path = get_repo_path()
try:
with open(repo_path) as f:
repository = yaml.load(f, Loader=yaml.FullLoader)
except Exception as ex:
error = HelmError(ex)
error.detail = (
f"Error while opening/parsing helm repository cache: '{repo_path}'"
)
raise HelmError(error)

if not repository:
# Metadata not available, so bail with empty dictionary.
return chart_info
entries = repository.get("entries")
if entries:
versions = entries.get(chart_name)
if versions:
# There are versions for the referenced chart. Add them to the
# result as HelmChart instances.
for version in versions:
chart = HelmChart(
version["name"],
version["description"],
version["version"],
# appVersion is relatively new so some old charts don't
# have it.
version.get("appVersion"),
version["urls"][0],
)
chart_info[chart.version] = chart
return chart_info


def get_chart_app_version(chart_name, chart_version):
"""
Returns the "appVersion" metadata for the helm chart with the referenced
Expand All @@ -273,8 +237,8 @@ def get_chart_app_version(chart_name, chart_version):
"appVersion" metadata.
"""

chart = get_chart_info(chart_name)
chart_at_version = chart.get(chart_version)
entries = get_helm_entries()
chart_at_version = get_chart_version_info(entries, chart_name, chart_version)
if chart_at_version:
return chart_at_version.app_version
else:
Expand Down
40 changes: 0 additions & 40 deletions controlpanel/api/models/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@ def image_tag(self):
return values.get("{}.tag".format(chart_image_key_name)) or \
values.get("{}.image.tag".format(chart_image_key_name))

def tool_release_tag(self, image_tag=None):
return "{}-{}-{}".format(self.chart_name, self.version, image_tag or self.image_tag)


class ToolDeploymentManager:
"""
Expand Down Expand Up @@ -137,43 +134,6 @@ def __init__(self, tool, user, old_chart_name=None):
def __repr__(self):
return f"<ToolDeployment: {self.tool!r} {self.user!r}>"

def get_installed_chart_version(self, id_token):
"""
Returns the installed chart version for this tool
Returns None if the chart is not installed for the user
"""
td = cluster.ToolDeployment(self.user, self.tool)
return td.get_installed_chart_version(id_token)

def get_installed_app_version(self, id_token, chart_version=None):
"""
Returns the version of the deployed tool
NOTE: This is the version coming from the helm
chart `appVersion` field, **not** the version
of the chart released in the user namespace.
e.g. if user has `rstudio-2.2.5` (chart version)
installed in his namespace, this would return
"RStudio: 1.2.1335+conda, R: 3.5.1, Python: 3.7.1, patch: 10"
**not** "2.2.5".
Also bear in mind that Helm added this `appVersion`
field only "recently" so if a user has an old
version of a tool chart installed this would return
`None` as we can't determine the tool version
as this information is simply not available
in the helm repository index.
"""
if not chart_version:
chart_version = self.get_installed_chart_version(id_token)
if chart_version:
return helm.get_chart_app_version(
self.tool.chart_name, chart_version
)
return None

def delete(self, id_token):
"""
Remove the release from the cluster
Expand Down
5 changes: 3 additions & 2 deletions controlpanel/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,10 @@ class ToolDeploymentSerializer(serializers.Serializer):

def validate_version(self, value):
try:
_, _ = value.split("__")
_, _, _ = value.split("__")
except ValueError:
raise serializers.ValidationError('This field include chart name and version and they are joined by "__".')
raise serializers.ValidationError('This field include chart name, version and tool.id,'
' they are joined by "__".')


class ESBucketHitsSerializer(serializers.BaseSerializer):
Expand Down
3 changes: 2 additions & 1 deletion controlpanel/api/views/tool_deployments.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@ def _deploy(self, chart_name, data):
# attribute and then split on "__" to extract them. Why? Because we
# need both pieces of information to kick off the background helm
# deploy.
tool_name, tool_version = chart_info.split("__")
tool_name, tool_version, tool_id = chart_info.split("__")

# Kick off the helm chart as a background task.
start_background_task(
"tool.deploy",
{
"tool_name": chart_name,
"version": tool_version,
"tool_id": tool_id,
"user_id": self.request.user.id,
"id_token": self.request.user.get_id_token(),
"old_chart_name": old_chart_name,
Expand Down
1 change: 1 addition & 0 deletions controlpanel/frontend/consumers.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ def update_tool_status(tool_deployment, id_token, status):
payload = {
"toolName": tool.chart_name,
"version": tool.version,
"tool_id": tool.id,
"status": status,
}
send_sse(user.auth0_id, {"event": "toolStatus", "data": json.dumps(payload),})
Expand Down
2 changes: 1 addition & 1 deletion controlpanel/frontend/jinja2/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@
<script src="{{ static('jquery/jquery.min.js') }}"></script>
<script src="{{ static('jquery-ui/jquery-ui.min.js') }}"></script>

<script src="{{ static('app.js') }}"></script>
<script src="{{ static('app.js') }}"?version=v0.29.27></script>
<script>window.moj.init();</script>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id={{ google_analytics_id }}"></script>
Expand Down
3 changes: 1 addition & 2 deletions controlpanel/frontend/jinja2/release-create.html
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ <h1 class="govuk-heading-xl">{{ page_title }}</h1>
},
"name": "description",
"attributes": {
"pattern": "[a-z0-9.-]{1,60}",
"maxlength": "60",
"maxlength": "100",
},
"value": form.description.value(),
"errorMessage": { "html": form.description.errors|join(". ") } if form.description.errors else {}
Expand Down
3 changes: 1 addition & 2 deletions controlpanel/frontend/jinja2/release-detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,7 @@ <h1 class="govuk-heading-xl">{{ page_title }}</h1>
},
"name": "description",
"attributes": {
"pattern": "[a-z0-9.-]{1,60}",
"maxlength": "60",
"maxlength": "100",
},
"value": form.description.value(),
"errorMessage": { "html": form.description.errors|join(". ") } if form.description.errors else {}
Expand Down
18 changes: 14 additions & 4 deletions controlpanel/frontend/jinja2/tool-list.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ <h2 class="govuk-heading-m">{{ tool_info.name }}</h2>
id="tools-{{ chart_name }}" name="version">
{% set installed_chart_version = None %}
{% set installed_release_version = None %}
{% if deployment %}
{% set installed_chart_version = deployment.app_version %}
{% set installed_release_version = deployment.tool_release_tag %}
{% if deployment and deployment.tool_id > -1 %}
{% set installed_chart_version = deployment.description %}
{% set installed_release_version = deployment.tool_id %}
<option class="installed" value="{{ deployment.chart_name }}__{{ installed_chart_version }}__{{ deployment.tool_id }}">
[{{ deployment.chart_name }} {{ deployment.image_tag }}] {{ installed_chart_version or "Unknown" }} (installed)
</option>
Expand Down Expand Up @@ -100,12 +100,22 @@ <h2 class="govuk-heading-m">{{ tool_info.name }}</h2>
{{ csrf_input }}
<button class="govuk-button govuk-button--secondary govuk-!-margin-right-1 govuk-!-margin-top-0 tool-action"
data-action-name="restart"
{% if not deployment %} disabled {% endif %}>
{% if not deployment or deployment.tool_id == -1 %} disabled {% endif %}>
Restart
</button>
</form>
</div>
</div>

{% if deployment and deployment.tool_id == -1 %}
<div>
<p class="govuk-body">
Looks like your current deployment <b> ({{ deployment.chart_name}}-{{ deployment.chart_version }}: {{ deployment.image_tag }}) </b>
was not recognised within current maintained tool release versions, No worry you can still open it and have a look,
then feel free to switch one of versions from above dropdown list.
</p>
</div>
{% endif %}
<hr class="govuk-section-break govuk-section-break--visible govuk-!-margin-bottom-4">
{% endfor %}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ moj.Modules.toolStatus = {
const toolstatus = this;
return event => {
const data = JSON.parse(event.data);
if (data.toolName != listener.dataset.toolName) {
if (data.toolName.startsWith(listener.dataset.toolName) === false ) {
return;
}
listener.querySelector(toolstatus.statusLabelClass).innerText = data.status;
Expand Down Expand Up @@ -89,14 +89,14 @@ moj.Modules.toolStatus = {
}

// 3. add "(installed)" suffix and class to new version
let newValue = newVersionData.toolName + "__" + newVersionData.version;
let newValue = newVersionData.toolName + "__" + newVersionData.version + "__" + newVersionData.tool_id;
let newVersionOption = listener.querySelector(this.versionSelector + " option[value='" + newValue + "']");
if (newVersionOption) {
newVersionOption.innerText = newVersionOption.innerText + this.installedSuffix;
newVersionOption.classList.add(this.versionInstalledClass)

// set the new version as the current chosen item
const dropDownToolId = "tools-" + newVersionData.toolName;
const dropDownToolId = "tools-" + listener.dataset.toolName;
document.getElementById(dropDownToolId).selectedIndex = newVersionOption.index;
}
}
Expand Down
38 changes: 19 additions & 19 deletions controlpanel/frontend/views/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,9 @@ def _add_new_item_to_tool_box(self, user, tool_box, tool, tools_info, charts_inf
}
image_tag = tool.image_tag
if not image_tag:
image_tag = charts_info.get(tool.version, {}).get('image_tag') or 'unknown'
tool_release_tag = tool.tool_release_tag(image_tag=image_tag)
if tool_release_tag not in tools_info[tool_box]["releases"]:
tools_info[tool_box]["releases"][tool_release_tag] = {
image_tag = charts_info.get(tool.version, {}) or 'unknown'
if tool.id not in tools_info[tool_box]["releases"]:
tools_info[tool_box]["releases"][tool.id] = {
"tool_id": tool.id,
"chart_name": tool.chart_name,
"description": tool.description,
Expand All @@ -104,15 +103,14 @@ def _add_deployed_charts_info(self, tools_info, user, id_token, charts_info):
tool = self._find_related_tool_record(chart_name, chart_version, image_tag)
if not tool:
log.warn("this chart({}-{}) has not available from DB. ".format(chart_name, chart_version))
continue
self._add_new_item_to_tool_box(user, tool_box, tool, tools_info, charts_info)
else:
self._add_new_item_to_tool_box(user, tool_box, tool, tools_info, charts_info)
tools_info[tool_box]["deployment"] = {
"tool_id": tool.id,
"tool_id": tool.id if tool else -1,
"chart_name": chart_name,
"chart_version": chart_version,
"image_tag": image_tag,
"description": tool.description if tool else 'Not available',
"tool_release_tag": tool.tool_release_tag(image_tag=image_tag),
"status": ToolDeployment(tool, user).get_status(id_token, deployment=deployment)
}

Expand All @@ -127,22 +125,25 @@ def _retrieve_detail_tool_info(self, user, tools, charts_info):
return tools_info

def _get_charts_info(self, tool_list):
# Each version now needs to display the chart_name and the
# "app_version" metadata from helm. TODO: Stop using helm.
# We may need the default image_tag from helm chart
# unless we configure it specifically in parameters of tool release
charts_info = {}
chart_entries = get_helm_entries()
chart_entries = None
for tool in tool_list:
if tool.version in charts_info:
continue

chart_app_version = get_chart_version_info(chart_entries, tool.chart_name, tool.version)
image_tag = tool.image_tag
if chart_app_version and not image_tag:
if image_tag:
continue

if chart_entries is None:
# load the potential massive helm chart yaml only it is necessary
chart_entries = get_helm_entries()
chart_app_version = get_chart_version_info(chart_entries, tool.chart_name, tool.version)
if chart_app_version:
image_tag = get_default_image_tag_from_helm_chart(chart_app_version.chart_url, tool.chart_name)
charts_info[tool.version] ={
"app_version": chart_app_version.app_version if chart_app_version else 'Unknown',
"image_tag": image_tag
}
charts_info[tool.version] = image_tag
return charts_info

def get_context_data(self, *args, **kwargs):
Expand All @@ -169,10 +170,9 @@ def get_context_data(self, *args, **kwargs):
"chart_version": <chart_version>,
"tool_id": <id of the tool in table>,
"status": <current status of the deployed tool,
"tool_release_tag": < from tool.tool_release_tag property>
},
"releases": {
"rstudio-2.2.5-<rstudio image tag>": {
"<tool_id>": {
"chart_name": "rstudio",
"description": "RStudio: 1.2.1335+conda, R: 3.5.1, Python: 3.7.1, patch: 10",
"image_tag": "4.0.5",
Expand Down
Loading

0 comments on commit c925e99

Please sign in to comment.