Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arvati/5855c148a62974fd193b6df866bc5523 to your computer and use it in GitHub Desktop.
Save arvati/5855c148a62974fd193b6df866bc5523 to your computer and use it in GitHub Desktop.
Create LXC container with Alpine for sound hacks in Openwrt

Create Alpine LXC container in OpenWrt

Config LXC Containers

Config fstab btrfs subvolume /containers to hold all LXC Containers
nano /etc/config/fstab

config mount 'lxc'
        option target '/srv/lxc'
        option uuid '68706ead-a626-4209-b3d0-1187b835f803'
        option fstype 'btrfs'
	option btrfs_raid '1'
	option options 'subvol=/containers,noatime,nodiratime,noacl,nossd'
#        option options 'subvol=/containers,noatime,nodiratime,noacl,degraded,nossd,device=/dev/sda,device=/dev/sdb,device=/dev/sdc,device=/dev/sdd' 
        option enabled '1'

Config LXC to use /srv/lxc

Create or Modify config file to use /srv/lxc path in extroot of openwrt
nano /etc/lxc/lxc.conf

lxc.lxcpath = /srv/lxc

nano /etc/lxc/default.conf

lxc.net.0.type = veth
lxc.net.0.link = br-lan
lxc.net.0.flags = up

Check LXC

lxc-checkconfig

Check host sound

aplay -D plughw:2,0 /usr/share/sounds/alsa/Front_Center.wav

Config LXC to use autodev

mkdir /etc/lxc/hook
nano /etc/lxc/hook/autodev
chmod +x /etc/lxc/hook/autodev
#!/bin/sh
# LXC Autodev hook. Created by Amylum
cd ${LXC_ROOTFS_MOUNT}
mkdir ./dev/snd
ifs_char=$IFS
IFS=$'\n'
ifs_line=$IFS
# group audio in Alpine container is 18 diferent from openwrt number 29
for i in $(ls -l /dev/snd | grep '^c' | tr -s ' ' | awk -F "[ ,]" {'print "mknod -m 660 ./dev/snd/"$11" c "$5" "$7" && chown root:18  ./dev/snd/"$11'})
  do
    IFS=$ifs_char
    eval $i
    IFS=$ifs_line
  done

Download Alpine into Container

First Clear any previous container

lxc-ls --fancy
LXC_CACHE_PATH=/srv/lxc/cache lxc-destroy --snapshots --force --name assistant

Create alpine edge container with name assistant within btrfs subvolume

LXC_CACHE_PATH=/srv/lxc/cache lxc-create --bdev btrfs --name assistant -t alpine -- --release edge --arch x86_64

Config Assistant Container

Config lxc config file container
nano /srv/lxc/assistant/config

lxc.net.0.hwaddr = fa:e6:bf:4f:31:43
lxc.net.0.type = veth
lxc.net.0.link = br-lan
lxc.net.0.flags = up
lxc.rootfs.path = btrfs:/srv/lxc/assistant/rootfs
lxc.mount.entry=/mnt/data/home home/ none bind 0 0
#lxc.mount.entry=/dev/snd dev/snd none bind,optional,create=dir 0 0
lxc.mount.entry=/dev/dsp dev/dsp none bind,optional,create=dir 0 0

# Use autodev to be compatible with systemd
lxc.autodev = 1
lxc.hook.autodev = /etc/lxc/hook/autodev

# Common configuration
lxc.include = /usr/share/lxc/config/alpine.common.conf
# Container specific configuration
lxc.uts.name = assistant
lxc.arch = x86_64
lxc.cap.drop = sys_admin

#Sound device nodes - must be at the end of file after lxc.include
lxc.cgroup.devices.allow = c 116:* rwm
lxc.cgroup.devices.allow = c 14:* rwm

Create folders inside LXC Host

chroot /srv/lxc/assistant/rootfs
mkdir -m 777 -p /opt/assistant
exit

Test Container

Test assistant LXC Container and create root password

lxc-start -n assistant
lxc-attach -n assistant
passwd
exit
lxc-console -n assistant
exit
#CTRL+a +q
lxc-stop -n assistant

Check cgroups devices: lxc-cgroup -n assistant devices.list

Initial Container OS Config

Install some basic packages

apk update
apk upgrade
apk --no-cache add openssh nano sudo tzdata openssh-server-pam openssl shadow
apk --no-cache add alsa-utils alsa-utils-doc alsa-lib alsaconf alsa-ucm-conf
rc-update add sshd
rc-update add alsa
/etc/init.d/sshd start
nano /etc/ssh/sshd_config
/etc/init.d/sshd restart
nano /etc/motd
addgroup root audio

Config Timezone and Languages

Configuring Timezone

ln -f -s '/usr/share/zoneinfo/America/Sao_Paulo' '/etc/localtime'
echo "America/Sao_Paulo" | tee /etc/timezone
date

Sudo without passwords

EDITOR=nano visudo /etc/sudoers.d/nopasswd

%sudo ALL = (ALL) NOPASSWD: ALL
Defaults exempt_group = sudo

Make a dynamic motd for your server

create a crond script to dynamic create an motd message to users

