diff mbox series

[OpenWrt-Devel,v2] scripts: add docker-run-rootfs.sh

Message ID 20200415003948.1128453-1-mail@aparcar.org
State Changes Requested
Headers show
Series [OpenWrt-Devel,v2] scripts: add docker-run-rootfs.sh | expand

Commit Message

Paul Spooren April 15, 2020, 12:39 a.m. UTC
The script allows to run a OpenWrt x86/64 rootfs in no time. It is
possible to access the web interface and SSH via 192.168.1.1.

By using docker volume mounts you can easily share files/folders between
container and host, allowing ot use hosts tools to work on files
deployed in a running OpenWrt instance.

Additional parameters (like volumes) are passed to the `docker create`
command, an example for this below. When quiting the container via `C-d`
a "teardown" removes the container + created network.

    ./scripts/docker-run-rootfs.sh \
      -v $(pwd)/package/base-files/files/bin/sysupgrade-online:/bin/sysupgrade-online \
      -v $(pwd)/package/base-files/files/lib/upgrade/online.sh:/lib/upgrade/online.sh

Files and folders to share must be in 664 mode for "live" upgrades, see[0].

Aditionally it is possible to define "NETWORK_PREFIX" like "192.168.2"
(without final number) to change the created network the OpenWrt
container uses as LAN. This is to avoid network trouble (like if the
developer uses 192.168.1.x as upstream connection) or multiple container
should run in parralllel.

Network is disabled by default, enable it via --network or -n.

Using --prebuild or -p will download the OpenWrt image from docker hub.

[0]: https://forums.docker.com/t/modify-a-file-which-mount-as-a-data-volume-but-it-didnt-change-in-container/2813/14

Signed-off-by: Paul Spooren <mail@aparcar.org>
---
 scripts/docker-run-rootfs.sh | 103 +++++++++++++++++++++++++++++++++++
 1 file changed, 103 insertions(+)
 create mode 100644 scripts/docker-run-rootfs.sh

Comments

Paul Spooren April 15, 2020, 12:53 a.m. UTC | #1
Forgot to annotate, the v2 adds a description of the NETWORK_PREFIX to the usage
message.

