From f363684abccdb6a9446171a6e800e7c931e8dd24 Mon Sep 17 00:00:00 2001 From: Rich Braun Date: Thu, 22 Aug 2024 07:41:01 -0700 Subject: [PATCH] SYS-623 re-implement weewx installation for version 5.x --- images/weewx/Dockerfile | 69 +++++++++++++++----------------- images/weewx/README.md | 11 +++-- images/weewx/entrypoint.sh | 50 ++++++++++++----------- images/weewx/helm/Chart.yaml | 2 +- images/weewx/install-input.txt | 3 +- images/weewx/log.conf | 4 ++ images/weewx/requirements.txt | 7 ---- k8s/helm/restic/Chart.yaml | 4 +- k8s/helm/restic/values.yaml | 2 +- k8s/helm/vaultwarden/values.yaml | 1 + 10 files changed, 74 insertions(+), 79 deletions(-) create mode 100644 images/weewx/log.conf diff --git a/images/weewx/Dockerfile b/images/weewx/Dockerfile index 55f4baa9..065b878a 100644 --- a/images/weewx/Dockerfile +++ b/images/weewx/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine:3.19 +FROM alpine:3.20 MAINTAINER Rich Braun "docker@instantlinux.net" ARG BUILD_DATE ARG VCS_REF @@ -43,52 +43,47 @@ ENV AIRLINK_HOST= \ TZ_CODE=10 \ WEBCAM_URL=https://www.wunderground.com/wundermap?lat=37.761&lon=-122.435&zoom=5&radar=1&cam=1 \ WEEK_START=6 \ - WX_USER=weewx \ - XTIDE_LOCATION=unset + WX_ROOT=/home/weewx/weewx-data \ + WX_USER=weewx -ARG WEEWX_VERSION=5.0.2 -ARG WEEWX_SHA=3e55fdf359b9aa3388a1826f0bfad6665a1a865ddfa521286449bcad036c4262 +ARG WEEWX_VERSION=5.1.0 ARG WEEGREEN_VERSION=v0.12 +ARG AIRLINK_VERSION=1.4 ARG WX_GROUP=dialout ARG WX_UID=2071 -ARG XTIDE_SHA=e5c4afbb17269fdde296e853f2cb84845ed1c1bb1932f780047ad71d623bc681 +ARG AIRLINK_SHA=6392ee1d8e96a543306f16430ec9095b79dd7d0aacf8078171aa61b060a49745 -COPY install-input.txt requirements.txt /root/ RUN apk add --no-cache --update \ curl freetype libjpeg libstdc++ openssh openssl python3 py3-cheetah \ - py3-configobj py3-mysqlclient py3-pillow py3-requests py3-six py3-usb \ + py3-configobj py3-mysqlclient py3-pillow py3-pymysql py3-pyserial \ + py3-requests py3-six py3-usb \ rsync rsyslog tzdata && \ adduser -u $WX_UID -s /bin/sh -G $WX_GROUP -D $WX_USER && \ - mkdir build && cd build && \ - curl -sLo weewx.tgz \ - http://www.weewx.com/downloads/released_versions/weewx-$WEEWX_VERSION.tgz && \ - echo "$WEEWX_SHA weewx.tgz" >> /build/checksums && \ - sha256sum -c /build/checksums && \ - apk add --no-cache --virtual .fetch-deps \ - file freetype-dev g++ gawk gcc git jpeg-dev libpng-dev make musl-dev \ - py3-pip py3-wheel python3-dev zlib-dev && \ - # - # Lots of breaking changes since 4.x, alas: ticket is SYS-623. - # See https://github.com/weewx/weewx/wiki/v5-upgrade - # The setup.py procedure found in 4.x went missing in 5.0 - # - # TODO deal with break-system-packages, no idea what broke - pip install -r /root/requirements.txt --break-system-packages && \ - tar xf weewx.tgz --strip-components=1 && \ - ### TODO 5/20/2024 version 5.0 no longer has setup.py. Build is broken. - cd /build && \ - ./setup.py build && ./setup.py install < /root/install-input.txt && \ + apk add --no-cache --virtual .fetch-deps git && \ git clone -b $WEEGREEN_VERSION --depth 1 \ https://github.com/instantlinux/weewx-WeeGreen.git \ - /home/$WX_USER/skins/WeeGreen && \ - curl -sLo /tmp/weewx-airlink.zip \ - https://github.com/chaunceygardiner/weewx-airlink/archive/master.zip && \ - /home/$WX_USER/bin/wee_extension --install /tmp/weewx-airlink.zip && \ + $WX_ROOT/skins/WeeGreen && \ apk del .fetch-deps && \ - rm -fr /build /home/$WX_USER/weewx.conf.2* /home/$WX_USER/docs \ - /home/$WX_USER/skins/WeeGreen/.git \ - /root/.cache /var/cache/apk/* /var/log/* /tmp/* && \ - find /home/$WX_USER/bin -name '*.pyc' -exec rm '{}' +; + chown $WX_USER $WX_ROOT && \ + chown -R $WX_USER $WX_ROOT/skins && \ + rm -fr $WX_ROOT/skins/WeeGreen/.git && \ + find /usr/lib/python3* -name __pycache__ -exec rm -r '{}' +; + +COPY install-input.txt entrypoint.sh log.conf /home/$WX_USER +USER $WX_USER +RUN VENV=/home/$WX_USER/weewx-venv && \ + python3 -m venv $VENV --system-site-packages && \ + source $VENV/bin/activate && \ + python3 -m pip install weewx && \ + $VENV/bin/weectl station create < /home/$WX_USER/install-input.txt && \ + cat /home/$WX_USER/log.conf >> $WX_ROOT/weewx.conf && \ + curl -sLo /tmp/weewx-airlink.zip \ + https://github.com/chaunceygardiner/weewx-airlink/releases/download/v$AIRLINK_VERSION/weewx-airlink-$AIRLINK_VERSION.zip && \ + echo "$AIRLINK_SHA /tmp/weewx-airlink.zip" >> /tmp/checksums && \ + sha256sum -c /tmp/checksums && \ + $VENV/bin/weectl extension install /tmp/weewx-airlink.zip --yes && \ + rm -fr /home/$WX_USER/.cache && \ + find $VENV -name __pycache__ -exec rm -r '{}' +; -COPY entrypoint.sh /usr/local/bin -ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] +USER root +ENTRYPOINT ["/home/weewx/entrypoint.sh"] diff --git a/images/weewx/README.md b/images/weewx/README.md index b460a35e..dc4d229d 100644 --- a/images/weewx/README.md +++ b/images/weewx/README.md @@ -59,7 +59,6 @@ definition, or (even easier) under Kubernetes deploy the | WEBCAM_URL | (generic) | Suggest http://www.wunderground.com/webcams//1/show.html | | WEEK_START | 6 | day of week to start weekly data (0 = Mon) | | WX_USER | weewx | run-as username | -| XTIDE_LOCATION | unset | xtide setting, see [index](http://tides.mobilegeographics.com/) | You can volume-mount a different skin to a subdirectory of /home/weewx/skins if you prefer one that isn't already included. @@ -101,11 +100,6 @@ mode to access the weather-station device(s). Example [docker-compose.yml](https://github.com/instantlinux/docker-tools/blob/main/images/weewx/docker-compose.yml), [helm chart](https://github.com/instantlinux/docker-tools/tree/main/images/weewx/helm) and [kubernetes.yaml](https://github.com/instantlinux/docker-tools/blob/main/images/weewx/kubernetes.yaml) files are included here. See the Makefile in [k8s](https://github.com/instantlinux/docker-tools/blob/main/k8s/Makefile) to launch with kubernetes. -Tide info for US locations is generated by a library called -[xtide](http://www.flaterco.com/xtide/); there's no binary package for it in Alpine Linux -so a somewhat complicated set of commands is included here to package -it from source within Dockerfile. - Sadly, forecasts are no longer supported. It was once possible to integrate weather-service forecasts with the observational data collected and uploaded by this software. The online API was @@ -113,6 +107,11 @@ discontinued in a September 2018 decision by IBM after the company acquired Weather Underground. Also, the weewx-forecast module never got updated from 3.3.2 to support python3. +Tide info for US locations can be generated by a library called +[xtide](http://www.flaterco.com/xtide/); there's no binary package for it in Alpine Linux +so it has to be built from source within Dockerfile. Support for this +was lost in 2018 when the forecasting UI quit working. + Output logging from weewx is a bit of a mess: when running in foreground, a lot of verbose clutter appears on stdout; the real logs go to syslog and there's no configuration method to diff --git a/images/weewx/entrypoint.sh b/images/weewx/entrypoint.sh index c28afe31..71acd549 100755 --- a/images/weewx/entrypoint.sh +++ b/images/weewx/entrypoint.sh @@ -6,24 +6,27 @@ WUNDER_API_KEY=$(cat /run/secrets/weewx-wunderground-apikey) SSHKEY=weewx-rsync-sshkey WX_GROUP=dialout HOMEDIR=/home/$WX_USER -PATH=$HOMEDIR/bin:$PATH +PATH=$HOMEDIR/weewx-venv/bin:$PATH if [ ! -f /etc/timezone ] && [ ! -z "$TZ" ]; then # At first startup, set timezone - cp /usr/share/zoneinfo/$TZ /etc/localtime + cat /usr/share/zoneinfo/$TZ > /etc/localtime echo $TZ >/etc/timezone fi -if [ ! -e $HOMEDIR/weewx.conf.bak ]; then +if [ ! -e $WX_ROOT/weewx.conf.bak ]; then if [ -z ${STATION_URL/ /} ]; then REGISTER_OPT=false else REGISTER_OPT=true fi # Edit distributed weewx.conf settings after adding driver for STATION_TYPE - sed -i -e "s+-/var/log/messages+$SYSLOG_DEST+" /etc/rsyslog.conf - wee_config --reconfigure --driver=weewx.drivers.$( - echo $STATION_TYPE | tr [:upper:] [:lower:]) --no-prompt + cp /etc/rsyslog.conf /tmp + sed -e "s+-/var/log/messages+$SYSLOG_DEST+" \ + -e 's/^.*imklog/# disabled ("imklog/' \ + /tmp/rsyslog.conf >/etc/rsyslog.conf + su $WX_USER -c "weectl station reconfigure --driver=weewx.drivers.$( + echo $STATION_TYPE | tr [:upper:] [:lower:]) --no-prompt" sed --in-place=.bak -e "s/location = DESC/location = \"$LOCATION\"/" \ -e "s/altitude = 0, foot/altitude = $ALTITUDE/" \ -e "s/archive_interval =.*/archive_interval = $LOGGING_INTERVAL/" \ @@ -39,7 +42,6 @@ if [ ! -e $HOMEDIR/weewx.conf.bak ]; then -e "s/ station =.*/ station = $STATION_ID/" \ -e "s+#station_url =.*+station_url = $STATION_URL+" \ -e "s/password = replace_me$/password = $WUNDER_PASS # Und/" \ - -e "s/location = \"INSERT_LOCATION_HERE /location = \"$XTIDE_LOCATION\" # \"/" \ -e "s/lid =/#lid =/" \ -e "s/foid =/#foid =/" \ -e "s/api_key = INSERT_WU_API_KEY_HERE/api_key = $WUNDER_API_KEY/" \ @@ -53,8 +55,8 @@ if [ ! -e $HOMEDIR/weewx.conf.bak ]; then -e "s/server = replace_me/server = $RSYNC_HOST/" \ -e "s/user = replace_me/user = $RSYNC_USER/" \ -e "s:path = replace_me:path = $RSYNC_DEST:" \ - $HOMEDIR/weewx.conf - if [ -e $HOMEDIR/skins/WeeGreen/skin.conf ]; then + $WX_ROOT/weewx.conf + if [ -e $WX_ROOT/skins/WeeGreen/skin.conf ]; then sed -i -e "s/ID=[A-Z0-9]$/ID=$STATION_ID/" \ -e "s/computerType =.*/computerType = $COMPUTER_TYPE/" \ -e "s/modelNumber =.*/modelNumber = $STATION_MODEL/" \ @@ -62,34 +64,34 @@ if [ ! -e $HOMEDIR/weewx.conf.bak ]; then -e "s/[#]*optionalAccessories = .*/optionalAccessories = $OPTIONAL_ACCESSORIES/" \ -e "s/siteOperator =.*/siteOperator = $OPERATOR/" \ -e "s+webcamLink = .*+webcamLink = $WEBCAM_URL+" \ - $HOMEDIR/skins/WeeGreen/skin.conf + $WX_ROOT/skins/WeeGreen/skin.conf fi if [ "$AIRLINK_HOST" != "" ]; then sed -i -e "s/hostname = airlink$/hostname = $AIRLINK_HOST/" \ - $HOMEDIR/weewx.conf + $WX_ROOT/weewx.conf else - sed -i "/[[Sensor1]]/{n;s/.*/ enable = false/}" $HOMEDIR/weewx.conf + sed -i "/[[Sensor1]]/{n;s/.*/ enable = false/}" $WX_ROOT/weewx.conf fi if [ $SKIN != Season ]; then sed -i \ - "/skin = Season/,/enable = true/c skin = Seasons\n enable = false" $HOMEDIR/weewx.conf + "/skin = Season/,/enable = true/c skin = Seasons\n enable = false" $WX_ROOT/weewx.conf sed -i \ - "/skin = Standard/,/enable = false/c skin = $SKIN\n enable = true" $HOMEDIR/weewx.conf + "/skin = Standard/,/enable = false/c skin = $SKIN\n enable = true" $WX_ROOT/weewx.conf fi # Change the 5th "enable = false" which is Wunderground StdRESTful toggle awk '/enable = false/{c++;if(c==5){sub("enable = false","enable = true");c=0}}1' \ - $HOMEDIR/weewx.conf > $HOMEDIR/weewx.conf.new - mv $HOMEDIR/weewx.conf $HOMEDIR/weewx.conf.awk - mv $HOMEDIR/weewx.conf.new $HOMEDIR/weewx.conf + $WX_ROOT/weewx.conf > $WX_ROOT/weewx.conf.new + mv $WX_ROOT/weewx.conf $WX_ROOT/weewx.conf.awk + mv $WX_ROOT/weewx.conf.new $WX_ROOT/weewx.conf # At first startup, set configs from environment - wee_device --set-interval=$(( $LOGGING_INTERVAL / 60 )) - wee_device --set-rain-year-start=$RAIN_YEAR_START - wee_device --set-tz-code=$TZ_CODE + su $WX_USER -c \ + "weectl device --set-interval=$(( $LOGGING_INTERVAL / 60 )) && + weectl device --set-rain-year-start=$RAIN_YEAR_START && + weectl device --set-tz-code=$TZ_CODE" fi -sed -i -e 's/^.*imklog/# disabled ("imklog/' /etc/rsyslog.conf TZ=UTC rsyslogd cp /run/secrets/$SSHKEY /run/$SSHKEY && chmod 400 /run/$SSHKEY @@ -114,11 +116,11 @@ EOF cat /tmp/sshkey >> $HOMEDIR/.ssh/known_hosts && rm /tmp/sshkey fi -chown -R $WX_USER $HOMEDIR $HTML_ROOT /run/$SSHKEY +chown -R $WX_USER $HTML_ROOT /run/$SSHKEY # Docker 18.02 changes group to root at launch -chgrp $WX_GROUP /dev/ttyUSB0 +#chgrp $WX_GROUP /dev/ttyUSB0 set +e -su $WX_USER -c "PATH=$PATH weewxd $HOMEDIR/weewx.conf|grep -v LOOP:" +su $WX_USER -c "PATH=$PATH weewxd|grep -v LOOP:" # Failure: attempt restart only every 2 minutes sleep 120 exit 1 diff --git a/images/weewx/helm/Chart.yaml b/images/weewx/helm/Chart.yaml index 9a57497d..d2bc3ecd 100644 --- a/images/weewx/helm/Chart.yaml +++ b/images/weewx/helm/Chart.yaml @@ -6,7 +6,7 @@ sources: - https://github.com/instantlinux/docker-tools - https://github.com/weewx/weewx/ type: application -version: 0.1.6 +version: 0.1.7 appVersion: "5.0.2" dependencies: - name: chartlib diff --git a/images/weewx/install-input.txt b/images/weewx/install-input.txt index 0d40ddb5..d45bb7c0 100644 --- a/images/weewx/install-input.txt +++ b/images/weewx/install-input.txt @@ -4,6 +4,7 @@ DESC 90.0 n us -5 +6 serial /dev/ttyUSB0 +n diff --git a/images/weewx/log.conf b/images/weewx/log.conf new file mode 100644 index 00000000..d11f193d --- /dev/null +++ b/images/weewx/log.conf @@ -0,0 +1,4 @@ +# Section added by Dockerfile +[Logging] + [[root]] + handlers = console, diff --git a/images/weewx/requirements.txt b/images/weewx/requirements.txt index 6e156832..640e3d44 100644 --- a/images/weewx/requirements.txt +++ b/images/weewx/requirements.txt @@ -1,9 +1,2 @@ -ephem==3.7.7.1 -# These are alpine packages, we just use latest -CT3 -mysqlclient -pillow -pyserial -PyUSB requests six diff --git a/k8s/helm/restic/Chart.yaml b/k8s/helm/restic/Chart.yaml index d7cb4f82..9d11a5a7 100644 --- a/k8s/helm/restic/Chart.yaml +++ b/k8s/helm/restic/Chart.yaml @@ -6,10 +6,10 @@ sources: - https://github.com/instantlinux/docker-tools - https://github.com/restic/restic type: application -version: 0.1.10 +version: 0.1.11 # Remember to update restic== in values.yaml as releases are published; # the values.yaml file is not able to reference .Chart.appVersion -appVersion: "0.16.4-r4" +appVersion: "0.16.4-r5" dependencies: - name: chartlib version: 0.1.8 diff --git a/k8s/helm/restic/values.yaml b/k8s/helm/restic/values.yaml index 12894cb6..d979d403 100644 --- a/k8s/helm/restic/values.yaml +++ b/k8s/helm/restic/values.yaml @@ -16,7 +16,7 @@ deployment: mkdir -p /var/log/week && tail -f -n 0 /var/log/restic.log env: # Edit the version in Chart.yaml to keep consistent - app_version: 0.16.4-r4 + app_version: 0.16.4-r5 env: /etc/profile tz: UTC nodeSelector: diff --git a/k8s/helm/vaultwarden/values.yaml b/k8s/helm/vaultwarden/values.yaml index 98327537..57e923db 100644 --- a/k8s/helm/vaultwarden/values.yaml +++ b/k8s/helm/vaultwarden/values.yaml @@ -6,6 +6,7 @@ deployment: - containerPort: 80 - containerPort: 3012 env: + domain: https://vault.example.com emergency_access_allowed: "true" invitation_expiration_hours: 36 invitations_allowed: "false"