rc-service crond start && rc-update add crond
nano /etc/periodic/15min/motd
chmod a+x /etc/periodic/15min/motd
run-parts --test /etc/periodic/15min

Contents of /etc/periodic/15min/motd

#!/bin/sh
#. /etc/os-release
PRETTY_NAME=`awk -F= '$1=="PRETTY_NAME" { print $2 ;}' /etc/os-release | tr -d '"'`
VERSION_ID=`awk -F= '$1=="VERSION_ID" { print $2 ;}' /etc/os-release`
UPTIME_DAYS=$(expr `cat /proc/uptime | cut -d '.' -f1` % 31556926 / 86400)
UPTIME_HOURS=$(expr `cat /proc/uptime | cut -d '.' -f1` % 31556926 % 86400 / 3600)
UPTIME_MINUTES=$(expr `cat /proc/uptime | cut -d '.' -f1` % 31556926 % 86400 % 3600 / 60)
cat > /etc/motd << EOF
%+++++++++++++++++++++++++++++++ SERVER INFO ++++++++++++++++++++++++++++++++%
%                                                                            %
        Name: `hostname`
        Uptime: $UPTIME_DAYS days, $UPTIME_HOURS hours, $UPTIME_MINUTES minutes
        CPU: `cat /proc/cpuinfo | grep 'model name' | head  -1 | cut -d':' -f2`
        Memory: `free -m | head -n 2 | tail -n 1 | awk {'print  $2'}`M
        Swap: `free -m | tail -n 1 | awk {'print $2'}`M Disk: `df -h / | awk  '{ a = $2 } END { print a }'`

        Kernel: `uname -r`
        Distro: $PRETTY_NAME
        Version $VERSION_ID

        CPU Load: `cat /proc/loadavg | awk '{print $1 ", " $2 ", " $3}'`
        Free Memory: `free -m | head -n 2 | tail -n 1 | awk {'print $4'}`M
        Free Swap: `free -m | tail -n 1 | awk {'print $4'}`M
        Free Disk: `df -h / | awk '{ a =  $2 } END { print a }'`

        eth0 Address: `ifconfig eth0 | grep "inet addr" |  awk -F: '{print $2}' | awk '{print $1}'`
%                                                                            %
%++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%
EOF

Check the result:
cat /etc/motd

Creating Users

Creating user manager and allow it to sudoers

addgroup -S sudo
adduser manager
addgroup manager sudo
addgroup manager audio

Check sudoers users
getent group sudo

Now log into container using user and password

exit
lxc-stop -n assistant
lxc-start -n assistant
lxc-console --name assistant

Create ssh login credentials

exit
#cat ~/.ssh/id_rsa.pub | ssh root@assistant "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
cat ~/.ssh/id_rsa.pub | ssh manager@assistant "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

You may Log in using ssh now

#ssh root@assistant
ssh manager@assistant

Sound inside container

Test with:

aplay -D plughw:2,0 /usr/share/sounds/alsa/Front_Center.wav
arecord -D plughw:2,0 -f S16_LE -r 48000 -d5 test.wav
aplay -D plughw:2,0 test.wav
rm test.wav

Make SSL certificate

Making certificate files:

  • keyfile=/root/certs/assistant.key
  • certfile=/root/certs/assistant.crt
su root
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout assistant.key -out assistant.crt -subj /CN=assistant.casa -addext subjectAltName=DNS:assistant.casa,DNS:assistant,IP:192.168.1.74
mkdir -p /root/certs
cp assistant.* /root/certs/
chgrp -R users /opt/assistant
chmod 750 -R /opt/assistant
https://developers.google.com/assistant/sdk/guides/service/python/embed/config-dev-project-and-account
https://console.cloud.google.com/apis/credentials/consent?project=gerente-7f562
```
sudo apk add py3-virtualenv python3-dev
cd /opt/assistant/
python3 -m venv env
env/bin/python -m pip install --upgrade pip setuptools wheel
source env/bin/activate
python -m pip install --upgrade google-auth-oauthlib[tool]
google-oauthlib-tool --client-secrets /opt/assistant/client_secret_client-id.json --scope https://www.googleapis.com/auth/assistant-sdk-prototype --save --headless
credentials saved: /home/user/.config/google-oauthlib-tool/credentials.json
```
```
sudo apk add portaudio-dev libffi-dev openssl-dev linux-headers g++ musl-dev libffi-dev py3-grpcio gcc cargo grpc py3-google-auth-httplib2
python -m pip install --upgrade setuptools_rust
python -m pip install --upgrade google-assistant-sdk[samples]
python -m pip install --upgrade google-auth-oauthlib[tool]
```
```
nano ~/.asoundrc
pcm.!default {
type asym
capture.pcm "mic"
playback.pcm "speaker"
}
pcm.mic {
type plug
slave {
pcm "hw:2,0"
}
}
pcm.speaker {
type plug
slave {
pcm "hw:2,0"
}
}
```
```
googlesamples-assistant-pushtotalk --project-id gerente-7f562 --device-model-id gerente-openwrt-x64-router
googlesamples-assistant-audiotest --project-id gerente-7f562 --device-model-id gerente-openwrt-x64-router
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment