├── .docker ├── config.json └── daemon.json ├── .dockerignore ├── .github └── workflows │ └── debian.yml ├── .gitignore ├── Dockerfile.amd64 ├── Dockerfile.arm32v7 ├── Dockerfile.arm64v8 ├── Dockerfile.multi ├── LICENSE ├── README.md ├── easyepg.minimal ├── init └── root ├── easyepg.cron ├── easyepg.process ├── easyepg.update ├── entrypoint ├── packages.cleanup └── packages.install /.docker/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "experimental": "enabled" 3 | } 4 | -------------------------------------------------------------------------------- /.docker/daemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "experimental": true 3 | } 4 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !root/* 3 | -------------------------------------------------------------------------------- /.github/workflows/debian.yml: -------------------------------------------------------------------------------- 1 | name: Debian 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: 6 | - master 7 | schedule: 8 | - cron: '0 0 * * *' 9 | env: 10 | DEBIAN_FRONTEND: noninteractive 11 | TEMPORARY_DIRECTORY: /home/runner/work/_temp 12 | jobs: 13 | preparation: 14 | name: Preparation 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Create environment 18 | run: | 19 | echo "export DOCKER_TAG=\"${GITHUB_SHA}-$(date +'%Y%m%d-%H%M%S')\"" >> ./vars 20 | - name: Persist environment 21 | uses: actions/upload-artifact@v1 22 | with: 23 | name: environment 24 | path: ./vars 25 | amd64: 26 | name: Process amd64 27 | runs-on: ubuntu-latest 28 | needs: [preparation] 29 | steps: 30 | - name: Checkout repository 31 | uses: actions/checkout@v1 32 | - name: Fetch environment 33 | uses: actions/download-artifact@v1 34 | with: 35 | name: environment 36 | - name: Configure system 37 | run: | 38 | # update packages & install requirements 39 | sudo apt-get -qy update 40 | sudo apt-get -qy install moreutils 41 | 42 | # enable Dockers experimental features 43 | if [[ -z "${DOCKER_CONFIG}" ]]; then 44 | export DOCKER_CONFIG="${TEMPORARY_DIRECTORY}/docker.$(date +%s)" 45 | mkdir -p ${DOCKER_CONFIG} 46 | touch ${DOCKER_CONFIG}/config.json 47 | fi 48 | 49 | sudo sh -c "jq -s 'add' ${DOCKER_CONFIG}/config.json ./.docker/config.json | sponge ${DOCKER_CONFIG}/config.json" 50 | sudo sh -c "jq . ./.docker/daemon.json | sponge /etc/docker/daemon.json" 51 | sudo service docker restart 52 | - name: Build image 53 | run: | 54 | source ./environment/vars 55 | 56 | docker build --compress --no-cache --force-rm --squash -t qoopido/easyepg.minimal:${DOCKER_TAG}-amd64 -f Dockerfile.amd64 . 57 | docker save qoopido/easyepg.minimal:${DOCKER_TAG}-amd64 > ./amd64 58 | - name: Persist artifact 59 | uses: actions/upload-artifact@v1 60 | with: 61 | name: images 62 | path: ./amd64 63 | arm32v7: 64 | name: Process arm32v7 65 | runs-on: ubuntu-latest 66 | needs: [preparation] 67 | steps: 68 | - name: Checkout repository 69 | uses: actions/checkout@v1 70 | - name: Fetch environment 71 | uses: actions/download-artifact@v1 72 | with: 73 | name: environment 74 | - name: Configure system 75 | run: | 76 | # update packages & install requirements 77 | sudo apt-get -qy update 78 | sudo apt-get -qy install qemu-user-static binfmt-support moreutils 79 | 80 | # copy qemu for use via Dockerfile 81 | cp /usr/bin/qemu-arm-static ./root 82 | 83 | # enable Dockers experimental features 84 | if [[ -z "${DOCKER_CONFIG}" ]]; then 85 | export DOCKER_CONFIG="${TEMPORARY_DIRECTORY}/docker.$(date +%s)" 86 | mkdir -p ${DOCKER_CONFIG} 87 | touch ${DOCKER_CONFIG}/config.json 88 | fi 89 | 90 | sudo sh -c "jq -s 'add' ${DOCKER_CONFIG}/config.json ./.docker/config.json | sponge ${DOCKER_CONFIG}/config.json" 91 | sudo sh -c "jq . ./.docker/daemon.json | sponge /etc/docker/daemon.json" 92 | sudo service docker restart 93 | - name: Build image 94 | run: | 95 | source ./environment/vars 96 | 97 | docker build --compress --no-cache --force-rm --squash -t qoopido/easyepg.minimal:${DOCKER_TAG}-arm32v7 -f Dockerfile.arm32v7 . 98 | docker save qoopido/easyepg.minimal:${DOCKER_TAG}-arm32v7 > ./arm32v7 99 | - name: Persist artifact 100 | uses: actions/upload-artifact@v1 101 | with: 102 | name: images 103 | path: ./arm32v7 104 | arm64v8: 105 | name: Process arm64v8 106 | runs-on: ubuntu-latest 107 | needs: [preparation] 108 | steps: 109 | - name: Checkout repository 110 | uses: actions/checkout@v1 111 | - name: Fetch environment 112 | uses: actions/download-artifact@v1 113 | with: 114 | name: environment 115 | - name: Configure system 116 | run: | 117 | # update packages & install requirements 118 | sudo apt-get -qy update 119 | sudo apt-get -qy install qemu-user-static binfmt-support moreutils 120 | 121 | # copy qemu for use via Dockerfile 122 | cp /usr/bin/qemu-aarch64-static ./root 123 | 124 | # enable Dockers experimental features 125 | if [[ -z "${DOCKER_CONFIG}" ]]; then 126 | export DOCKER_CONFIG="${TEMPORARY_DIRECTORY}/docker.$(date +%s)" 127 | mkdir -p ${DOCKER_CONFIG} 128 | touch ${DOCKER_CONFIG}/config.json 129 | fi 130 | 131 | sudo sh -c "jq -s 'add' ${DOCKER_CONFIG}/config.json ./.docker/config.json | sponge ${DOCKER_CONFIG}/config.json" 132 | sudo sh -c "jq . ./.docker/daemon.json | sponge /etc/docker/daemon.json" 133 | sudo service docker restart 134 | - name: Build image 135 | run: | 136 | source ./environment/vars 137 | 138 | docker build --compress --no-cache --force-rm --squash -t qoopido/easyepg.minimal:${DOCKER_TAG}-arm64v8 -f Dockerfile.arm64v8 . 139 | docker save qoopido/easyepg.minimal:${DOCKER_TAG}-arm64v8 > ./arm64v8 140 | - name: Persist artifact 141 | uses: actions/upload-artifact@v1 142 | with: 143 | name: images 144 | path: ./arm64v8 145 | publish: 146 | name: Process multi-arch 147 | runs-on: ubuntu-latest 148 | needs: [preparation, amd64, arm32v7, arm64v8] 149 | steps: 150 | - name: Checkout repository 151 | uses: actions/checkout@v1 152 | - name: Fetch environment 153 | uses: actions/download-artifact@v1 154 | with: 155 | name: environment 156 | - name: Fetch artifacts 157 | uses: actions/download-artifact@v1 158 | with: 159 | name: images 160 | - name: Authenticate registry 161 | uses: azure/docker-login@v1 162 | with: 163 | username: ${{ secrets.DOCKER_HUB_USER }} 164 | password: ${{ secrets.DOCKER_HUB_TOKEN }} 165 | - name: Configure system 166 | run: | 167 | # update packages & install requirements 168 | sudo apt-get -qy update 169 | sudo apt-get -qy install moreutils 170 | 171 | # enable Dockers experimental features 172 | if [[ -z "${DOCKER_CONFIG}" ]]; then 173 | export DOCKER_CONFIG="${TEMPORARY_DIRECTORY}/docker.$(date +%s)" 174 | mkdir -p ${DOCKER_CONFIG} 175 | touch ${DOCKER_CONFIG}/config.json 176 | fi 177 | 178 | sudo sh -c "jq -s 'add' ${DOCKER_CONFIG}/config.json ./.docker/config.json | sponge ${DOCKER_CONFIG}/config.json" 179 | sudo sh -c "jq . ./.docker/daemon.json | sponge /etc/docker/daemon.json" 180 | sudo service docker restart 181 | - name: Import artifacts 182 | run: | 183 | docker load --input ./images/amd64 184 | docker load --input ./images/arm32v7 185 | docker load --input ./images/arm64v8 186 | - name: Push version to registry 187 | run: | 188 | source ./environment/vars 189 | 190 | for ARCH in amd64 arm32v7 arm64v8; do 191 | docker push qoopido/easyepg.minimal:${DOCKER_TAG}-${ARCH} 192 | done 193 | 194 | docker manifest create qoopido/easyepg.minimal:${DOCKER_TAG} qoopido/easyepg.minimal:${DOCKER_TAG}-amd64 qoopido/easyepg.minimal:${DOCKER_TAG}-arm32v7 qoopido/easyepg.minimal:${DOCKER_TAG}-arm64v8 195 | docker manifest annotate qoopido/easyepg.minimal:${DOCKER_TAG} qoopido/easyepg.minimal:${DOCKER_TAG}-arm32v7 --os linux --arch arm 196 | docker manifest annotate qoopido/easyepg.minimal:${DOCKER_TAG} qoopido/easyepg.minimal:${DOCKER_TAG}-arm64v8 --os linux --arch arm64 --variant armv8 197 | 198 | docker manifest push qoopido/easyepg.minimal:${DOCKER_TAG} --purge 199 | - name: Push latest to registry 200 | run: | 201 | source ./environment/vars 202 | 203 | for ARCH in amd64 arm32v7 arm64v8; do 204 | docker tag qoopido/easyepg.minimal:${DOCKER_TAG}-${ARCH} qoopido/easyepg.minimal:latest-${ARCH} 205 | docker push qoopido/easyepg.minimal:latest-${ARCH} 206 | done 207 | 208 | docker manifest create qoopido/easyepg.minimal:latest qoopido/easyepg.minimal:latest-amd64 qoopido/easyepg.minimal:latest-arm32v7 qoopido/easyepg.minimal:latest-arm64v8 209 | docker manifest annotate qoopido/easyepg.minimal:latest qoopido/easyepg.minimal:latest-arm32v7 --os linux --arch arm 210 | docker manifest annotate qoopido/easyepg.minimal:latest qoopido/easyepg.minimal:latest-arm64v8 --os linux --arch arm64 --variant armv8 211 | 212 | docker manifest push qoopido/easyepg.minimal:latest --purge 213 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | root/qemu-* 4 | -------------------------------------------------------------------------------- /Dockerfile.amd64: -------------------------------------------------------------------------------- 1 | FROM amd64/debian:buster-slim AS build 2 | 3 | LABEL maintainer="Dirk Lüth " \ 4 | org.label-schema.docker.dockerfile="/Dockerfile" \ 5 | org.label-schema.name="easyepg.minimal" 6 | 7 | ARG BUILD_DEPENDENCIES="build-essential cpanminus" 8 | ARG DEPENDENCIES="socat cron iproute2 nano procps phantomjs dialog curl file wget git libxml2-utils perl perl-doc jq php php-curl xml-twig-tools liblocal-lib-perl inetutils-ping zip unzip ca-certificates" 9 | 10 | ENV MODE="run" \ 11 | USER_ID="1099" \ 12 | GROUP_ID="1099" \ 13 | TIMEZONE="Europe/Berlin" \ 14 | FREQUENCY="0 2 * * *" \ 15 | UPDATE="yes" \ 16 | REPO="sunsettrack4" \ 17 | BRANCH="master" \ 18 | PACKAGES="" \ 19 | DEBIAN_FRONTEND="noninteractive" \ 20 | TERM=xterm \ 21 | LANGUAGE="en_US.UTF-8" \ 22 | LANG="en_US.UTF-8" \ 23 | LC_ALL="en_US.UTF-8" \ 24 | CURL_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt" \ 25 | CLEANUP="/tmp/* /var/tmp/* /var/log/* /var/lib/apt/lists/* /var/lib/{apt,dpkg,cache,log}/ /var/cache/apt/archives /usr/share/doc/ /usr/share/man/ /usr/share/locale/ /root/.cpan /root/.cpanm" 26 | 27 | COPY root/entrypoint /usr/local/sbin/entrypoint 28 | COPY root/easyepg.process /usr/local/bin/easyepg.process 29 | COPY root/easyepg.update /usr/local/bin/easyepg.update 30 | COPY root/packages.install /usr/local/sbin/packages.install 31 | COPY root/packages.cleanup /usr/local/sbin/packages.cleanup 32 | COPY root/easyepg.cron /etc/easyepg.cron 33 | 34 | RUN apt-get -qy update \ 35 | ### tweak some apt & dpkg settngs 36 | && echo "APT::Install-Recommends "0";" >> /etc/apt/apt.conf.d/docker-noinstall-recommends \ 37 | && echo "APT::Install-Suggests "0";" >> /etc/apt/apt.conf.d/docker-noinstall-suggests \ 38 | && echo "Dir::Cache "";" >> /etc/apt/apt.conf.d/docker-nocache \ 39 | && echo "Dir::Cache::archives "";" >> /etc/apt/apt.conf.d/docker-nocache \ 40 | && echo "path-exclude=/usr/share/locale/*" >> /etc/dpkg/dpkg.cfg.d/docker-nolocales \ 41 | && echo "path-exclude=/usr/share/man/*" >> /etc/dpkg/dpkg.cfg.d/docker-noman \ 42 | && echo "path-exclude=/usr/share/doc/*" >> /etc/dpkg/dpkg.cfg.d/docker-nodoc \ 43 | && echo "path-include=/usr/share/doc/*/copyright" >> /etc/dpkg/dpkg.cfg.d/docker-nodoc \ 44 | ### install basic packages 45 | && apt-get install -qy apt-utils locales tzdata \ 46 | ### limit locale to en_US.UTF-8 47 | && sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \ 48 | && locale-gen --purge en_US.UTF-8 \ 49 | && update-locale LANG=en_US.UTF-8 \ 50 | ### run dist-upgrade 51 | && apt-get dist-upgrade -qy \ 52 | ### install easyepg dependencies 53 | && apt-get install -qy ${BUILD_DEPENDENCIES} ${DEPENDENCIES} \ 54 | ### install cpan modules 55 | && cpan -T App:cpanminus \ 56 | && cpanm install -n utf8 \ 57 | && cpanm install -n JSON \ 58 | && cpanm install -n XML::Rules \ 59 | && cpanm install -n XML::DOM \ 60 | && cpanm install -n Data::Dumper \ 61 | && cpanm install -n Time::Piece \ 62 | && cpanm install -n Time::Seconds \ 63 | && cpanm install -n DateTime \ 64 | && cpanm install -n DateTime::Format::DateParse \ 65 | && cpanm install -n DateTime::Format::Strptime \ 66 | ### create necessary files/directories 67 | && mkdir -p /easyepg \ 68 | && touch /xmltv.sock \ 69 | ### alter permissions 70 | && chmod +x /usr/local/sbin/entrypoint \ 71 | && chmod +x /usr/local/bin/easyepg.process \ 72 | && chmod +x /usr/local/bin/easyepg.update \ 73 | && chmod +x /usr/local/sbin/packages.install \ 74 | && chmod +x /usr/local/sbin/packages.cleanup \ 75 | && chmod 644 /etc/easyepg.cron \ 76 | ### cleanup 77 | && apt-get remove --purge -qy ${BUILD_DEPENDENCIES} \ 78 | && /usr/local/sbin/packages.cleanup 79 | 80 | ENTRYPOINT [ "/usr/local/sbin/entrypoint" ] 81 | 82 | VOLUME /easyepg 83 | 84 | 85 | -------------------------------------------------------------------------------- /Dockerfile.arm32v7: -------------------------------------------------------------------------------- 1 | FROM arm32v7/debian:buster-slim AS build 2 | 3 | LABEL maintainer="Dirk Lüth " \ 4 | org.label-schema.docker.dockerfile="/Dockerfile" \ 5 | org.label-schema.name="easyepg.minimal" 6 | 7 | ARG BUILD_DEPENDENCIES="build-essential cpanminus" 8 | ARG DEPENDENCIES="socat cron iproute2 nano procps phantomjs dialog curl file wget git libxml2-utils perl perl-doc jq php php-curl xml-twig-tools liblocal-lib-perl inetutils-ping zip unzip ca-certificates" 9 | 10 | ENV MODE="run" \ 11 | USER_ID="1099" \ 12 | GROUP_ID="1099" \ 13 | TIMEZONE="Europe/Berlin" \ 14 | FREQUENCY="0 2 * * *" \ 15 | UPDATE="yes" \ 16 | REPO="sunsettrack4" \ 17 | BRANCH="master" \ 18 | PACKAGES="" \ 19 | DEBIAN_FRONTEND="noninteractive" \ 20 | TERM=xterm \ 21 | LANGUAGE="en_US.UTF-8" \ 22 | LANG="en_US.UTF-8" \ 23 | LC_ALL="en_US.UTF-8" \ 24 | CURL_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt" \ 25 | CLEANUP="/tmp/* /var/tmp/* /var/log/* /var/lib/apt/lists/* /var/lib/{apt,dpkg,cache,log}/ /var/cache/apt/archives /usr/share/doc/ /usr/share/man/ /usr/share/locale/ /root/.cpan /root/.cpanm" 26 | 27 | COPY root/qemu-arm-static /usr/bin/ 28 | COPY root/entrypoint /usr/local/sbin/entrypoint 29 | COPY root/easyepg.process /usr/local/bin/easyepg.process 30 | COPY root/easyepg.update /usr/local/bin/easyepg.update 31 | COPY root/packages.install /usr/local/sbin/packages.install 32 | COPY root/packages.cleanup /usr/local/sbin/packages.cleanup 33 | COPY root/easyepg.cron /etc/easyepg.cron 34 | 35 | RUN apt-get -qy update \ 36 | ### tweak some apt & dpkg settngs 37 | && echo "APT::Install-Recommends "0";" >> /etc/apt/apt.conf.d/docker-noinstall-recommends \ 38 | && echo "APT::Install-Suggests "0";" >> /etc/apt/apt.conf.d/docker-noinstall-suggests \ 39 | && echo "Dir::Cache "";" >> /etc/apt/apt.conf.d/docker-nocache \ 40 | && echo "Dir::Cache::archives "";" >> /etc/apt/apt.conf.d/docker-nocache \ 41 | && echo "path-exclude=/usr/share/locale/*" >> /etc/dpkg/dpkg.cfg.d/docker-nolocales \ 42 | && echo "path-exclude=/usr/share/man/*" >> /etc/dpkg/dpkg.cfg.d/docker-noman \ 43 | && echo "path-exclude=/usr/share/doc/*" >> /etc/dpkg/dpkg.cfg.d/docker-nodoc \ 44 | && echo "path-include=/usr/share/doc/*/copyright" >> /etc/dpkg/dpkg.cfg.d/docker-nodoc \ 45 | ### install basic packages 46 | && apt-get install -qy apt-utils locales tzdata \ 47 | ### limit locale to en_US.UTF-8 48 | && sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \ 49 | && locale-gen --purge en_US.UTF-8 \ 50 | && update-locale LANG=en_US.UTF-8 \ 51 | ### run dist-upgrade 52 | && apt-get dist-upgrade -qy \ 53 | ### install easyepg dependencies 54 | && apt-get install -qy ${BUILD_DEPENDENCIES} ${DEPENDENCIES} \ 55 | ### install cpan modules 56 | && cpan -T App:cpanminus \ 57 | && cpanm install -n utf8 \ 58 | && cpanm install -n JSON \ 59 | && cpanm install -n XML::Rules \ 60 | && cpanm install -n XML::DOM \ 61 | && cpanm install -n Data::Dumper \ 62 | && cpanm install -n Time::Piece \ 63 | && cpanm install -n Time::Seconds \ 64 | && cpanm install -n DateTime \ 65 | && cpanm install -n DateTime::Format::DateParse \ 66 | && cpanm install -n DateTime::Format::Strptime \ 67 | ### create necessary files/directories 68 | && mkdir -p /easyepg \ 69 | && touch /xmltv.sock \ 70 | ### alter permissions 71 | && chmod +x /usr/local/sbin/entrypoint \ 72 | && chmod +x /usr/local/bin/easyepg.process \ 73 | && chmod +x /usr/local/bin/easyepg.update \ 74 | && chmod +x /usr/local/sbin/packages.install \ 75 | && chmod +x /usr/local/sbin/packages.cleanup \ 76 | && chmod 644 /etc/easyepg.cron \ 77 | ### cleanup 78 | && apt-get remove --purge -qy ${BUILD_DEPENDENCIES} \ 79 | && /usr/local/sbin/packages.cleanup 80 | 81 | ENTRYPOINT [ "/usr/local/sbin/entrypoint" ] 82 | 83 | VOLUME /easyepg 84 | 85 | FROM build 86 | 87 | RUN rm -rf /usr/bin/qemu-* 88 | -------------------------------------------------------------------------------- /Dockerfile.arm64v8: -------------------------------------------------------------------------------- 1 | FROM arm64v8/debian:buster-slim AS build 2 | 3 | LABEL maintainer="Dirk Lüth " \ 4 | org.label-schema.docker.dockerfile="/Dockerfile" \ 5 | org.label-schema.name="easyepg.minimal" 6 | 7 | ARG BUILD_DEPENDENCIES="build-essential cpanminus" 8 | ARG DEPENDENCIES="socat cron iproute2 nano procps phantomjs dialog curl file wget git libxml2-utils perl perl-doc jq php php-curl xml-twig-tools liblocal-lib-perl inetutils-ping zip unzip ca-certificates" 9 | 10 | ENV MODE="run" \ 11 | USER_ID="1099" \ 12 | GROUP_ID="1099" \ 13 | TIMEZONE="Europe/Berlin" \ 14 | FREQUENCY="0 2 * * *" \ 15 | UPDATE="yes" \ 16 | REPO="sunsettrack4" \ 17 | BRANCH="master" \ 18 | PACKAGES="" \ 19 | DEBIAN_FRONTEND="noninteractive" \ 20 | TERM=xterm \ 21 | LANGUAGE="en_US.UTF-8" \ 22 | LANG="en_US.UTF-8" \ 23 | LC_ALL="en_US.UTF-8" \ 24 | CURL_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt" \ 25 | CLEANUP="/tmp/* /var/tmp/* /var/log/* /var/lib/apt/lists/* /var/lib/{apt,dpkg,cache,log}/ /var/cache/apt/archives /usr/share/doc/ /usr/share/man/ /usr/share/locale/ /root/.cpan /root/.cpanm" 26 | 27 | COPY root/qemu-aarch64-static /usr/bin/ 28 | COPY root/entrypoint /usr/local/sbin/entrypoint 29 | COPY root/easyepg.process /usr/local/bin/easyepg.process 30 | COPY root/easyepg.update /usr/local/bin/easyepg.update 31 | COPY root/packages.install /usr/local/sbin/packages.install 32 | COPY root/packages.cleanup /usr/local/sbin/packages.cleanup 33 | COPY root/easyepg.cron /etc/easyepg.cron 34 | 35 | RUN apt-get -qy update \ 36 | ### tweak some apt & dpkg settngs 37 | && echo "APT::Install-Recommends "0";" >> /etc/apt/apt.conf.d/docker-noinstall-recommends \ 38 | && echo "APT::Install-Suggests "0";" >> /etc/apt/apt.conf.d/docker-noinstall-suggests \ 39 | && echo "Dir::Cache "";" >> /etc/apt/apt.conf.d/docker-nocache \ 40 | && echo "Dir::Cache::archives "";" >> /etc/apt/apt.conf.d/docker-nocache \ 41 | && echo "path-exclude=/usr/share/locale/*" >> /etc/dpkg/dpkg.cfg.d/docker-nolocales \ 42 | && echo "path-exclude=/usr/share/man/*" >> /etc/dpkg/dpkg.cfg.d/docker-noman \ 43 | && echo "path-exclude=/usr/share/doc/*" >> /etc/dpkg/dpkg.cfg.d/docker-nodoc \ 44 | && echo "path-include=/usr/share/doc/*/copyright" >> /etc/dpkg/dpkg.cfg.d/docker-nodoc \ 45 | ### install basic packages 46 | && apt-get install -qy apt-utils locales tzdata \ 47 | ### limit locale to en_US.UTF-8 48 | && sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \ 49 | && locale-gen --purge en_US.UTF-8 \ 50 | && update-locale LANG=en_US.UTF-8 \ 51 | ### run dist-upgrade 52 | && apt-get dist-upgrade -qy \ 53 | ### install easyepg dependencies 54 | && apt-get install -qy ${BUILD_DEPENDENCIES} ${DEPENDENCIES} \ 55 | ### install cpan modules 56 | && cpan -T App:cpanminus \ 57 | && cpanm install -n utf8 \ 58 | && cpanm install -n JSON \ 59 | && cpanm install -n XML::Rules \ 60 | && cpanm install -n XML::DOM \ 61 | && cpanm install -n Data::Dumper \ 62 | && cpanm install -n Time::Piece \ 63 | && cpanm install -n Time::Seconds \ 64 | && cpanm install -n DateTime \ 65 | && cpanm install -n DateTime::Format::DateParse \ 66 | && cpanm install -n DateTime::Format::Strptime \ 67 | ### create necessary files/directories 68 | && mkdir -p /easyepg \ 69 | && touch /xmltv.sock \ 70 | ### alter permissions 71 | && chmod +x /usr/local/sbin/entrypoint \ 72 | && chmod +x /usr/local/bin/easyepg.process \ 73 | && chmod +x /usr/local/bin/easyepg.update \ 74 | && chmod +x /usr/local/sbin/packages.install \ 75 | && chmod +x /usr/local/sbin/packages.cleanup \ 76 | && chmod 644 /etc/easyepg.cron \ 77 | ### cleanup 78 | && apt-get remove --purge -qy ${BUILD_DEPENDENCIES} \ 79 | && /usr/local/sbin/packages.cleanup 80 | 81 | ENTRYPOINT [ "/usr/local/sbin/entrypoint" ] 82 | 83 | VOLUME /easyepg 84 | 85 | FROM build 86 | 87 | RUN rm -rf /usr/bin/qemu-* 88 | -------------------------------------------------------------------------------- /Dockerfile.multi: -------------------------------------------------------------------------------- 1 | FROM __BASE_ARCH__/debian:buster-slim AS build 2 | 3 | LABEL maintainer="Dirk Lüth " \ 4 | org.label-schema.docker.dockerfile="/Dockerfile" \ 5 | org.label-schema.name="easyepg.minimal" 6 | 7 | ARG BUILD_DEPENDENCIES="build-essential cpanminus" 8 | ARG DEPENDENCIES="socat cron iproute2 nano procps phantomjs dialog curl file wget git libxml2-utils perl perl-doc jq php php-curl xml-twig-tools liblocal-lib-perl inetutils-ping zip unzip ca-certificates" 9 | 10 | ENV MODE="run" \ 11 | USER_ID="1099" \ 12 | GROUP_ID="1099" \ 13 | TIMEZONE="Europe/Berlin" \ 14 | FREQUENCY="0 2 * * *" \ 15 | UPDATE="yes" \ 16 | REPO="sunsettrack4" \ 17 | BRANCH="master" \ 18 | PACKAGES="" \ 19 | DEBIAN_FRONTEND="noninteractive" \ 20 | TERM=xterm \ 21 | LANGUAGE="en_US.UTF-8" \ 22 | LANG="en_US.UTF-8" \ 23 | LC_ALL="en_US.UTF-8" \ 24 | CURL_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt" \ 25 | CLEANUP="/tmp/* /var/tmp/* /var/log/* /var/lib/apt/lists/* /var/lib/{apt,dpkg,cache,log}/ /var/cache/apt/archives /usr/share/doc/ /usr/share/man/ /usr/share/locale/ /root/.cpan /root/.cpanm" 26 | 27 | __CROSS_COPY root/qemu-__QEMU_ARCH__-static /usr/bin/ 28 | COPY root/entrypoint /usr/local/sbin/entrypoint 29 | COPY root/easyepg.process /usr/local/bin/easyepg.process 30 | COPY root/easyepg.update /usr/local/bin/easyepg.update 31 | COPY root/packages.install /usr/local/sbin/packages.install 32 | COPY root/packages.cleanup /usr/local/sbin/packages.cleanup 33 | COPY root/easyepg.cron /etc/easyepg.cron 34 | 35 | RUN apt-get -qy update \ 36 | ### tweak some apt & dpkg settngs 37 | && echo "APT::Install-Recommends "0";" >> /etc/apt/apt.conf.d/docker-noinstall-recommends \ 38 | && echo "APT::Install-Suggests "0";" >> /etc/apt/apt.conf.d/docker-noinstall-suggests \ 39 | && echo "Dir::Cache "";" >> /etc/apt/apt.conf.d/docker-nocache \ 40 | && echo "Dir::Cache::archives "";" >> /etc/apt/apt.conf.d/docker-nocache \ 41 | && echo "path-exclude=/usr/share/locale/*" >> /etc/dpkg/dpkg.cfg.d/docker-nolocales \ 42 | && echo "path-exclude=/usr/share/man/*" >> /etc/dpkg/dpkg.cfg.d/docker-noman \ 43 | && echo "path-exclude=/usr/share/doc/*" >> /etc/dpkg/dpkg.cfg.d/docker-nodoc \ 44 | && echo "path-include=/usr/share/doc/*/copyright" >> /etc/dpkg/dpkg.cfg.d/docker-nodoc \ 45 | ### install basic packages 46 | && apt-get install -qy apt-utils locales tzdata \ 47 | ### limit locale to en_US.UTF-8 48 | && sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \ 49 | && locale-gen --purge en_US.UTF-8 \ 50 | && update-locale LANG=en_US.UTF-8 \ 51 | ### run dist-upgrade 52 | && apt-get dist-upgrade -qy \ 53 | ### install easyepg dependencies 54 | && apt-get install -qy ${BUILD_DEPENDENCIES} ${DEPENDENCIES} \ 55 | ### install cpan modules 56 | && cpan -T App:cpanminus \ 57 | && cpanm install -n utf8 \ 58 | && cpanm install -n JSON \ 59 | && cpanm install -n XML::Rules \ 60 | && cpanm install -n XML::DOM \ 61 | && cpanm install -n Data::Dumper \ 62 | && cpanm install -n Time::Piece \ 63 | && cpanm install -n Time::Seconds \ 64 | && cpanm install -n DateTime \ 65 | && cpanm install -n DateTime::Format::DateParse \ 66 | && cpanm install -n DateTime::Format::Strptime \ 67 | ### create necessary files/directories 68 | && mkdir -p /easyepg \ 69 | && touch /xmltv.sock \ 70 | ### alter permissions 71 | && chmod +x /usr/local/sbin/entrypoint \ 72 | && chmod +x /usr/local/bin/easyepg.process \ 73 | && chmod +x /usr/local/bin/easyepg.update \ 74 | && chmod +x /usr/local/sbin/packages.install \ 75 | && chmod +x /usr/local/sbin/packages.cleanup \ 76 | && chmod 644 /etc/easyepg.cron \ 77 | ### cleanup 78 | && apt-get remove --purge -qy ${BUILD_DEPENDENCIES} \ 79 | && /usr/local/sbin/packages.cleanup 80 | 81 | ENTRYPOINT [ "/usr/local/sbin/entrypoint" ] 82 | 83 | VOLUME /easyepg 84 | 85 | __CROSS_FROM build 86 | 87 | __CROSS_RUN rm -rf /usr/bin/qemu-* 88 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Dirk Lüth 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![PayPal.Me donation](https://img.shields.io/static/v1?label=PayPal.Me&message=Donate&color=green&logo=paypal)](https://www.paypal.me/qoopido) 2 | ![Docker Pulls](https://img.shields.io/docker/pulls/qoopido/easyepg.minimal.svg) 3 | 4 | # easyepg.minimal 5 | A minimal docker container for running easyepg either on demand or permanently with built-in cronjob 6 | 7 | ## Manual installation via shell 8 | > This section is not for users with a GUI interface for docker on a NAS system like Synology, UnRaid or OpenMediaVault (see [here](#technical-info-for-docker-guis-eg-synology-unraid-openmediavault) for details) but for people having a dedicated host running TVheadend directly but wanting to run easyepg as docker on this host. 9 | 10 | ### Prerequisites 11 | You will need to have `docker` installed on your system and the user you want to run it needs to be in the `docker` group. 12 | 13 | ### Installation 14 | Switch to the user you want to run the container with and issue the following command to get everything up and running 15 | ``` 16 | sh -c "$(curl -s -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/dlueth/easyepg.minimal/master/init)" 17 | ``` 18 | 19 | > **Note:** The image is a multi-arch build providing variants for amd64, arm32v7 and arm64v8 - the correct variant for your architecture shouldTM be pulled automatically. 20 | 21 | > **Note:** If the init-script successfully detects a valid `xmltv.sock` it will default to "yes" and provide the correct path automatically. Otherwise it will default to "no". 22 | 23 | ### Initial setup 24 | Switch to the user you want to run the container with and start the admin container and enter it via 25 | ``` 26 | docker start easyepg.admin 27 | docker exec -ti -u easyepg -w /easyepg easyepg.admin /bin/bash ./epg.sh 28 | ``` 29 | 30 | to start easyepg's setup and configure it. When your setup is finished return to the shell and issue `exit` to leave the container followed by `docker stop easyepg.admin` to stop it. 31 | 32 | > **Note:** If you did run the init-script as root user the container will not have an `easyepg` user and you will have remove the `-u easyepg` from the line above. I do not recommend this for security though. 33 | 34 | ### Updating EPG XML-files 35 | 36 | #### Variant A: via Cronjob in the container 37 | Simply run the following command while logged in as the desired user 38 | ``` 39 | docker start easyepg.cron 40 | ``` 41 | 42 | There already is a crontab in the container that will run easyepg at 2:00am every night. 43 | 44 | #### Variant B: via Cronjob on the host 45 | > **Note:** Skip this section if you decided to go with Variant A (e.g. you are running the container on a NAS) 46 | 47 | Simply run the following command while logged in as the desired user 48 | ``` 49 | crontab -e 50 | ``` 51 | 52 | Append the following line to the file that should have been opened 53 | ``` 54 | 0 2 * * * docker start easyepg.run 55 | ``` 56 | 57 | If you did not set a path to `xmltv.sock` during installation you might need the following two lines in addition. 58 | ``` 59 | 0 4 * * * cat ~/easyepg/xml/[your file].xml | socat - UNIX-CONNECT:/home/hts/.hts/tvheadend/epggrab/xmltv.sock 60 | 10 4 * * * cat ~/easyepg/xml/[your file].xml | socat - UNIX-CONNECT:/home/hts/.hts/tvheadend/epggrab/xmltv.sock 61 | ``` 62 | Replace `[your file]` with the filename of your generated XML. 63 | 64 | Save and exit the file and you are done! 65 | 66 | ## Technical info for docker GUIs (e.g. Synology, UnRaid, OpenMediaVault) 67 | To learn how to manually start the container or about available parameters (you might need for your GUI used) see the following example: 68 | 69 | ``` 70 | docker run \ 71 | -d \ 72 | -e MODE="admin" \ 73 | -e USER_ID="1099" \ 74 | -e GROUP_ID="1099" \ 75 | -e TIMEZONE="Europe/Berlin" \ 76 | -e FREQUENCY="0 2 * * *" \ 77 | -e UPDATE="yes" \ 78 | -e REPO="sunsettrack4" \ 79 | -e BRANCH="master" \ 80 | -v {EASYEPG_STORAGE}:/easyepg \ 81 | -v {XML_STORAGE}:/easyepg/xml \ 82 | -v {XMLTV_SOCKET}:/xmltv.sock \ 83 | -v {XMLTV_DIRECTORY}:/xmltv \ 84 | --name=easyepg \ 85 | --restart unless-stopped \ 86 | --tmpfs /tmp \ 87 | --tmpfs /var/log \ 88 | qoopido/easyepg.minimal:latest 89 | ``` 90 | 91 | The available parameters in detail: 92 | 93 | | Parameter | Optional | Values/Type | Default | Description | 94 | | ---- | --- | --- | --- | --- | 95 | | `MODE` | yes | run, admin, cron | run | Mode to run the container in | 96 | | `USER_ID` | yes | [integer] | 1099 | UID to run easyepg as | 97 | | `GROUP_ID` | yes | [integer] | 1099 | GID to run easyepg as | 98 | | `TIMEZONE` | yes | [string] | Europe/Berlin | Timezone for the container | 99 | | `FREQUENCY` | yes | [string] | 0 2 * * * | Cron frequency (when run in MODE='cron') | 100 | | `UPDATE` | yes | yes, no | yes | Flag whether to update easyepg on container start | 101 | | `REPO` | yes | sunsettrack4, DeBaschdi | sunsettrack4 | The repo to update/install easyepg from | 102 | | `BRANCH` | yes | [string] | master | The branch to update/install easyepg from | 103 | 104 | Frequently used volumes: 105 | 106 | | Volume | Optional | Description | 107 | |-------------------| --- |---------------------------------------------------------| 108 | | `EASYEPG_STORAGE` | no | The directory to persist easyepg to | 109 | | `XML_STORAGE` | yes | The directory to store the finished XML files in | 110 | | `XMLTV_SOCKET` | yes | The socket to automatically write finished XMLs to | 111 | | `XMLTV_DIRECTORY` | yes | The directory to alternatively expect an `xmltv.sock` in | 112 | 113 | When passing volumes please replace the name including the surrounding curly brackets with existing absolute paths with correct permissions. 114 | 115 | If you decide to remove `XML_STORAGE` the finished XML files can be found in the `xml` subdirectory of `EASYEPG_STORAGE` instead. 116 | 117 | > **Note:** `XML_STORAGE` can, e.g., be used to directly write finished XMLs into the directory you pass into a separately running TVheadend docker container. 118 | 119 | ## Crontab syntax 120 | ``` 121 | ┌───────────── minute (0 - 59) 122 | │ ┌───────────── hour (0 - 23) 123 | │ │ ┌───────────── day of month (1 - 31) 124 | │ │ │ ┌───────────── month (1 - 12) 125 | │ │ │ │ ┌───────────── day of week (0 - 6) (Sunday to Saturday; 126 | │ │ │ │ │ 7 is also Sunday on some systems) 127 | │ │ │ │ │ 128 | │ │ │ │ │ 129 | * * * * * /command/to/execute 130 | ``` 131 | -------------------------------------------------------------------------------- /easyepg.minimal: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while getopts ":t:m:n:" options; do 4 | case "${options}" in 5 | t) 6 | TAG="${OPTARG}" 7 | ;; 8 | n) 9 | TAGNEW="${OPTARG}" 10 | ;; 11 | m) 12 | MODE="${OPTARG}" 13 | ;; 14 | esac 15 | done 16 | 17 | if [[ -z "${TAG}" ]]; then 18 | TAG="latest" 19 | fi 20 | 21 | if [[ -z "${TAGNEW}" ]]; then 22 | TAGNEW="latest" 23 | fi 24 | 25 | COLOR_NOTICE='\e[95m' 26 | COLOR_ERROR='\e[91m' 27 | COLOR_NONE='\e[39m' 28 | 29 | logDefault() 30 | { 31 | echo -e "$1" 32 | } 33 | 34 | logNotice() 35 | { 36 | echo -e "${COLOR_NOTICE}$1${COLOR_NONE}" 37 | } 38 | 39 | logError() 40 | { 41 | echo -e "${COLOR_ERROR}$1${COLOR_NONE}" 1>&2 42 | } 43 | 44 | getLatestRelease() { 45 | curl --silent "https://api.github.com/repos/$1/releases/latest" | \ 46 | grep '"tag_name":' | \ 47 | sed -E 's/.*"([^"]+)".*/\1/' 48 | } 49 | 50 | build() 51 | { 52 | logNotice "Getting latest release of \"multiarch/qemu-user-static\"" 53 | 54 | LATEST=$(getLatestRelease multiarch/qemu-user-static) 55 | 56 | logDefault "> Latest release of \"multiarch/qemu-user-static\" is ${LATEST}" 57 | 58 | logNotice "Fetching \"multiarch/qemu-user-static\"" 59 | 60 | for ARCH in aarch64 arm x86_64; do 61 | curl -sL https://github.com/multiarch/qemu-user-static/releases/download/${LATEST}/x86_64_qemu-${ARCH}-static.tar.gz | tar -C ./root -xf - 62 | 63 | logDefault "> fetched ${ARCH}" 64 | done 65 | 66 | logNotice "Creating Dockerfiles" 67 | 68 | for DOCKER_ARCH in amd64 arm32v7 arm64v8; do 69 | case ${DOCKER_ARCH} in 70 | amd64) 71 | QEMU_ARCH="x86_64" 72 | ;; 73 | arm32v7) 74 | QEMU_ARCH="arm" 75 | ;; 76 | arm64v8) 77 | QEMU_ARCH="aarch64" 78 | ;; 79 | esac 80 | 81 | cp Dockerfile.multi Dockerfile.${DOCKER_ARCH} 82 | 83 | sed -i "" "s|__BASE_ARCH__|${DOCKER_ARCH}|g" Dockerfile.${DOCKER_ARCH} 84 | sed -i "" "s|__QEMU_ARCH__|${QEMU_ARCH}|g" Dockerfile.${DOCKER_ARCH} 85 | 86 | if [[ ${DOCKER_ARCH} == 'amd64' ]]; then 87 | sed -i "" "/__CROSS_/d" Dockerfile.${DOCKER_ARCH} 88 | else 89 | sed -i "" "s/__CROSS_//g" Dockerfile.${DOCKER_ARCH} 90 | fi 91 | 92 | logDefault "> created Dockerfile.${DOCKER_ARCH}" 93 | done 94 | 95 | logNotice "Building images" 96 | 97 | for DOCKER_ARCH in amd64 arm32v7 arm64v8; do 98 | docker build --compress --no-cache --force-rm --squash -t qoopido/easyepg.minimal:${TAG}-${DOCKER_ARCH} -f Dockerfile.${DOCKER_ARCH} . 99 | 100 | logDefault "> built qoopido/easyepg.minimal:${TAG}-${DOCKER_ARCH}" 101 | done 102 | } 103 | 104 | tag() { 105 | for DOCKER_ARCH in amd64 arm32v7 arm64v8; do 106 | docker tag qoopido/easyepg.minimal:${TAG}-${DOCKER_ARCH} qoopido/easyepg.minimal:${TAGNEW}-${DOCKER_ARCH} 107 | 108 | logDefault "> tagged qoopido/easyepg.minimal:${TAG}-${DOCKER_ARCH} as qoopido/easyepg.minimal:${TAGNEW}-${DOCKER_ARCH}" 109 | done 110 | } 111 | 112 | publish() { 113 | logNotice "Publishing images" 114 | 115 | for DOCKER_ARCH in amd64 arm32v7 arm64v8; do 116 | docker push qoopido/easyepg.minimal:${TAG}-${DOCKER_ARCH} 117 | 118 | logDefault "> pushed qoopido/easyepg.minimal:${TAG}-${DOCKER_ARCH}" 119 | done 120 | 121 | logNotice "Processing manifest" 122 | 123 | docker manifest create qoopido/easyepg.minimal:${TAG} qoopido/easyepg.minimal:${TAG}-amd64 qoopido/easyepg.minimal:${TAG}-arm32v7 qoopido/easyepg.minimal:${TAG}-arm64v8 124 | 125 | logDefault "> created manifest" 126 | 127 | docker manifest annotate qoopido/easyepg.minimal:${TAG} qoopido/easyepg.minimal:${TAG}-arm32v7 --os linux --arch arm 128 | docker manifest annotate qoopido/easyepg.minimal:${TAG} qoopido/easyepg.minimal:${TAG}-arm64v8 --os linux --arch arm64 --variant armv8 129 | 130 | logDefault "> added annotations" 131 | 132 | docker manifest push qoopido/easyepg.minimal:${TAG} --purge 133 | 134 | logDefault "> pushed manifest" 135 | } 136 | 137 | case "${MODE}" in 138 | build) 139 | build 140 | ;; 141 | tag) 142 | tag 143 | ;; 144 | publish) 145 | publish 146 | ;; 147 | *) 148 | logError "Usage: easyepg.minimal -m [build|tag|publish]" 149 | logError " -t: tag for the image" 150 | logError " => used by [build|tag|publish], defaults to \"latest\"" 151 | logError " -n: new tag for the image" 152 | logError " => used by [tag], defaults to \"latest\"" 153 | exit 1 154 | ;; 155 | esac 156 | 157 | exit 158 | -------------------------------------------------------------------------------- /init: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -f 3 | 4 | log() 5 | { 6 | echo "${1}" 7 | } 8 | 9 | log "Checking requirements..." 10 | if [ -n $(which docker) ]; then 11 | log "> docker => installed" 12 | else 13 | log "> docker => not installed" 14 | 15 | exit 1 16 | fi 17 | 18 | log "Preparing..." 19 | 20 | NO_CPU_LIMIT=$(docker info 2>&1 | grep -E "No cpu cfs (quota|period)") 21 | 22 | GROUP_ID=$(id -g `whoami`) 23 | USER_ID=$(id -u `whoami`) 24 | 25 | DEFAULT_VOLUME=$(cd ~ && pwd -P)"/easyepg" 26 | DEFAULT_SOCKET=$(find ~/ -type s -name "xmltv.sock" 2> /dev/null) 27 | DEFAULT_TIMEZONE="Europe/Berlin" 28 | DEFAULT_FREQUENCY="0 2 * * *" 29 | DEFAULT_UPDATE="no" 30 | DEFAULT_REPO="sunsettrack4" 31 | DEFAULT_BRANCH="master" 32 | DEFAULT_TAG="latest" 33 | DEFAULT_PACKAGES="" 34 | 35 | if [ -z "${NO_CPU_LIMIT}" ]; then 36 | DEFAULT_CPU_LIMIT=$(docker info 2>&1 | grep -E "^ *CPUs: " | sed "s/^ *CPUs: //") 37 | fi 38 | 39 | read -p "Storage location [${DEFAULT_VOLUME}]: " VOLUME 40 | while true; do 41 | if [ -n "${DEFAULT_SOCKET}" ]; then 42 | read -p "Use existing local xmltv.sock [Y/n]: " yn 43 | 44 | case ${yn} in 45 | [Nn]*) 46 | break 47 | ;; 48 | *) 49 | read -p "Socket location [${DEFAULT_SOCKET}]: " SOCKET 50 | break 51 | ;; 52 | esac 53 | else 54 | read -p "Use custom location/directory for xmltv.sock [y/N]: " yn 55 | 56 | case ${yn} in 57 | [Yy]*) 58 | read -p "Socket location [${DEFAULT_SOCKET}]: " SOCKET 59 | break 60 | ;; 61 | *) 62 | break 63 | ;; 64 | esac 65 | fi 66 | done 67 | 68 | if [ -n "${DEFAULT_CPU_LIMIT}" ]; then 69 | while true; do 70 | read -p "Limit CPU usage [y/N]: " yn 71 | 72 | case ${yn} in 73 | [Yy]*) 74 | read -p "CPU limit [${DEFAULT_CPU_LIMIT}]: " CPU_LIMIT 75 | break 76 | ;; 77 | *) 78 | break 79 | ;; 80 | esac 81 | done 82 | fi 83 | read -p "Timezone [${DEFAULT_TIMEZONE}]: " TIMEZONE 84 | read -p "Cronjob frequency [${DEFAULT_FREQUENCY}]: " FREQUENCY 85 | 86 | read -p "Easyepg git repo [${DEFAULT_REPO}]: " REPO 87 | read -p "Easyepg git branch [${DEFAULT_BRANCH}]: " BRANCH 88 | 89 | if [ -z "${BRANCH}" ] || [ "${BRANCH}" = "master" ]; then 90 | DEFAULT_UPDATE="yes" 91 | 92 | while true; do 93 | read -p "Autoupdate easyepg [Y/n]: " yn 94 | 95 | case ${yn} in 96 | [Nn]*) 97 | UPDATE="no" 98 | break 99 | ;; 100 | *) 101 | UPDATE="yes" 102 | break 103 | ;; 104 | esac 105 | done 106 | fi 107 | 108 | read -p "Easyepg.minimal docker tag [${DEFAULT_TAG}]: " TAG 109 | read -p "Additional OS packages [${DEFAULT_PACKAGES}]: " PACKAGES 110 | 111 | if [ -z "${VOLUME}" ]; then 112 | VOLUME=${DEFAULT_VOLUME} 113 | fi 114 | 115 | if [ -z "${SOCKET}" ]; then 116 | SOCKET=${DEFAULT_SOCKET} 117 | fi 118 | 119 | if [ -z "${CPU_LIMIT}" ]; then 120 | CPU_LIMIT=${DEFAULT_CPU_LIMIT} 121 | fi 122 | 123 | if [ -z "${TIMEZONE}" ]; then 124 | TIMEZONE=${DEFAULT_TIMEZONE} 125 | fi 126 | 127 | if [ -z "${FREQUENCY}" ]; then 128 | FREQUENCY=${DEFAULT_FREQUENCY} 129 | fi 130 | 131 | if [ -z "${UPDATE}" ]; then 132 | UPDATE=${DEFAULT_UPDATE} 133 | fi 134 | 135 | if [ -z "${REPO}" ]; then 136 | REPO=${DEFAULT_REPO} 137 | fi 138 | 139 | if [ -z "${BRANCH}" ]; then 140 | BRANCH=${DEFAULT_BRANCH} 141 | fi 142 | 143 | if [ -z "${TAG}" ]; then 144 | TAG=${DEFAULT_TAG} 145 | fi 146 | 147 | if [ -z "${PACKAGES}" ]; then 148 | PACKAGES=${DEFAULT_PACKAGES} 149 | fi 150 | 151 | if [ ! -d "${VOLUME}" ]; then 152 | mkdir -p ${VOLUME} 153 | fi 154 | 155 | if [ -z "${VOLUME}" ] || [ ! -d "${VOLUME}" ] || [ ! -w "${VOLUME}" ]; then 156 | log "Storage location incorrect" 157 | exit 1 158 | fi 159 | 160 | if [ ! -z "${SOCKET}" ]; then 161 | if [ ! -S "${SOCKET}" ] && [ ! -d "${SOCKET}" ]; then 162 | log "Socket location incorrect" 163 | exit 1 164 | fi 165 | fi 166 | 167 | # make paths absolute for docker 168 | VOLUME=$(cd ${VOLUME} && pwd -P) 169 | 170 | if [ ! -z "${SOCKET}" ]; then 171 | SOCKET=$(cd `dirname ${SOCKET}` && pwd -P)/$(basename ${SOCKET}) 172 | fi 173 | 174 | log "Stopping container..." 175 | docker ps --format "{{.Image}} {{.ID}}" | grep "qoopido/easyepg.minimal" | cut -d " " -f 2 | xargs -I {} docker stop {} > /dev/null 176 | 177 | log "Removing old container..." 178 | docker ps -a --format "{{.Image}} {{.ID}}" | grep "qoopido/easyepg.minimal" | cut -d " " -f 2 | xargs -I {} docker rm --force {} > /dev/null 179 | 180 | log "Removing old image..." 181 | docker images --format "{{.Repository}}:{{.Tag}}" | grep "qoopido/easyepg.minimal" | xargs -I {} docker rmi --force {} > /dev/null 182 | 183 | log "Pulling new image..." 184 | docker pull qoopido/easyepg.minimal:${TAG} 185 | 186 | log "Creating new container..." 187 | 188 | OPTIONS="--tmpfs /tmp --tmpfs /var/log -e USER_ID=\"${USER_ID}\" -e GROUP_ID=\"${GROUP_ID}\" -e TIMEZONE=\"${TIMEZONE}\" -e FREQUENCY=\"${FREQUENCY}\" -e UPDATE=\"${UPDATE}\" -e REPO=\"${REPO}\" -e BRANCH=\"${BRANCH}\" -e PACKAGES=\"${PACKAGES}\" -v ${VOLUME}:/easyepg" 189 | 190 | if [ -n "${SOCKET}" ]; then 191 | if [ -S "${SOCKET}" ]; then 192 | OPTIONS="${OPTIONS} -v ${SOCKET}:/xmltv.sock" 193 | fi 194 | 195 | if [ -d "${SOCKET}" ]; then 196 | OPTIONS="${OPTIONS} -v ${SOCKET}:/xmltv" 197 | fi 198 | fi 199 | 200 | if [ -n "${CPU_LIMIT}" ]; then 201 | OPTIONS="${OPTIONS} --cpus ${CPU_LIMIT}" 202 | fi 203 | 204 | sh -c "docker create -l easyepg.minimal --name=easyepg.admin -e MODE=\"admin\" ${OPTIONS} qoopido/easyepg.minimal:${TAG} 1> /dev/null" 205 | log "> easyepg.admin" 206 | 207 | sh -c "docker create -l easyepg.minimal --name=easyepg.run -e MODE=\"run\" ${OPTIONS} qoopido/easyepg.minimal:${TAG} 1> /dev/null" 208 | log "> easyepg.run" 209 | 210 | sh -c "docker create -l easyepg.minimal --name=easyepg.cron -e MODE=\"cron\" --restart unless-stopped ${OPTIONS} qoopido/easyepg.minimal:${TAG} 1> /dev/null" 211 | log "> easyepg.cron" 212 | 213 | log "Finished!" 214 | 215 | exit 216 | -------------------------------------------------------------------------------- /root/easyepg.cron: -------------------------------------------------------------------------------- 1 | ${FREQUENCY} su -s /bin/bash -c "TERM=xterm /bin/bash /usr/local/bin/easyepg.process" ${USERNAME} > /proc/1/fd/1 2> /proc/1/fd/2 2 | -------------------------------------------------------------------------------- /root/easyepg.process: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PWD=$(pwd) 4 | SOCKET="" 5 | 6 | if [[ -S /xmltv.sock ]]; then 7 | SOCKET="/xmltv.sock" 8 | fi 9 | 10 | if [[ -d /xmltv ]]; then 11 | SOCKET=$(find /xmltv -type s -name "xmltv.sock" 2> /dev/null) 12 | fi 13 | 14 | writeSocket() 15 | { 16 | FILES=$(find /easyepg/xml -type f -name "*.xml" -printf "%T@ %p\n" | sort -n | cut -d " " -f 2) 17 | 18 | while read -r FILE; do 19 | cat ${FILE} | socat - UNIX-CONNECT:${SOCKET} 20 | 21 | echo "> ${FILE}" 22 | done <<< "${FILES}" 23 | } 24 | 25 | if [[ "${MODE}" = "cron" ]] && [[ "${UPDATE}" = "yes" ]]; then 26 | echo "Updating easyepg" 27 | /usr/local/bin/easyepg.update 28 | fi 29 | 30 | chown -R ${USER_ID}:${GROUP_ID} /easyepg 31 | chown -R ${USER_ID}:${GROUP_ID} /tmp 32 | 33 | chmod -R 775 /easyepg 34 | chmod -R 777 /tmp 35 | 36 | echo "Cleaning up" 37 | rm -rf /easyepg/xml/* 38 | 39 | echo "Running easyepg" 40 | cd /easyepg && /bin/bash /easyepg/epg.sh 41 | 42 | if [[ ! -z "${SOCKET}" ]]; then 43 | echo "Writing to ${SOCKET}..." 44 | 45 | writeSocket 46 | sleep 300 47 | writeSocket 48 | fi 49 | 50 | cd ${PWD} 51 | -------------------------------------------------------------------------------- /root/easyepg.update: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PWD=$(pwd) 4 | 5 | rm -rf /easyepg/easyepg 6 | git clone https://github.com/${REPO}/easyepg.git /easyepg/easyepg 7 | 8 | if [[ "${BRANCH}" != "master" ]]; then 9 | cd /easyepg/easyepg 10 | git checkout ${BRANCH} 11 | fi 12 | 13 | cd /easyepg 14 | /bin/bash ./easyepg/update.sh 15 | cd / 16 | rm -rf /easyepg/easyepg 17 | 18 | cd ${PWD} 19 | 20 | -------------------------------------------------------------------------------- /root/entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -f 4 | 5 | USERNAME="easyepg" 6 | 7 | if [[ -z "${MODE}" ]]; then 8 | MODE="run" 9 | fi 10 | 11 | if [[ -z "${TIMEZONE}" ]]; then 12 | TIMEZONE="Europe/Berlin" 13 | fi 14 | 15 | if [[ -z "${GROUP_ID}" ]]; then 16 | GROUP_ID="1099" 17 | fi 18 | 19 | if [[ -z "${USER_ID}" ]]; then 20 | USER_ID="1099" 21 | fi 22 | 23 | if [[ -z "${FREQUENCY}" ]]; then 24 | FREQUENCY="0 2 * * *" 25 | fi 26 | 27 | if [[ -z "${UPDATE}" ]]; then 28 | UPDATE="yes" 29 | fi 30 | 31 | if [[ -z "${REPO}" ]]; then 32 | REPO="sunsettrack4" 33 | fi 34 | 35 | if [[ -z "${BRANCH}" ]]; then 36 | BRANCH="master" 37 | fi 38 | 39 | # handle persistance of environment 40 | # if [[ -f /easyepg/.env ]]; then 41 | # echo "> .env file exists" 42 | # 43 | # if [[ -s /easyepg/.env ]]; then 44 | # echo " > .env file not empty" 45 | # echo " > importing settings from .env" 46 | # source /easyepg/.env 47 | # else 48 | # echo " > .env file empty" 49 | # echo " > exporting settings to .env" 50 | # 51 | # cat /dev/null > /easyepg/.env 52 | # 53 | # echo "export USER_ID=\"${USER_ID}\"" >> /easyepg/.env 54 | # echo "export GROUP_ID=\"${GROUP_ID}\"" >> /easyepg/.env 55 | # echo "export MODE=\"${MODE}\"" >> /easyepg/.env 56 | # echo "export TIMEZONE=\"${TIMEZONE}\"" >> /easyepg/.env 57 | # echo "export FREQUENCY=\"${FREQUENCY}\"" >> /easyepg/.env 58 | # echo "export UPDATE=\"${UPDATE}\"" >> /easyepg/.env 59 | # echo "export REPO=\"${REPO}\"" >> /easyepg/.env 60 | # echo "export BRANCH=\"${BRANCH}\"" >> /easyepg/.env 61 | # echo "export PACKAGES=\"${PACKAGES}\"" >> /easyepg/.env 62 | # fi 63 | # else 64 | # echo "> .env file not found" 65 | # fi 66 | 67 | echo "> settings used" 68 | echo " > USER_ID: \"${USER_ID}\"" 69 | echo " > GROUP_ID: \"${GROUP_ID}\"" 70 | echo " > MODE: \"${MODE}\"" 71 | echo " > TIMEZONE: \"${TIMEZONE}\"" 72 | echo " > FREQUENCY: \"${FREQUENCY}\"" 73 | echo " > UPDATE: \"${UPDATE}\"" 74 | echo " > REPO: \"${REPO}\"" 75 | echo " > BRANCH: \"${BRANCH}\"" 76 | echo " > PACKAGES: \"${PACKAGES}\"" 77 | 78 | if [[ ! -f /easyepg/update.sh ]] || [[ "${UPDATE}" = "yes" ]]; then 79 | /usr/local/bin/easyepg.update 80 | fi 81 | 82 | ln -fs /usr/share/zoneinfo/${TIMEZONE} /etc/localtime 83 | dpkg-reconfigure -f noninteractive tzdata 84 | 85 | echo "${USERNAME}:x:${USER_ID}:${GROUP_ID}:${USERNAME}:/:/sbin/nologin" >> /etc/passwd 86 | echo "${USERNAME}:!::0:::::" >> /etc/shadow 87 | 88 | if ! getent group ${GROUP_ID}; then 89 | echo "${USERNAME}:x:${GROUP_ID}:" >> /etc/group 90 | fi 91 | 92 | chown -R ${USER_ID}:${GROUP_ID} /easyepg 93 | chown -R ${USER_ID}:${GROUP_ID} /tmp 94 | 95 | chmod -R 775 /easyepg 96 | chmod -R 777 /tmp 97 | 98 | if [[ ! -z "${PACKAGES}" ]]; then 99 | /usr/local/sbin/packages.install 100 | /usr/local/sbin/packages.cleanup 101 | fi 102 | 103 | case "${MODE}" in 104 | run) 105 | su -s /bin/bash -c "TERM=xterm /usr/local/bin/easyepg.process" ${USERNAME} 106 | ;; 107 | cron) 108 | sed -i "s|\${FREQUENCY}|${FREQUENCY}|" /etc/easyepg.cron 109 | sed -i "s|\${USERNAME}|${USERNAME}|" /etc/easyepg.cron 110 | crontab -u root /etc/easyepg.cron 111 | exec /usr/sbin/cron -f -l 0 112 | ;; 113 | *) 114 | exec tail -f /dev/null 115 | ;; 116 | esac 117 | -------------------------------------------------------------------------------- /root/packages.cleanup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PWD=$(pwd) 4 | 5 | apt-get -qy autoclean 6 | apt-get -qy clean 7 | apt-get -qy autoremove --purge 8 | rm -rf ${CLEANUP} 9 | 10 | cd ${PWD} 11 | -------------------------------------------------------------------------------- /root/packages.install: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PWD=$(pwd) 4 | 5 | apt-get -qy update 6 | apt-get install -qy ${PACKAGES} 7 | 8 | cd ${PWD} 9 | 10 | --------------------------------------------------------------------------------