On Tue, 2020-04-14 at 14:39 -1000, Paul Spooren wrote:
> The script allows to run a OpenWrt x86/64 rootfs in no time. It is
> possible to access the web interface and SSH via 192.168.1.1.
> 
> By using docker volume mounts you can easily share files/folders between
> container and host, allowing ot use hosts tools to work on files
> deployed in a running OpenWrt instance.
> 
> Additional parameters (like volumes) are passed to the `docker create`
> command, an example for this below. When quiting the container via `C-d`
> a "teardown" removes the container + created network.
> 
>     ./scripts/docker-run-rootfs.sh \
>       -v $(pwd)/package/base-files/files/bin/sysupgrade-
> online:/bin/sysupgrade-online \
>       -v $(pwd)/package/base-
> files/files/lib/upgrade/online.sh:/lib/upgrade/online.sh
> 
> Files and folders to share must be in 664 mode for "live" upgrades, see[0].
> 
> Aditionally it is possible to define "NETWORK_PREFIX" like "192.168.2"
> (without final number) to change the created network the OpenWrt
> container uses as LAN. This is to avoid network trouble (like if the
> developer uses 192.168.1.x as upstream connection) or multiple container
> should run in parralllel.
> 
> Network is disabled by default, enable it via --network or -n.
> 
> Using --prebuild or -p will download the OpenWrt image from docker hub.
> 
> [0]: 
> https://forums.docker.com/t/modify-a-file-which-mount-as-a-data-volume-but-it-didnt-change-in-container/2813/14
> 
> Signed-off-by: Paul Spooren <mail@aparcar.org>
> ---
>  scripts/docker-run-rootfs.sh | 103 +++++++++++++++++++++++++++++++++++
>  1 file changed, 103 insertions(+)
>  create mode 100644 scripts/docker-run-rootfs.sh
> 
> diff --git a/scripts/docker-run-rootfs.sh b/scripts/docker-run-rootfs.sh
> new file mode 100644
> index 0000000000..827ce37c61
> --- /dev/null
> +++ b/scripts/docker-run-rootfs.sh
> @@ -0,0 +1,103 @@
> +#!/bin/sh
> +#   Copyright (C) 2020 Paul Spooren <mail@aparcar.org>
> +
> +set -e
> +
> +SELF="$0"
> +ROOTFS_PATH="$(pwd)/bin/targets/x86/64/openwrt-x86-64-generic-rootfs.tar.gz"
> +NETWORK_ENABLE="${NETWORK_ENABLE:-0}"
> +NETWORK_PREFIX="${NETWORK_PREFIX:-192.168.1}"
> +IMAGE_NAME="openwrt-rootfs:$NETWORK_PREFIX"
> +NETWORK_NAME="none"
> +
> +die() {
> +	echo "$1"
> +	exit 1
> +}
> +
> +usage() {
> +	cat >&2 <<EOF
> +Usage: $SELF [-h|--help]
> +       $SELF
> +         [--rootfs <rootfs>]
> +         [-n|--network]
> +         [-p|--prebuild]
> +
> +<rootfs> allows to specifiy a different path for the rootfs.
> +<network> enables network access based on <NETWORK_PREFIX>
> +
> +A "NETWORK_PREFIX" like "192.168.2" (without final number) can be used to
> +change the created network the OpenWrt container uses as LAN. This is to
> avoid
> +network trouble (like if the developer uses 192.168.1.x as upstream
> connection)
> +or multiple container should run in parralllel.
> +
> +<prebuild> uses the official docker images openwrtorg/rootfs:latest
> +	-> changes to <NETWORK_PREFIX> are ignored
> +EOF
> +}
> +
> +parse_args() {
> +	while [ "$#" -gt 0 ]; do
> +		case "$1" in
> +			--rootfs) ROOTFS_PATH="$2"; shift 2 ;;
> +			--network|-n) NETWORK_ENABLE=1; shift ;;
> +			--prebuild|-p) PREBUILD=1; shift ;;
> +			--help|-h)
> +				usage
> +				exit 0
> +				;;
> +			*)
> +				DOCKER_EXTRA="$DOCKER_EXTRA $1"
> +				shift
> +				;;
> +		esac
> +	done
> +}
> +
> +parse_args "$@"
> +
> +[ -f "$ROOTFS_PATH" ] || die "Couldn't find rootfs at $ROOTFS_PATH"
> +
> +if [ -z "$PREBUILD" ]; then
> +	DOCKERFILE="$(mktemp -p $(dirname $ROOTFS_PATH))"
> +	cat <<EOT > "$DOCKERFILE"
> +	FROM scratch
> +	ADD $(basename $ROOTFS_PATH) /
> +	RUN sed 's/pi_ip="192.168.1.1/pi_ip="$NETWORK_PREFIX.1"/'
> +	RUN sed
> 's/pi_broadcast="192.168.1.255/pi_broadcast="$NETWORK_PREFIX.255"/'
> +	RUN echo "console::askfirst:/usr/libexec/login.sh" >> /etc/inittab
> +	EXPOSE 22 80 443
> +	USER root
> +	CMD ["/sbin/init"]
> +EOT
> +	docker build -t "$IMAGE_NAME" -f "$DOCKERFILE" "$(dirname $ROOTFS_PATH)"
> +	rm "$DOCKERFILE"
> +else
> +	IMAGE_NAME="openwrtorg/rootfs:latest"
> +	docker pull "$IMAGE_NAME"
> +fi
> +
> +echo "[*] Build: $ROOTFS_PATH"
> +
> +if [ "$NETWORK_ENABLE" = 1 ]; then
> +	NETWORK_NAME="openwrt-lan-$NETWORK_PREFIX"
> +	LAN_IP="$NETWORK_PREFIX.1"
> +	if [ -z "$(docker network ls | grep $NETWORK_NAME)" ]; then
> +		docker network create \
> +		  --driver=bridge \
> +		  --subnet="$NETWORK_PREFIX.0/24" \
> +		  --ip-range="$NETWORK_PREFIX.0/24" \
> +		  --gateway="$NETWORK_PREFIX.2" \
> +		  "$NETWORK_NAME"
> +		echo "[*] Created $NETWORK_NAME network "
> +	fi
> +fi
> +
> +docker run -it --rm --network="$NETWORK_NAME" --ip="$LAN_IP" \
> +	--name openwrt-docker $DOCKER_EXTRA "$IMAGE_NAME"
> +echo "[*] Created $IMAGE_NAME"
> +
> +if [ "$NETWORK_ENABLE" = 1 ]; then
> +	docker network rm "$NETWORK_NAME"
> +	echo "[*] Cleaned up network"
> +fi
Yousong Zhou April 15, 2020, 5:29 a.m. UTC | #2
Hi Paul,

