RaspberryPi tethered to iPad personal hotspot via usb

Alright, I tried the following:
Docker.template

FROM balenalib/rpi-raspbian:stretch

# Install Systemd
RUN apt-get update && apt-get install -y --no-install-recommends \
        systemd \
        systemd-sysv \
    && rm -rf /var/lib/apt/lists/*

ENV container docker

RUN curl https://nginx.org/keys/nginx_signing.key | apt-key add - \
	&& echo 'deb http://nginx.org/packages/debian/ stretch nginx' >> /etc/apt/sources.list \
    && apt-get update && apt-get install -y --no-install-recommends \
        systemd \
        nginx \
    && rm -rf /var/lib/apt/lists/*

# We never want these to run in a container
# Feel free to edit the list but this is the one we used
RUN systemctl mask \
    dev-hugepages.mount \
    sys-fs-fuse-connections.mount \
    sys-kernel-config.mount \

    display-manager.service \
    getty@.service \
    systemd-logind.service \
    systemd-remount-fs.service \

    getty.target \
    graphical.target \
    kmod-static-nodes.service

COPY entry.sh /usr/bin/entry.sh
COPY resin.service /etc/systemd/system/resin.service

RUN systemctl enable resin.service

RUN apt-get update && \
    apt-get install telnet nano iputils-ping less kmod net-tools ifupdown i2c-tools usbutils wget curl ipheth-utils libimobiledevice-dev libimobiledevice-utils ifuse usbmuxd && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

COPY nginx.service /lib/systemd/system/nginx.service

# Copies the package.json first for better cache on later pushes
COPY package.json package.json

COPY start.sh start.sh
COPY nginx.conf /etc/nginx/nginx.conf


# This will copy all files in our root to the working  directory in the container
COPY . /usr/share/nginx/html/

# Enable systemd init system in container
#ENV INITSYSTEM on

#CMD ["bash", "start.sh"]

STOPSIGNAL 37
ENTRYPOINT ["/usr/bin/entry.sh"]

Entry.sh (I omitted the start.sh script for the time being to see if the container can start without it)

#!/bin/bash

set -m

if hostname "$HOSTNAME" &> /dev/null; then
	PRIVILEGED=true
else
	PRIVILEGED=false
fi

# Send SIGTERM to child processes of PID 1.
function signal_handler()
{
	kill "$pid"
}

function start_udev()
{
	if [ "$UDEV" == "on" ]; then
		if [ "$INITSYSTEM" != "on" ]; then
			if command -v udevd &>/dev/null; then
				unshare --net udevd --daemon &> /dev/null
			else
				unshare --net /lib/systemd/systemd-udevd --daemon &> /dev/null
			fi
			udevadm trigger &> /dev/null
		fi
	else
		if [ "$INITSYSTEM" == "on" ]; then
			systemctl mask systemd-udevd
		fi
	fi
}

function mount_dev()
{
	tmp_dir='/tmp/tmpmount'
	mkdir -p "$tmp_dir"
	mount -t devtmpfs none "$tmp_dir"
	mkdir -p "$tmp_dir/shm"
	mount --move /dev/shm "$tmp_dir/shm"
	mkdir -p "$tmp_dir/mqueue"
	mount --move /dev/mqueue "$tmp_dir/mqueue"
	mkdir -p "$tmp_dir/pts"
	mount --move /dev/pts "$tmp_dir/pts"
	touch "$tmp_dir/console"
	mount --move /dev/console "$tmp_dir/console"
	umount /dev || true
	mount --move "$tmp_dir" /dev

	# Since the devpts is mounted with -o newinstance by Docker, we need to make
	# /dev/ptmx point to its ptmx.
	# ref: https://www.kernel.org/doc/Documentation/filesystems/devpts.txt
	ln -sf /dev/pts/ptmx /dev/ptmx
	mount -t debugfs nodev /sys/kernel/debug
}

function init_systemd()
{
	GREEN='\033[0;32m'
	echo -e "${GREEN}Systemd init system enabled."
	for var in $(compgen -e); do
		printf '%q=%q\n' "$var" "${!var}"
	done > /etc/docker.env
	echo 'source /etc/docker.env' >> ~/.bashrc

	printf '#!/bin/bash\n exec ' > /etc/resinApp.sh
	printf '%q ' "$@" >> /etc/resinApp.sh
	chmod +x /etc/resinApp.sh

	mkdir -p /etc/systemd/system/resin.service.d
	cat <<-EOF > /etc/systemd/system/resin.service.d/override.conf
		[Service]
		WorkingDirectory=$(pwd)
	EOF

	sleep infinity &
	exec env DBUS_SYSTEM_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket /sbin/init quiet systemd.show_status=0
}

function init_non_systemd()
{
	# trap the stop signal then send SIGTERM to user processes
	trap signal_handler SIGRTMIN+3 SIGTERM

	# echo error message, when executable file doesn't exist.
	if CMD=$(command -v "$1" 2>/dev/null); then
		shift
		"$CMD" "$@" &
		pid=$!
		wait "$pid"
		exit_code=$?
		fg &> /dev/null || exit "$exit_code"
	else
		echo "Command not found: $1"
		exit 1
	fi
}

INITSYSTEM=$(echo "$INITSYSTEM" | awk '{print tolower($0)}')

case "$INITSYSTEM" in
	'1' | 'true')
		INITSYSTEM='on'
	;;
esac

if $PRIVILEGED; then
	# Only run this in privileged container
	mount_dev
	start_udev
fi

if [ "$INITSYSTEM" = "on" ]; then
	init_systemd "$@"
else
	init_non_systemd "$@"
fi

tail -f /dev/null

the container is still not starting

Hello, the start.sh script tests for INITSYSTEM = on but that is commented out in your Dockerfile. Iā€™d also change ENTRYPOINT to CMD to keep things simple.

Hi thanks for your help.
I tried as suggested but still no luck.
Out of desperation I tried to search for an example of how to enable systemd on Balena containers and found the following:

It seems a pretty recent example by your team

I tried to clone the repository and run it but I still have the same issue (container installed but not starting)

PS: Iā€™m using balenaOS 2.31.5+rev1

I am pushing the app to my device to test it out, but I have some questions in the meantime. Did you push it to your device as-is? Did you get any errors during the build step? If you want you can enable support access for the device, send me the ID in PM and I can look at it.

I tested it out and it works correctly, and the container starts as expected (tried on a rpi3 on balena 2.37.0). Maybe you can try upgrading the OS and see if that works, otherwise we can check the device out.

Thanks for testing,
I will try upgrading and let you know asap

I manage to install and run balenalib-systemd-example on the raspberryPi3 with balenaOS 2.36.0+rev2

Now, going back to the original topic, I tried to install the libraries to enable iphone tethering.
Tethering works fine when I restart the container and call ā€œidevicepair pairā€ but if I disconnect the iphone and reconnect ā€œidevicepair pairā€ returns ā€œNo device found, is it plugged in?ā€
I can see the device with lsusb but I canā€™t see eth1 with ā€œifconfig -sā€
See below docker compose and docker files:

Docker compose

version: '2'
services:
  app:
    build: ./app
    privileged: true
    environment:
      - UDEV=1
    devices:
      - '/dev:/dev'
    network_mode: host

Docker template

FROM balenalib/%%BALENA_MACHINE_NAME%%-debian

#################
# Install Systemd
#################
ENV container docker
RUN apt-get update && apt-get install -y --no-install-recommends \
		systemd-sysv \
	&& rm -rf /var/lib/apt/lists/*

# We never want these to run in a container
# Feel free to edit the list but this is the one we used
RUN systemctl mask \
    dev-hugepages.mount \
    #sys-fs-fuse-connections.mount \
    sys-kernel-config.mount \

    display-manager.service \
    getty@.service \
    systemd-logind.service \
    #systemd-remount-fs.service \

    getty.target \
    graphical.target

COPY systemd/entry.sh /usr/bin/entry.sh
COPY systemd/balena.service /etc/systemd/system/balena.service

RUN systemctl enable /etc/systemd/system/balena.service

STOPSIGNAL 37
ENTRYPOINT ["/usr/bin/entry.sh"]
ENV INITSYSTEM on
######################
# Finish setup systemd
######################

RUN apt-get update && \
    apt-get install telnet nano iputils-ping less kmod net-tools ifupdown i2c-tools usbutils wget curl libimobiledevice-utils ifuse usbmuxd && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# Setting up the user application
WORKDIR /usr/src/app
COPY start.sh ./
COPY iphoneconnect /lib/udev/iphoneconnect
RUN chmod 755 /lib/udev/iphoneconnect
COPY 90-iphone-tether.rules /lib/udev/rules.d/90-iphone-tether.rules

CMD ["bash", "start.sh"]

Start.sh

#!/bin/bash

systemctl enable usbmuxd
systemctl start usbmuxd

mkdir /media/iphone

echo 'allow-hotplug eth1' >> /etc/network/interfaces
echo 'iface eth1 inet dhcp' >> /etc/network/interfaces

sudo /etc/init.d/networking restart

while : ; do
  systemctl --system --no-pager
  sleep 15
done

I also granted access to the device if that helps! Many thanks!

hey @enricopenzo, can you please share with us your device uuid so we can have a look?

Sure, 91e84ead745ab256398cc31035d07362
thanks

Hi

It looks like UDEV is not running in your application container, which is probably the reason for the issue. Could you go ahead and change your entry.sh script to the one found here: https://github.com/balena-io-library/base-images/blob/master/examples/INITSYSTEM/systemd/systemd.v230/entry.sh and retry.

Thanks.

Hi, thanks
Just tried, Iā€™m getting the following error message in the logs:

Should the UDEV environment variable be UDEV=1 or UDEV=on?

version: '2'
services:
  app:
    build: ./app
    privileged: true
    environment:
      - UDEV=1
    devices:
      - '/dev:/dev'
    network_mode: host

I would say UDEV=on as per https://github.com/balena-io-library/base-images/blob/f0df6f1dde8174b94cfc7cd078247b3c6c3a4254/examples/INITSYSTEM/systemd/systemd.v230/entry.sh#L17 :+1:

Alright UDEV=on seems to be working.
Udev seems active but that didnā€™t solve the problem related to iphone tethering not working once disconnected / reconnected :exploding_head:

It seems to be working now :sweat_smile:

For future reference, I installed different libraries:
RUN apt-get update &&
apt-get install gvfs ipheth-utils libimobiledevice-utils gvfs-backends gvfs-bin gvfs-fuse ifuse usbmuxd &&
apt-get clean &&
rm -rf /var/lib/apt/lists/*

as found in this post:
http://w6kd.boards.net/thread/146/usb-tethering-instructions-raspberry-star

Awesome. Glad you managed to get it working, and great idea using the USB tethering mode.

1 Like