aboutsummaryrefslogtreecommitdiff
path: root/src/hydrilla/proxy
diff options
context:
space:
mode:
Diffstat (limited to 'src/hydrilla/proxy')
-rw-r--r--src/hydrilla/proxy/state_impl/_operations/pull_missing_files.py9
-rw-r--r--src/hydrilla/proxy/state_impl/base.py37
-rw-r--r--src/hydrilla/proxy/tables.sql4
-rw-r--r--src/hydrilla/proxy/web_ui/packages.py5
-rw-r--r--src/hydrilla/proxy/web_ui/repos.py4
-rw-r--r--src/hydrilla/proxy/web_ui/templates/packages/show_single_version.html.jinja5
-rw-r--r--src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja5
7 files changed, 59 insertions, 10 deletions
diff --git a/src/hydrilla/proxy/state_impl/_operations/pull_missing_files.py b/src/hydrilla/proxy/state_impl/_operations/pull_missing_files.py
index 04a2910..f1e0414 100644
--- a/src/hydrilla/proxy/state_impl/_operations/pull_missing_files.py
+++ b/src/hydrilla/proxy/state_impl/_operations/pull_missing_files.py
@@ -81,17 +81,16 @@ def pull_missing_files(
try:
url = urljoin(repo_url, f'file/sha256/{sha256}')
response = requests.get(url)
- except:
- raise state.RepoCommunicationError()
- if not response.ok:
+ assert response.ok
+
+ file_bytes = response.content
+ except:
raise state.FileMissingError(
repo_id = str(repo_id),
sha256 = sha256
)
- file_bytes = response.content
-
computed_sha256 = hashlib.sha256(file_bytes).digest().hex()
if computed_sha256 != sha256:
raise state.FileIntegrityError(
diff --git a/src/hydrilla/proxy/state_impl/base.py b/src/hydrilla/proxy/state_impl/base.py
index 25fd4c5..a889e71 100644
--- a/src/hydrilla/proxy/state_impl/base.py
+++ b/src/hydrilla/proxy/state_impl/base.py
@@ -78,6 +78,34 @@ class PolicyTree(pattern_tree.PatternTree[policies.PolicyFactory]):
return policy_tree
+def mark_failed_file_installs(
+ cursor: sqlite3.Cursor,
+ file_sha256: str,
+ repo_id: int
+) -> None:
+ cursor.execute(
+ '''
+ WITH failed_items AS (
+ SELECT DISTINCT
+ item_version_id
+ FROM
+ files AS f
+ JOIN file_uses AS fu USING (file_id)
+ JOIN item_versions_extra AS ive USING (item_version_id)
+ WHERE
+ f.sha256 = ? AND f.data IS NULL AND ive.repo_id = ?
+ )
+ UPDATE
+ item_versions
+ SET
+ installed = 'F'
+ WHERE
+ item_version_id IN failed_items;
+ ''',
+ (file_sha256, repo_id)
+ )
+
+
PayloadsData = t.Mapping[st.PayloadRef, st.PayloadData]
# mypy needs to be corrected:
@@ -123,6 +151,15 @@ class HaketiloStateWithFields(st.HaketiloState):
if start_transaction:
self.current_cursor.execute('ROLLBACK TRANSACTION;')
raise
+ except st.FileInstallationError as ex:
+ if start_transaction:
+ assert self.current_cursor is not None
+ mark_failed_file_installs(
+ cursor = self.current_cursor,
+ file_sha256 = ex.sha256,
+ repo_id = int(ex.repo_id)
+ )
+ raise
finally:
self.current_cursor = None
diff --git a/src/hydrilla/proxy/tables.sql b/src/hydrilla/proxy/tables.sql
index 54fe3ee..2483c96 100644
--- a/src/hydrilla/proxy/tables.sql
+++ b/src/hydrilla/proxy/tables.sql
@@ -245,8 +245,8 @@ SELECT
iv.repo_iteration_id,
iv.definition,
iv.active,
- r.name AS repo,
- ri.iteration AS repo_iteration,
+ r.repo_id, r.name AS repo,
+ ri.repo_iteration_id, ri.iteration AS repo_iteration,
COALESCE(r.active_iteration_id, -1) != ri.repo_iteration_id AND r.repo_id != 1
AS is_orphan,
r.repo_id = 1 AS is_local
diff --git a/src/hydrilla/proxy/web_ui/packages.py b/src/hydrilla/proxy/web_ui/packages.py
index 5172a07..1edddc0 100644
--- a/src/hydrilla/proxy/web_ui/packages.py
+++ b/src/hydrilla/proxy/web_ui/packages.py
@@ -179,6 +179,11 @@ def alter_package_version(mapping_version_id: str) -> werkzeug.Response:
return flask.redirect(flask.url_for('.packages'))
else:
raise ValueError()
+ except st.FileInstallationError:
+ return show_package_version(
+ mapping_version_id,
+ {'file_installation_error': True}
+ )
except st.ImpossibleSituation:
return show_package_version(
mapping_version_id,
diff --git a/src/hydrilla/proxy/web_ui/repos.py b/src/hydrilla/proxy/web_ui/repos.py
index 5aa5a21..c31a0a4 100644
--- a/src/hydrilla/proxy/web_ui/repos.py
+++ b/src/hydrilla/proxy/web_ui/repos.py
@@ -130,9 +130,7 @@ def alter_repo(repo_id: str) -> werkzeug.Response:
except st.RepoCommunicationError:
return show_repo(repo_id, {'repo_communication_error': True})
except st.FileInstallationError:
- # We'll add the ability to present more meaningful errors later. For now
- # let's treat file errors the same as repo communication errors.
- return show_repo(repo_id, {'repo_communication_error': True})
+ return show_repo(repo_id, {'file_installation_error': True})
except st.RepoApiVersionUnsupported:
return show_repo(repo_id, {'repo_api_version_unsupported': True})
except st.MissingItemError:
diff --git a/src/hydrilla/proxy/web_ui/templates/packages/show_single_version.html.jinja b/src/hydrilla/proxy/web_ui/templates/packages/show_single_version.html.jinja
index aa01272..4d4f1d5 100644
--- a/src/hydrilla/proxy/web_ui/templates/packages/show_single_version.html.jinja
+++ b/src/hydrilla/proxy/web_ui/templates/packages/show_single_version.html.jinja
@@ -22,6 +22,11 @@ in a proprietary work, I am not going to enforce this in court.
{% extends "packages/show_single.html.jinja" %}
{% block title %} {{ _('web_ui.packages.single_version.title') }} {% endblock %}
{% block main_info %}
+ {% if file_installation_error is defined %}
+ <aside class="error-note">
+ {{ _('web_ui.err.file_installation_error') }}
+ </aside>
+ {% endif %}
{% if uninstall_disallowed is defined %}
<aside class="error-note">
{{ _('web_ui.err.uninstall_disallowed') }}
diff --git a/src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja b/src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja
index b032765..baecfea 100644
--- a/src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja
+++ b/src/hydrilla/proxy/web_ui/templates/repos/show_single.html.jinja
@@ -27,6 +27,11 @@ in a proprietary work, I am not going to enforce this in court.
{% include 'include/checkbox_tricks_style.css.jinja' %}
{% endblock %}
{% block main %}
+ {% if file_installation_error is defined %}
+ <aside class="error-note">
+ {{ _('web_ui.err.file_installation_error') }}
+ </aside>
+ {% endif %}
{% if repo_communication_error is defined %}
<aside class="error-note">
{{ _('web_ui.err.repo_communication_error') }}