On Wed, 15 Apr 2020 at 08:40, Paul Spooren <mail@aparcar.org> wrote:
>
> The script allows to run a OpenWrt x86/64 rootfs in no time. It is
> possible to access the web interface and SSH via 192.168.1.1.
>
> By using docker volume mounts you can easily share files/folders between
> container and host, allowing ot use hosts tools to work on files
> deployed in a running OpenWrt instance.
>
> Additional parameters (like volumes) are passed to the `docker create`
> command, an example for this below. When quiting the container via `C-d`
> a "teardown" removes the container + created network.
>
>     ./scripts/docker-run-rootfs.sh \
>       -v $(pwd)/package/base-files/files/bin/sysupgrade-online:/bin/sysupgrade-online \
>       -v $(pwd)/package/base-files/files/lib/upgrade/online.sh:/lib/upgrade/online.sh
>
> Files and folders to share must be in 664 mode for "live" upgrades, see[0].
>
> Aditionally it is possible to define "NETWORK_PREFIX" like "192.168.2"
> (without final number) to change the created network the OpenWrt
> container uses as LAN. This is to avoid network trouble (like if the
> developer uses 192.168.1.x as upstream connection) or multiple container
> should run in parralllel.
>
> Network is disabled by default, enable it via --network or -n.
>
> Using --prebuild or -p will download the OpenWrt image from docker hub.

Maybe past tense "prebuilt" as option name is better.

>
> [0]: https://forums.docker.com/t/modify-a-file-which-mount-as-a-data-volume-but-it-didnt-change-in-container/2813/14
>
> Signed-off-by: Paul Spooren <mail@aparcar.org>
> ---
>  scripts/docker-run-rootfs.sh | 103 +++++++++++++++++++++++++++++++++++
>  1 file changed, 103 insertions(+)
>  create mode 100644 scripts/docker-run-rootfs.sh
>
> diff --git a/scripts/docker-run-rootfs.sh b/scripts/docker-run-rootfs.sh
> new file mode 100644
> index 0000000000..827ce37c61
> --- /dev/null
> +++ b/scripts/docker-run-rootfs.sh
> @@ -0,0 +1,103 @@
> +#!/bin/sh
> +#   Copyright (C) 2020 Paul Spooren <mail@aparcar.org>
> +
> +set -e
> +
> +SELF="$0"
> +ROOTFS_PATH="$(pwd)/bin/targets/x86/64/openwrt-x86-64-generic-rootfs.tar.gz"
> +NETWORK_ENABLE="${NETWORK_ENABLE:-0}"
> +NETWORK_PREFIX="${NETWORK_PREFIX:-192.168.1}"
> +IMAGE_NAME="openwrt-rootfs:$NETWORK_PREFIX"
> +NETWORK_NAME="none"
> +
> +die() {
> +       echo "$1"
> +       exit 1
> +}
> +
> +usage() {
> +       cat >&2 <<EOF
> +Usage: $SELF [-h|--help]
> +       $SELF
> +         [--rootfs <rootfs>]
> +         [-n|--network]
> +         [-p|--prebuild]
> +
> +<rootfs> allows to specifiy a different path for the rootfs.
> +<network> enables network access based on <NETWORK_PREFIX>
> +
> +A "NETWORK_PREFIX" like "192.168.2" (without final number) can be used to
> +change the created network the OpenWrt container uses as LAN. This is to avoid
> +network trouble (like if the developer uses 192.168.1.x as upstream connection)
> +or multiple container should run in parralllel.
> +
> +<prebuild> uses the official docker images openwrtorg/rootfs:latest
> +       -> changes to <NETWORK_PREFIX> are ignored
> +EOF
> +}
> +
> +parse_args() {
> +       while [ "$#" -gt 0 ]; do
> +               case "$1" in
> +                       --rootfs) ROOTFS_PATH="$2"; shift 2 ;;
> +                       --network|-n) NETWORK_ENABLE=1; shift ;;
> +                       --prebuild|-p) PREBUILD=1; shift ;;
> +                       --help|-h)
> +                               usage
> +                               exit 0
> +                               ;;
> +                       *)
> +                               DOCKER_EXTRA="$DOCKER_EXTRA $1"
> +                               shift
> +                               ;;
> +               esac
> +       done
> +}
> +
> +parse_args "$@"
> +
> +[ -f "$ROOTFS_PATH" ] || die "Couldn't find rootfs at $ROOTFS_PATH"
> +
> +if [ -z "$PREBUILD" ]; then
> +       DOCKERFILE="$(mktemp -p $(dirname $ROOTFS_PATH))"

