From eefb903a28c1ecf3143975786e9c2189d397abf7 Mon Sep 17 00:00:00 2001 From: Kohei Watanabe Date: Sun, 25 Jul 2021 13:56:57 +0900 Subject: [PATCH] feat: megabit mode --- README.md | 2 +- apkovl/etc/apk/world | 1 + apkovl/etc/init.d/megabit | 4 ++++ apkovl/etc/init.d/megabit-sync | 11 +++++++++++ apkovl/etc/modprobe.d/g_mass_storage.conf | 1 - apkovl/etc/modules-load.d/g_mass_storage.conf | 1 - apkovl/etc/runlevels/default/megabit | 1 + apkovl/etc/runlevels/default/megabit-sync | 1 + apkovl/usr/local/bin/megabit | 4 ++++ apkovl/usr/local/bin/megabit-sync | 3 +++ docker-compose.yml | 8 +++++--- fstab | 4 ++-- overlay.img.gz | Bin 588868 -> 590970 bytes 13 files changed, 33 insertions(+), 8 deletions(-) create mode 100755 apkovl/etc/init.d/megabit create mode 100755 apkovl/etc/init.d/megabit-sync delete mode 100644 apkovl/etc/modprobe.d/g_mass_storage.conf delete mode 100644 apkovl/etc/modules-load.d/g_mass_storage.conf create mode 120000 apkovl/etc/runlevels/default/megabit create mode 120000 apkovl/etc/runlevels/default/megabit-sync create mode 100755 apkovl/usr/local/bin/megabit create mode 100755 apkovl/usr/local/bin/megabit-sync diff --git a/README.md b/README.md index 1c7e7c8..2a7de75 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Yama +# Megabit OS Raspberry Pi 向け OS のビルドするためのツール群 diff --git a/apkovl/etc/apk/world b/apkovl/etc/apk/world index 5534b63..222f2dc 100644 --- a/apkovl/etc/apk/world +++ b/apkovl/etc/apk/world @@ -1,4 +1,5 @@ alpine-base i2c-tools openssh +rsync wpa_supplicant diff --git a/apkovl/etc/init.d/megabit b/apkovl/etc/init.d/megabit new file mode 100755 index 0000000..93e0760 --- /dev/null +++ b/apkovl/etc/init.d/megabit @@ -0,0 +1,4 @@ +#!/sbin/openrc-run +name=megabit +command="/usr/local/bin/megabit" +pidfile="/var/run/megabit.pid" diff --git a/apkovl/etc/init.d/megabit-sync b/apkovl/etc/init.d/megabit-sync new file mode 100755 index 0000000..6153b82 --- /dev/null +++ b/apkovl/etc/init.d/megabit-sync @@ -0,0 +1,11 @@ +#!/sbin/openrc-run +name=megabit-sync +command="/usr/local/bin/megabit-sync" +pidfile="/var/run/megabit-sync.pid" + +start_pre() { + mkdir -p /mnt/tmp + mount /usr/share/megabit/tmp.img /mnt/tmp + modprobe -r g_mass_storage + modprobe g_mass_storage file=/usr/share/megabit/tmp.img +} diff --git a/apkovl/etc/modprobe.d/g_mass_storage.conf b/apkovl/etc/modprobe.d/g_mass_storage.conf deleted file mode 100644 index cf8ee44..0000000 --- a/apkovl/etc/modprobe.d/g_mass_storage.conf +++ /dev/null @@ -1 +0,0 @@ -options g_mass_storage file=/dev/mmcblk0p1 diff --git a/apkovl/etc/modules-load.d/g_mass_storage.conf b/apkovl/etc/modules-load.d/g_mass_storage.conf deleted file mode 100644 index fd5ae93..0000000 --- a/apkovl/etc/modules-load.d/g_mass_storage.conf +++ /dev/null @@ -1 +0,0 @@ -g_mass_storage diff --git a/apkovl/etc/runlevels/default/megabit b/apkovl/etc/runlevels/default/megabit new file mode 120000 index 0000000..fb1ac2b --- /dev/null +++ b/apkovl/etc/runlevels/default/megabit @@ -0,0 +1 @@ +/etc/init.d/megabit \ No newline at end of file diff --git a/apkovl/etc/runlevels/default/megabit-sync b/apkovl/etc/runlevels/default/megabit-sync new file mode 120000 index 0000000..e38d827 --- /dev/null +++ b/apkovl/etc/runlevels/default/megabit-sync @@ -0,0 +1 @@ +/etc/init.d/megabit-sync \ No newline at end of file diff --git a/apkovl/usr/local/bin/megabit b/apkovl/usr/local/bin/megabit new file mode 100755 index 0000000..1e20220 --- /dev/null +++ b/apkovl/usr/local/bin/megabit @@ -0,0 +1,4 @@ +#!/bin/sh +export NODE_PATH=$(npm root -g) +nodemon --delay 1 --watch /tmp --signal SIGTERM --exec 'node /tmp/index.js || true' & +echo $! > /var/run/megabit.pid diff --git a/apkovl/usr/local/bin/megabit-sync b/apkovl/usr/local/bin/megabit-sync new file mode 100755 index 0000000..9aa4cc3 --- /dev/null +++ b/apkovl/usr/local/bin/megabit-sync @@ -0,0 +1,3 @@ +#!/bin/sh +nodemon --delay 1 --watch /usr/share/megabit/tmp.img --signal SIGTERM --exec 'umount /mnt/tmp; mount /usr/share/megabit/tmp.img /mnt/tmp; rsync -a --delete --exclude=node_modules/ /mnt/tmp/ /tmp/' & +echo $! > /var/run/megabit-sync.pid diff --git a/docker-compose.yml b/docker-compose.yml index f59e17d..449b09f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,7 +16,9 @@ services: - ./dist/overlay.img:/overlay.img privileged: true command: | - sh -c ' - mount -a \ - && apk add g++ linux-headers make nodejs npm python3 + sh -exc ' + mkdir -p /mnt/overlay + mount -a + apk add g++ linux-headers make nodejs npm python3 + npm install -g megabit nodemon ' diff --git a/fstab b/fstab index 5618065..9e9d56c 100644 --- a/fstab +++ b/fstab @@ -1,2 +1,2 @@ -/overlay.img /mnt ext4 rw,relatime,errors=remount-ro 0 0 -overlay /usr overlay lowerdir=/usr,upperdir=/mnt/upper/usr,workdir=/mnt/work/usr 0 0 +/overlay.img /mnt/overlay ext4 rw,relatime,errors=remount-ro 0 0 +overlay /usr overlay lowerdir=/usr,upperdir=/mnt/overlay/upper/usr,workdir=/mnt/overlay/work/usr 0 0 diff --git a/overlay.img.gz b/overlay.img.gz index 1b6992bc2ceef29464a4b5d68c984357b759456a..84846eff317b2418ac2adb8cf001fbd93099877c 100644 GIT binary patch delta 5833 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 XD8xzZSx$b%@tlJ%J*|7E_Z0gdpa0Yv delta 3549 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