Skip to content

Commit

Permalink
Show app version on tool Deploy/Upgrade
Browse files Browse the repository at this point in the history
When a user click on the Deploy or Upgrade button the Control Panel
now shows them the version of the tool they're about to install or
upgrade to.

This version is actually the `appVersion` information coming from
the helm chart, this should contain useful information, for example
for RStudio would be something like

> RStudio: 1.2.1335+conda, R: 3.5.1, Python: 3.7.1, patch: 10

This will give the user enough details to take an informed decision
on whether to install or more importantly upgrade.

NOTE: As part of this change I've moved the logic to get a tool/chart
`appVersion` into the `HelmRepository` class as it's now used in more
than one place and it makes sense for this to be in the class used to
query the helm repository.

Ticket: https://trello.com/c/jHI3iCHq
  • Loading branch information
xoen committed Jun 26, 2020
1 parent a899b1a commit 5327586
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 7 deletions.
19 changes: 19 additions & 0 deletions controlpanel/api/helm.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,25 @@ def get_chart_info(cls, name):
chart_info[chart.version] = chart
return chart_info

@classmethod
def get_chart_app_version(cls, name, version):
"""
Returns the "appVersion" metadata for the given
chart name/version.
It returns None if the chart or the chart version
are not found or if that version of a chart doesn't
have the "appVersion" field (e.g. the chart
preceed the introduction of this field)
"""

chart_info = cls.get_chart_info(name)
version_info = chart_info.get(version, None)
if version_info:
return version_info.app_version

return None

@classmethod
def _outdated(cls):
# helm update never called?
Expand Down
25 changes: 20 additions & 5 deletions controlpanel/api/models/tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,23 @@ def __repr__(self):
def url(self, user):
return f"https://{user.slug}-{self.chart_name}.{settings.TOOLS_DOMAIN}/"

@property
def app_version(self):
"""
Returns the "appVersion" for this tool.
This is metadata in the helm chart which we use to maintain details
of the actual tool version (e.g. "RStudio: 1.2.1335+conda, R: 3.5.1, ...")
as opposed to the chart version.
Returns None if this information is not available for this tool and
chart version (e.g. the chart was released before the `appVersion`
was introduced) or because the chart doesn't exist in the helm
reporitory.
"""

return HelmRepository.get_chart_app_version(self.chart_name, self.version)


class ToolDeploymentManager:
"""
Expand Down Expand Up @@ -109,11 +126,9 @@ def get_installed_app_version(self, id_token):
td = cluster.ToolDeployment(self.user, self.tool)
chart_version = td.get_installed_chart_version(id_token)
if chart_version:
chart_info = HelmRepository.get_chart_info(self.tool.chart_name)

version_info = chart_info.get(chart_version, None)
if version_info:
return version_info.app_version
return HelmRepository.get_chart_app_version(
self.tool.chart_name, chart_version
)

return None

Expand Down
4 changes: 2 additions & 2 deletions controlpanel/frontend/jinja2/tool-list.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ <h1 class="govuk-heading-xl">Your tools</h1>
method="post">
{{ csrf_input }}
<input type="hidden" value="{{ tool.version }}" name="version">
<button class="govuk-button govuk-button--secondary right">Deploy</button>
<button class="govuk-button govuk-button--secondary right js-confirm" data-confirm-message="This will install {{ tool.name }} ({% if tool.app_version %}{{ tool.app_version }}{% else %}version information not available{% endif %}), do you wish to continue?">Deploy</button>
</form>
{% if deployment and deployment.outdated(id_token) %}
<form action="{{ url('upgrade-tool', kwargs={"name": tool.chart_name}) }}"
Expand All @@ -66,7 +66,7 @@ <h1 class="govuk-heading-xl">Your tools</h1>
method="post">
{{ csrf_input }}
<input type="hidden" value="{{ tool.version }}" name="version">
<button class="govuk-button govuk-button--secondary right">Upgrade</button>
<button class="govuk-button govuk-button--secondary right js-confirm" data-confirm-message="This will change your {{ tool.name }} instance {% if tool.app_version %}to {{ tool.app_version }}{% else %}(version information not available){% endif %}, do you wish to continue?">Upgrade</button>
</form>
{% endif %}
</td>
Expand Down
15 changes: 15 additions & 0 deletions tests/api/models/test_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,18 @@ def test_tool_deployment_get_installed_app_version(
assert td.get_installed_app_version(id_token) == expected_app_version
cluster.ToolDeployment.assert_called_with(user, tool)
cluster_td.get_installed_chart_version.assert_called_with(id_token)


@pytest.mark.parametrize(
"chart_version, expected_app_version",
[
("unknown-version", None),
("1.0.0", None),
("2.2.5", "RStudio: 1.2.1335+conda, R: 3.5.1, Python: 3.7.1, patch: 10"),
],
ids=["unknown-version", "chart-with-no-appVersion", "chart-with-appVersion",],
)
def test_tool_app_version(helm_repository_index, chart_version, expected_app_version):
tool = Tool(chart_name="rstudio", version=chart_version)

assert tool.app_version == expected_app_version
28 changes: 28 additions & 0 deletions tests/api/test_helm.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,34 @@ def test_helm_repository_chart_info_when_chart_found(helm_repository_index):
assert rstudio_info["1.0.0"].app_version == None


@pytest.mark.parametrize(
"chart_name, version, expected_app_version",
[
("notfound", "v42", None),
("rstudio", "unknown-version", None),
("rstudio", "1.0.0", None),
(
"rstudio",
"2.2.5",
"RStudio: 1.2.1335+conda, R: 3.5.1, Python: 3.7.1, patch: 10",
),
],
ids=[
"unknown-chart",
"unknown-version",
"chart-with-no-appVersion",
"chart-with-appVersion",
],
)
def test_helm_repository_get_chart_app_version(
helm_repository_index, chart_name, version, expected_app_version
):
# See tests/api/fixtures/helm_mojanalytics_index.py
with patch("controlpanel.api.helm.open", helm_repository_index):
app_version = HelmRepository.get_chart_app_version(chart_name, version)
assert app_version == expected_app_version


def test_helm_upgrade_release():
helm.__class__.execute = MagicMock()

Expand Down

0 comments on commit 5327586

Please sign in to comment.