From d77f7ebfd68d7a30e924f366dec10f594dd4bd6a Mon Sep 17 00:00:00 2001 From: Jakub Michalski Date: Thu, 1 Feb 2024 12:38:28 +0100 Subject: [PATCH] Make shared dirs persistent --- .github/workflows/release.yml | 53 ++++++++++++++++++++++++ README.md | 8 ++-- action/device/hifive_unleashed/init.resc | 2 +- action/device/zynq_7000/init.resc | 2 +- action/images.py | 42 ++++++++++++++----- action/run-in-renode.py | 14 ++++++- action/tasks/save_shared_dirs.yml | 8 ++++ 7 files changed, 112 insertions(+), 17 deletions(-) create mode 100644 action/tasks/save_shared_dirs.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1d519e9..78c7aad 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -144,6 +144,59 @@ jobs: git+https://github.com/antmicro/tuttest.git@c44309e0365c54759fb36864fb77bf8b347bd647 repos: https://github.com/antmicro/pyrav4l2.git pyrav4l2 + riscv64-shared-dirs-test: + runs-on: ubuntu-latest + needs: send-to-releases + if: ${{ !failure() && !github.event.act }} + steps: + - uses: actions/checkout@v3 + + - name: prepare shared directiories + run: mkdir shared_dir shared_dir2 + + - name: test + uses: ./ + with: + rootfs-size: +128M + shared-dirs: | + shared_dir /home/shared_dir + shared_dir2 /home/shared_dir2 + renode-run: | + echo "shared-dirs-test" > shared_dir/f.txt + echo "shared-dirs-test2" > shared_dir2/f.txt + + - name: read shared directories + run: | + $([ "$(cat shared_dir/f.txt)" = "shared-dirs-test" ]) + $([ "$(cat shared_dir2/f.txt)" = "shared-dirs-test2" ]) + + arm32-shared-dirs-test: + runs-on: ubuntu-latest + needs: send-to-releases + if: ${{ !failure() && !github.event.act }} + steps: + - uses: actions/checkout@v3 + + - name: prepare shared directiories + run: mkdir shared_dir shared_dir2 + + - name: test + uses: ./ + with: + arch: arm32 + rootfs-size: +128M + shared-dirs: | + shared_dir /home/shared_dir + shared_dir2 /home/shared_dir2 + renode-run: | + echo "shared-dirs-test" > shared_dir/f.txt + echo "shared-dirs-test2" > shared_dir2/f.txt + + - name: read shared directories + run: | + $([ "$(cat shared_dir/f.txt)" = "shared-dirs-test" ]) + $([ "$(cat shared_dir2/f.txt)" = "shared-dirs-test2" ]) + arm32-test: runs-on: ubuntu-latest needs: send-to-releases diff --git a/README.md b/README.md index 822ec33..1a3b35d 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ This is achieved by running an emulated Linux system inside [Renode](https://ren ### OS configuration -- [`rootfs-size`](#rootfs-size) - Set the size of the rootfs image. Default: `auto` +- [`rootfs-size`](#rootfs-size) - Set the size of the rootfs image. Default: `auto`. - [`image-type`](#image) - `native` or `docker`. Read about the differences in the [image section](#image) - [`image`](#image) - URL path to a Linux rootfs `tar.xz` archive for the specified architecture or a Docker image identifier. If not specified, the action will use the default one. See releases for examples - [`tasks`](#tasks) - Allows you to change the way the system is initialized. See [Tasks](#tasks) for more details. @@ -132,7 +132,9 @@ We are working on adding `arm64` support. You can specify many directories that will be added to the rootfs. All files from these directories will be available in the specified target directories. -In the following example, files from the `project-files` directory will be extracted to the `/opt/project` directory. If no destination directory is specified, the files will be extracted to `/home`. +In the following example, files from the `project-files` directory will be extracted to the `/opt/project` directory. If no destination directory is specified, the files will be extracted to `/home`. + +At the end of the action contents of the shared directories will be copied back from the mounted filesystem. ```yaml - uses: antmicro/renode-linux-runner-action@v1 @@ -226,7 +228,7 @@ If you need additional software, you can mount your own filesystem. More informa ## Rootfs size -The size of the mounted rootfs can be specified with the `rootfs-size` parameter. The parameter accepts sizes in bytes (e.g. `1000000000`), kilobytes (e.g. `50000K`), megabytes (e.g. `512M`) or gigabytes (e.g. `1G`). The default `rootfs-size` value is `auto`; with this setting the size is calculated automatically. +The size of the mounted rootfs can be specified with the `rootfs-size` parameter. The parameter accepts sizes in bytes (e.g. `1000000000`), kilobytes (e.g. `50000K`), megabytes (e.g. `512M`) or gigabytes (e.g. `1G`). The default `rootfs-size` value is `auto`; with this setting the size is calculated automatically. Preceding the value with `+` sign (e.g. `+value`) sets the size to `auto` + `value`. ```yaml - uses: antmicro/renode-linux-runner-action@v1 diff --git a/action/device/hifive_unleashed/init.resc b/action/device/hifive_unleashed/init.resc index 94a77cf..f60a288 100644 --- a/action/device/hifive_unleashed/init.resc +++ b/action/device/hifive_unleashed/init.resc @@ -6,7 +6,7 @@ machine LoadPlatformDescription @action/device/hifive_unleashed/platform.repl # rootfs machine LoadPlatformDescriptionFromString 'virtio: Storage.VirtIOBlockDevice @ sysbus 0x100d0000 { IRQ -> plic@50 }' -virtio LoadImage @images/rootfs.img +virtio LoadImage @images/rootfs.img true showAnalyzer uart0 e51 LogFunctionNames true diff --git a/action/device/zynq_7000/init.resc b/action/device/zynq_7000/init.resc index 021c99f..802a520 100644 --- a/action/device/zynq_7000/init.resc +++ b/action/device/zynq_7000/init.resc @@ -19,7 +19,7 @@ ttc1 Frequency 33333333 # rootfs machine LoadPlatformDescriptionFromString 'virtio: Storage.VirtIOBlockDevice @ sysbus 0xe0104000 { IRQ -> gic@63 }' -virtio LoadImage @images/rootfs.img +virtio LoadImage @images/rootfs.img true # This setting increases emulation speed, thus mitigates networks errors and speedup user scripts. machine SetAdvanceImmediately true diff --git a/action/images.py b/action/images.py index 85a3faa..bda1e24 100644 --- a/action/images.py +++ b/action/images.py @@ -105,6 +105,36 @@ def prepare_kernel_and_initramfs(kernel: str): error("Kernel not found! Action expects Image or vmlinux file.") +def rootfs_size(size_str: str) -> int: + """ + Returns rootfs size + + Parameters + ---------- + size_str: str + rootfs-size action parameter value + """ + + units = { + "B": 1, + "K": 1024, + "M": 1024**2, + "G": 1024**3 + } + + if size_str == "auto" or size_str.startswith("+"): + size = 0 + for path, _, files in os.walk("images/rootfs"): + for f in files: + fp = os.path.join(path, f) + if not os.path.islink(fp): + size += os.path.getsize(fp) + + additional_size = int(size_str[:-1]) * units[size_str[-1]] if size_str.startswith("+") and size_str[-1] in units else 0 + return max(size * 2, 5 * 10**7) + additional_size + return int(size_str) + + def burn_rootfs_image( user_directory: str, image: str, @@ -185,18 +215,8 @@ def burn_rootfs_image( dirs_exist_ok=True ) - if image_size == "auto": - size = 0 - for path, _, files in os.walk("images/rootfs"): - for f in files: - fp = os.path.join(path, f) - if not os.path.islink(fp): - size += os.path.getsize(fp) - - image_size = f'{max(size * 2, 5 * 10**7)}' try: - - run(["truncate", "images/rootfs.img", "-s", image_size], check=True) + run(["truncate", "images/rootfs.img", "-s", f"{rootfs_size(image_size)}"], check=True) run(["mkfs.ext4", "-d", "images/rootfs", "images/rootfs.img"], check=True, stdout=DEVNULL) diff --git a/action/run-in-renode.py b/action/run-in-renode.py index b0e0a8d..6f0eba5 100644 --- a/action/run-in-renode.py +++ b/action/run-in-renode.py @@ -16,14 +16,17 @@ from common import get_file, error, archs from devices import add_devices from dependencies import add_repos, add_packages -from images import prepare_shared_directories, prepare_kernel_and_initramfs, burn_rootfs_image +from images import prepare_shared_directories, prepare_kernel_and_initramfs, burn_rootfs_image, shared_directories_actions from dispatcher import CommandDispatcher +from subprocess import run from datetime import datetime import sys import json import yaml +import shutil +import os DEFAULT_IMAGE_PATH = "https://github.com/{}/releases/download/{}/image-{}-default.tar.xz" @@ -146,3 +149,12 @@ def test_task(test_task_str: str): dispatcher.add_task(test_task(args.get("renode-run", ""))) dispatcher.evaluate() + + run(["mkdir", "rootfs"], check=True) + run(["sudo", "mount", "images/rootfs.img", "rootfs"], check=True) + + for dir in shared_directories_actions: + src = f"rootfs/{dir.target}" + dst = f"{user_directory}/{dir.host}" if not dir.host.startswith('/') else dir.host + if os.path.exists(src): + shutil.copytree(src, dst, dirs_exist_ok=True) diff --git a/action/tasks/save_shared_dirs.yml b/action/tasks/save_shared_dirs.yml new file mode 100644 index 0000000..0568515 --- /dev/null +++ b/action/tasks/save_shared_dirs.yml @@ -0,0 +1,8 @@ +name: save_shared_dirs +shell: target +requires: [action_test] +echo: true +timeout: 5 +fail-fast: false +commands: + - sync \ No newline at end of file