-
Notifications
You must be signed in to change notification settings - Fork 41
add vex tarball downloader for IoP #638
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
42e6d49
eac8b8e
a79056f
77f2a14
e1bd040
0c57510
3f87058
82c426c
03c7816
4447cb6
d1c1e8a
d105c10
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| --- | ||
| iop_vex_downloader_base_url: "https://security.access.redhat.com/data/csaf/v2/vex/" | ||
| iop_vex_downloader_output_dir: "/var/www/html/pub/iop/data/csaf/v2/vex/" | ||
| iop_vex_downloader_timer_interval: "1d" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| [Unit] | ||
| Description=Path unit for vex-latest.tar.zst manual file watcher | ||
|
|
||
| [Path] | ||
| PathChanged=/var/lib/foreman/vex-latest.tar.zst | ||
| PathModified=/var/lib/foreman/vex-latest.tar.zst | ||
|
|
||
| [Install] | ||
| WantedBy=multi-user.target |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| --- | ||
| - name: Restart vex download timer | ||
| ansible.builtin.systemd: | ||
| name: iop-vex-download.timer | ||
| state: restarted | ||
|
|
||
| - name: Restart vex download path | ||
| ansible.builtin.systemd: | ||
| name: iop-vex-download.path | ||
| state: restarted |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| --- | ||
| - name: Install vex download script | ||
| ansible.builtin.template: | ||
| src: iop-vex-downloader.sh.j2 | ||
| dest: /usr/local/bin/iop-vex-downloader.sh | ||
| owner: root | ||
| group: root | ||
| mode: '0755' | ||
|
|
||
| - name: Create vex download service unit | ||
| ansible.builtin.copy: | ||
| dest: /etc/systemd/system/iop-vex-download.service | ||
| content: | | ||
| [Unit] | ||
| Description=Manages vex-latest.tar.zst for IoP Vulnerability | ||
| After=network-online.target iop-core-gateway.service | ||
| Wants=network-online.target iop-core-gateway.service | ||
|
|
||
| [Service] | ||
| Type=oneshot | ||
| ExecStart=/usr/local/bin/iop-vex-downloader.sh \ | ||
| '{{ iop_vex_downloader_base_url }}' \ | ||
| '{{ iop_vex_downloader_output_dir }}' | ||
| User=root | ||
| Group=root | ||
| mode: '0644' | ||
|
|
||
| - name: Create vex download timer unit | ||
| ansible.builtin.template: | ||
| src: iop-vex-download.timer.j2 | ||
| dest: /etc/systemd/system/iop-vex-download.timer | ||
| mode: '0644' | ||
| notify: Restart vex download timer | ||
|
|
||
| - name: Create vex download path unit | ||
| ansible.builtin.copy: | ||
| src: iop-vex-download.path | ||
| dest: /etc/systemd/system/iop-vex-download.path | ||
| mode: '0644' | ||
| notify: Restart vex download path | ||
|
|
||
| - name: Reload systemd daemon | ||
| ansible.builtin.systemd: | ||
| daemon_reload: true | ||
|
|
||
| - name: Flush handlers | ||
| ansible.builtin.meta: flush_handlers | ||
|
|
||
| - name: Create directory vex download directory | ||
| ansible.builtin.file: | ||
| path: '{{ iop_vex_downloader_output_dir }}' | ||
| state: directory | ||
| mode: "0755" | ||
|
|
||
| - name: Enable and start vex download timer | ||
| ansible.builtin.systemd: | ||
| name: iop-vex-download.timer | ||
| enabled: true | ||
| state: started | ||
|
|
||
| - name: Enable and start vex download path watcher | ||
| ansible.builtin.systemd: | ||
| name: iop-vex-download.path | ||
| enabled: true | ||
| state: started |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| [Unit] | ||
| Description=Timer for vex-latest.tar.zst download | ||
|
|
||
| [Timer] | ||
| OnActiveSec=0 | ||
| OnUnitActiveSec={{ iop_vex_downloader_timer_interval }} | ||
|
|
||
| [Install] | ||
| WantedBy=timers.target |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| #!/bin/bash | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| FILENAME_LATEST="archive_latest.txt" | ||
| OUTPUT_FILENAME="vex-latest.tar.zst" | ||
|
|
||
| URL="${1:-}" | ||
| OUTPUT_DIR="${2:-}" | ||
|
|
||
|
|
||
| if [[ -z "${URL}" || -z "${OUTPUT_DIR}" ]]; then | ||
| echo "Usage: ${0} URL OUTPUT_DIR" >&2 | ||
| echo "Example: ${0} https://security.access.redhat.com/data/csaf/v2/vex/ /root/download/" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| URL="${URL%/}/" | ||
| OUTPUT_DIR="${OUTPUT_DIR%/}/" | ||
|
|
||
| MANUAL_FILE="/var/lib/foreman/vex-latest.tar.zst" | ||
|
|
||
| if [[ -f "$MANUAL_FILE" ]]; then | ||
| echo "Offline mode: Using manual file from $MANUAL_FILE" | ||
|
|
||
| CURRENT_CHECKSUM=$(sha256sum "${MANUAL_FILE}" | cut -d' ' -f1) | ||
| STORED_CHECKSUM=$(sha256sum "${OUTPUT_DIR}${OUTPUT_FILENAME}" | cut -d' ' -f1) | ||
|
|
||
| if [[ "$CURRENT_CHECKSUM" != "$STORED_CHECKSUM" ]]; then | ||
| echo "Copying updated manual file" | ||
| cp -Z "$MANUAL_FILE" "${OUTPUT_DIR}${OUTPUT_FILENAME}" && echo "$CURRENT_CHECKSUM" > "$CHECKSUM_FILE" | ||
| chmod 644 "${OUTPUT_DIR}${OUTPUT_FILENAME}" | ||
| else | ||
| echo "Manual file unchanged, skipping" | ||
| fi | ||
| else | ||
| echo "Online mode: Checking for updates from $URL" | ||
|
|
||
| FILE_MODTIME="Thu, 01 Jan 1970 00:00:00 +0000" | ||
|
|
||
| if [[ -f "${OUTPUT_DIR}${OUTPUT_FILENAME}" ]]; then | ||
| FILE_MODTIME=$(date -u -R -r "${OUTPUT_DIR}${OUTPUT_FILENAME}") | ||
| fi | ||
|
|
||
| # | ||
| # \ | ||
| ARCHIVE_DOWNLOAD_NAME_CONTENT=$(curl \ | ||
| --silent \ | ||
| --fail \ | ||
| --location \ | ||
| -H "If-Modified-Since: ${FILE_MODTIME}"\ | ||
| "${URL}${FILENAME_LATEST}") | ||
|
|
||
| RET=${?} | ||
|
|
||
| if [ "${RET}" -ne 0 ]; then | ||
| echo "Error: The tarball's name wasn't downloaded" >&2 | ||
| exit 1 | ||
| fi | ||
|
|
||
| if [ -z "${ARCHIVE_DOWNLOAD_NAME_CONTENT}" ]; then | ||
| echo "The file wasn't updated." | ||
| exit 0 | ||
| fi | ||
|
|
||
| TEMP_FILE_ARCH=$(mktemp -t "iop-vex-download.XXXXXX") | ||
| TEMP_FILE_ASC=$(mktemp -t "iop-vex-download.asc.XXXXXX") | ||
|
|
||
| trap 'rm -f "${TEMP_FILE_ARCH}" "${TEMP_FILE_ASC}"' EXIT | ||
|
|
||
| curl --silent \ | ||
| --fail \ | ||
| --location \ | ||
| "${URL}${ARCHIVE_DOWNLOAD_NAME_CONTENT}" \ | ||
| --output "${TEMP_FILE_ARCH}" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you figure out a way to skip the download if the content hasn't changed? The file is too large to be downloaded each time this runs. There are two options:
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How large is this file?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I edited the script so now it is downloading only when content is changed. It uses |
||
|
|
||
| RET=${?} | ||
|
|
||
| if [ "${RET}" -ne 0 ]; then | ||
| echo "Error: Downloading of tarball failed. Curl failed with code ${RET}" >&2 | ||
| exit 2 | ||
| fi | ||
|
|
||
| curl --silent \ | ||
| --fail \ | ||
| --location \ | ||
| "${URL}${ARCHIVE_DOWNLOAD_NAME_CONTENT}.asc" \ | ||
| --output "${TEMP_FILE_ASC}" | ||
|
|
||
| RET=${?} | ||
|
|
||
| if [ "${RET}" -ne 0 ]; then | ||
| echo "Error: Downloading of tarball's signature failed. Curl failed with code ${RET}" >&2 | ||
| exit 3 | ||
| fi | ||
|
|
||
| mv -Z "${TEMP_FILE_ARCH}" "${OUTPUT_DIR}${OUTPUT_FILENAME}" | ||
| mv -Z "${TEMP_FILE_ASC}" "${OUTPUT_DIR}${OUTPUT_FILENAME}.asc" | ||
|
|
||
| chmod 644 "${OUTPUT_DIR}${OUTPUT_FILENAME}" | ||
| chmod 644 "${OUTPUT_DIR}${OUTPUT_FILENAME}.asc" | ||
| fi | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| import pytest | ||
|
|
||
| pytestmark = pytest.mark.feature("iop") | ||
|
|
||
|
|
||
| def test_vex_download_script(server): | ||
| script = server.file("/usr/local/bin/iop-vex-downloader.sh") | ||
| assert script.exists | ||
| assert script.is_file | ||
| assert script.mode == 0o755 | ||
|
|
||
|
|
||
| def test_vex_download_service_unit(server): | ||
| unit = server.file("/etc/systemd/system/iop-vex-download.service") | ||
| assert unit.exists | ||
| assert unit.is_file | ||
|
|
||
| content = unit.content_string | ||
| assert "Type=oneshot" in content | ||
| assert "iop-vex-downloader.sh" in content | ||
| assert "iop-core-gateway.service" in content | ||
|
|
||
|
|
||
| def test_vex_download_timer_unit(server): | ||
| unit = server.file("/etc/systemd/system/iop-vex-download.timer") | ||
| assert unit.exists | ||
| assert unit.is_file | ||
|
|
||
| content = unit.content_string | ||
| assert "OnActiveSec=0" in content | ||
| assert "OnUnitActiveSec=7d" in content | ||
| assert "WantedBy=timers.target" in content | ||
|
|
||
|
|
||
| def test_vex_download_timer_enabled(server): | ||
| timer = server.service("iop-vex-download.timer") | ||
| assert timer.is_enabled | ||
| assert timer.is_running | ||
|
|
||
|
|
||
| def test_vex_download_path_unit(server): | ||
| unit = server.file("/etc/systemd/system/iop-vex-download.path") | ||
| assert unit.exists | ||
| assert unit.is_file | ||
|
|
||
| content = unit.content_string | ||
| assert "PathChanged=/var/lib/foreman/vex-latest.tar.zst" in content | ||
| assert "PathModified=/var/lib/foreman/vex-latest.tar.zst" in content | ||
| assert "WantedBy=multi-user.target" in content | ||
|
|
||
|
|
||
| def test_vex_download_path_enabled(server): | ||
| path = server.service("iop-vex-download.path") | ||
| assert path.is_enabled | ||
| assert path.is_running |
Uh oh!
There was an error while loading. Please reload this page.