The "[ -f $ROOTFS_PATH" ]" check should only happen if we do not use
prebuilt image.

> +       cat <<EOT > "$DOCKERFILE"
> +       FROM scratch
> +       ADD $(basename $ROOTFS_PATH) /
> +       RUN sed 's/pi_ip="192.168.1.1/pi_ip="$NETWORK_PREFIX.1"/'
> +       RUN sed 's/pi_broadcast="192.168.1.255/pi_broadcast="$NETWORK_PREFIX.255"/'
> +       RUN echo "console::askfirst:/usr/libexec/login.sh" >> /etc/inittab
> +       EXPOSE 22 80 443
> +       USER root
> +       CMD ["/sbin/init"]
> +EOT

The formatting could be better with "<<-EOF", compraed to "<<EOF"

> +       docker build -t "$IMAGE_NAME" -f "$DOCKERFILE" "$(dirname $ROOTFS_PATH)"
> +       rm "$DOCKERFILE"
> +else
> +       IMAGE_NAME="openwrtorg/rootfs:latest"
> +       docker pull "$IMAGE_NAME"
> +fi
> +
> +echo "[*] Build: $ROOTFS_PATH"

The message should only appear when we use prebuilt image.  Better if
log messages were printed to stderr.  The same applies to "die"
message

> +
> +if [ "$NETWORK_ENABLE" = 1 ]; then
> +       NETWORK_NAME="openwrt-lan-$NETWORK_PREFIX"
> +       LAN_IP="$NETWORK_PREFIX.1"
> +       if [ -z "$(docker network ls | grep $NETWORK_NAME)" ]; then

"docker network inspect xx" is likely better.

> +               docker network create \
> +                 --driver=bridge \
> +                 --subnet="$NETWORK_PREFIX.0/24" \
> +                 --ip-range="$NETWORK_PREFIX.0/24" \
> +                 --gateway="$NETWORK_PREFIX.2" \
> +                 "$NETWORK_NAME"
> +               echo "[*] Created $NETWORK_NAME network "
> +       fi
> +fi
> +
> +docker run -it --rm --network="$NETWORK_NAME" --ip="$LAN_IP" \
> +       --name openwrt-docker $DOCKER_EXTRA "$IMAGE_NAME"
> +echo "[*] Created $IMAGE_NAME"

Should be "Created container openwrt-docker"?  Note that using a fixed
name disallows running multiple containers with this script as
suggested in the commit message.

> +
> +if [ "$NETWORK_ENABLE" = 1 ]; then
> +       docker network rm "$NETWORK_NAME"
> +       echo "[*] Cleaned up network"

Better if "$NETWORK_NAME" was included in log.

Regards,
                yousong
diff mbox series

Patch

diff --git a/scripts/docker-run-rootfs.sh b/scripts/docker-run-rootfs.sh
new file mode 100644
index 0000000000..827ce37c61
--- /dev/null
+++ b/scripts/docker-run-rootfs.sh
@@ -0,0 +1,103 @@ 
+#!/bin/sh
+#   Copyright (C) 2020 Paul Spooren <mail@aparcar.org>
+
+set -e
+
+SELF="$0"
+ROOTFS_PATH="$(pwd)/bin/targets/x86/64/openwrt-x86-64-generic-rootfs.tar.gz"
+NETWORK_ENABLE="${NETWORK_ENABLE:-0}"
+NETWORK_PREFIX="${NETWORK_PREFIX:-192.168.1}"
+IMAGE_NAME="openwrt-rootfs:$NETWORK_PREFIX"
+NETWORK_NAME="none"
+
+die() {
+	echo "$1"
+	exit 1
+}
+
+usage() {
+	cat >&2 <<EOF
+Usage: $SELF [-h|--help]
+       $SELF
+         [--rootfs <rootfs>]
+         [-n|--network]
+         [-p|--prebuild]
+
+<rootfs> allows to specifiy a different path for the rootfs.
+<network> enables network access based on <NETWORK_PREFIX>
+
+A "NETWORK_PREFIX" like "192.168.2" (without final number) can be used to
+change the created network the OpenWrt container uses as LAN. This is to avoid
+network trouble (like if the developer uses 192.168.1.x as upstream connection)
+or multiple container should run in parralllel.
+
+<prebuild> uses the official docker images openwrtorg/rootfs:latest
+	-> changes to <NETWORK_PREFIX> are ignored
+EOF
+}
+
+parse_args() {
+	while [ "$#" -gt 0 ]; do
+		case "$1" in
+			--rootfs) ROOTFS_PATH="$2"; shift 2 ;;
+			--network|-n) NETWORK_ENABLE=1; shift ;;
+			--prebuild|-p) PREBUILD=1; shift ;;
+			--help|-h)
+				usage
+				exit 0
+				;;
+			*)
+				DOCKER_EXTRA="$DOCKER_EXTRA $1"
+				shift
+				;;
+		esac
+	done
+}
+
+parse_args "$@"
+
+[ -f "$ROOTFS_PATH" ] || die "Couldn't find rootfs at $ROOTFS_PATH"
+
+if [ -z "$PREBUILD" ]; then
+	DOCKERFILE="$(mktemp -p $(dirname $ROOTFS_PATH))"
+	cat <<EOT > "$DOCKERFILE"
+	FROM scratch
+	ADD $(basename $ROOTFS_PATH) /
+	RUN sed 's/pi_ip="192.168.1.1/pi_ip="$NETWORK_PREFIX.1"/'
+	RUN sed 's/pi_broadcast="192.168.1.255/pi_broadcast="$NETWORK_PREFIX.255"/'
+	RUN echo "console::askfirst:/usr/libexec/login.sh" >> /etc/inittab
+	EXPOSE 22 80 443
+	USER root
+	CMD ["/sbin/init"]
+EOT
+	docker build -t "$IMAGE_NAME" -f "$DOCKERFILE" "$(dirname $ROOTFS_PATH)"
+	rm "$DOCKERFILE"
+else
+	IMAGE_NAME="openwrtorg/rootfs:latest"
+	docker pull "$IMAGE_NAME"
+fi
+
+echo "[*] Build: $ROOTFS_PATH"
+
+if [ "$NETWORK_ENABLE" = 1 ]; then
+	NETWORK_NAME="openwrt-lan-$NETWORK_PREFIX"
+	LAN_IP="$NETWORK_PREFIX.1"
+	if [ -z "$(docker network ls | grep $NETWORK_NAME)" ]; then
+		docker network create \
+		  --driver=bridge \
+		  --subnet="$NETWORK_PREFIX.0/24" \
+		  --ip-range="$NETWORK_PREFIX.0/24" \
+		  --gateway="$NETWORK_PREFIX.2" \
+		  "$NETWORK_NAME"
+		echo "[*] Created $NETWORK_NAME network "
+	fi
+fi
+
+docker run -it --rm --network="$NETWORK_NAME" --ip="$LAN_IP" \
+	--name openwrt-docker $DOCKER_EXTRA "$IMAGE_NAME"
+echo "[*] Created $IMAGE_NAME"
+
+if [ "$NETWORK_ENABLE" = 1 ]; then
+	docker network rm "$NETWORK_NAME"
+	echo "[*] Cleaned up network"
+fi