├── .ci ├── Dockerfile.alpine └── Dockerfile.debian ├── .gitignore ├── .gitlab-ci.yml ├── README.md ├── example-18.06.4.sh ├── example-libremesh_17.06.sh ├── example-libremesh_master.sh ├── example-snapshot.sh └── meta /.ci/Dockerfile.alpine: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | RUN apk update && \ 4 | apk add alpine-sdk \ 5 | bash \ 6 | bzip2 \ 7 | coreutils \ 8 | curl \ 9 | file \ 10 | findutils \ 11 | gawk \ 12 | gnupg \ 13 | grep \ 14 | linux-headers \ 15 | ncurses-dev \ 16 | outils-signify \ 17 | perl \ 18 | python2 \ 19 | python3 \ 20 | rsync \ 21 | rsync \ 22 | unzip \ 23 | wget \ 24 | xz \ 25 | zlib-dev 26 | 27 | RUN adduser -h /home/build -s /bin/bash build -D 28 | COPY --chown=build:build ./meta /home/build/openwrt/ 29 | RUN chown build:build /home/build/openwrt/ 30 | 31 | USER build 32 | ENV HOME /home/build 33 | WORKDIR /home/build/openwrt/ 34 | -------------------------------------------------------------------------------- /.ci/Dockerfile.debian: -------------------------------------------------------------------------------- 1 | FROM debian:latest 2 | 3 | MAINTAINER Paul Spooren 4 | 5 | RUN apt-get update -qq &&\ 6 | apt-get install -y \ 7 | build-essential \ 8 | curl \ 9 | file \ 10 | gawk \ 11 | gettext \ 12 | git \ 13 | libncurses5-dev \ 14 | libssl-dev \ 15 | python2.7 \ 16 | python3 \ 17 | rsync \ 18 | signify-openbsd \ 19 | subversion \ 20 | swig \ 21 | unzip \ 22 | wget \ 23 | zlib1g-dev \ 24 | && apt-get -y autoremove && apt-get clean 25 | 26 | RUN useradd -c "OpenWrt Builder" -m -d /home/build -s /bin/bash build 27 | COPY --chown=build:build ./meta /home/build/openwrt/ 28 | RUN chown build:build /home/build/openwrt/ 29 | 30 | USER build 31 | ENV HOME /home/build 32 | WORKDIR /home/build/openwrt/ 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | gpg/ 3 | imagebuilder/ 4 | usign/ 5 | .meta_setup 6 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | variables: 2 | DEBUG: 1 3 | 4 | build: 5 | image: docker:latest 6 | stage: build 7 | services: 8 | - docker:dind 9 | before_script: 10 | - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY 11 | script: 12 | - docker build --pull -t "$CI_REGISTRY_IMAGE:alpine$CI_COMMIT_REF_SLUG" -f ".ci/Dockerfile.alpine" . 13 | - docker build --pull -t "$CI_REGISTRY_IMAGE:debian$CI_COMMIT_REF_SLUG" -f ".ci/Dockerfile.debian" . 14 | - docker push "$CI_REGISTRY_IMAGE" 15 | 16 | test-examples: 17 | image: "$CI_REGISTRY_IMAGE:alpine$CI_COMMIT_REF_SLUG" 18 | stage: test 19 | script: 20 | - | 21 | for example in $(ls example-*.sh); do 22 | bash "$example" 23 | done 24 | 25 | test-alpine-1806: 26 | image: "$CI_REGISTRY_IMAGE:alpine$CI_COMMIT_REF_SLUG" 27 | stage: test 28 | variables: 29 | VERSION: "18.06.4" 30 | TARGET: "ar71xx/generic" 31 | PROFILE: "archer-c7-v4" 32 | script: 33 | - bash ./meta info 34 | - bash ./meta package_list 35 | - bash ./meta image 36 | - ls ./bin/openwrt/releases/$VERSION/targets/$TARGET/*sysupgrade.bin 37 | 38 | test-alpine-snapshot: 39 | image: "$CI_REGISTRY_IMAGE:alpine$CI_COMMIT_REF_SLUG" 40 | stage: test 41 | variables: 42 | TARGET: "ath79/generic" 43 | PROFILE: "tplink_archer-c7-v1" 44 | script: 45 | - bash ./meta info 46 | - bash ./meta package_list 47 | - bash ./meta image 48 | - ls ./bin/openwrt/snapshots/targets/$TARGET/*sysupgrade.bin 49 | 50 | test-debian-snapshot: 51 | image: "$CI_REGISTRY_IMAGE:debian$CI_COMMIT_REF_SLUG" 52 | stage: test 53 | variables: 54 | TARGET: "ath79/generic" 55 | PROFILE: "tplink_archer-c7-v1" 56 | script: 57 | - bash ./meta info 58 | - bash ./meta package_list 59 | - bash ./meta image 60 | - ls ./bin/openwrt/snapshots/targets/$TARGET/*sysupgrade.bin 61 | 62 | deploy: 63 | image: docker:latest 64 | only: 65 | - master 66 | stage: deploy 67 | services: 68 | - docker:dind 69 | before_script: 70 | - docker login -u "$DOCKER_USER" -p "$DOCKER_PASS" 71 | script: 72 | - docker build --pull -t "aparcar/openwrt-metabuilder:alpine" -f ".ci/Dockerfile.alpine" . 73 | - docker build --pull -t "aparcar/openwrt-metabuilder:debian" -f ".ci/Dockerfile.debian" . 74 | - docker tag "aparcar/openwrt-metabuilder:debian" "aparcar/openwrt-metabuilder:latest" 75 | - docker push "aparcar/openwrt-metabuilder" 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This code is no longer maintaned (tho likely works). It was initially created to be used by [ASU](https://github.com/aparcar/asu/) which however switched to a full Python implementation. 2 | 3 | # meta ImageBuilder 4 | 5 | Instead of downloading (and updating) ImageBuilders manually, this script does 6 | all the work. Automatically download ImageBuilder and create desired image. 7 | Extra variables like `$PACKAGES` are forwarded to the ImageBuilder make call. 8 | 9 | ## Usage 10 | 11 | Build `ar71xx/generic/tl-wr710n-v2.1` with latest (17.01.4) release: 12 | 13 | PROFILE="tl-wr710n-v2.1" TARGET="ar71xx/generic" ./meta 14 | 15 | Build latest snapshot of the same target/profile combo (both work): 16 | 17 | PROFILE="tl-wr710n-v2.1" RELEASE=snapshots TARGET="ar71xx/generic" ./meta 18 | 19 | ### Custom repositories 20 | 21 | To support other distributions like LibreMesh which is based on OpenWrt but 22 | which use additional repositories, it is possible to replace the 23 | `repositories.conf` with a custom version. 24 | 25 | You may setup extra repositories exporting the following variable: 26 | 27 | export REPOS="""src/gz reboot_core http://downloads.openwrt.org/releases/{{ ib_version }}/targets/{{ target }}/packages 28 | src/gz reboot_base http://downloads.openwrt.org/releases/{{ ib_version }}/packages/{{ pkg_arch }}/base 29 | src/gz reboot_luci http://downloads.openwrt.org/releases/{{ ib_version }}/packages/{{ pkg_arch }}/luci 30 | src/gz reboot_packages http://downloads.openwrt.org/releases/{{ ib_version }}/packages/{{ pkg_arch }}/packages 31 | src/gz reboot_telephony http://downloads.openwrt.org/releases/{{ ib_version }}/packages/{{ pkg_arch }}/telephony 32 | src imagebuilder file:packages 33 | src/gz libremesh http://repo.libremesh.org/releases/{{ version }}/packages/{{ pkg_arch }}/libremesh 34 | src/gz libremap http://repo.libremesh.org/releases/{{ version }}/packages/{{ pkg_arch }}/libremap 35 | src/gz limeui http://repo.libremesh.org/releases/{{ version }}/packages/{{ pkg_arch }}/limeui 36 | src/gz lm_routing http://repo.libremesh.org/releases/{{ version }}/packages/{{ pkg_arch }}/routing 37 | src/gz lm_profiles http://repo.libremesh.org/network-profiles/""" 38 | 39 | The following variables are automatically replaced: 40 | 41 | * `{{ version }}` Custom version 42 | * `{{ ib_version }}` OpenWrt ImageBuilder version 43 | * `{{ pkg_arch }}` Automatically determined package architecture 44 | * `{{ target }}` 45 | -------------------------------------------------------------------------------- /example-18.06.4.sh: -------------------------------------------------------------------------------- 1 | export DISTRO="openwrt" 2 | export VERSION="18.06.4" 3 | export TARGET="ar71xx/generic" 4 | export PROFILE="tl-wdr4300-v1" 5 | export PACKAGES="tmux htop" 6 | 7 | ./meta image 8 | -------------------------------------------------------------------------------- /example-libremesh_17.06.sh: -------------------------------------------------------------------------------- 1 | export VERSION="17.06" 2 | export IB_VERSION="17.01.6" 3 | export DISTRO="lime" 4 | export TARGET="ar71xx/generic" 5 | export PROFILE="tl-wdr3600-v1" 6 | export PACKAGES="lime-system lime-proto-wan lime-hwd-openwrt-wan lime-debug smonit lime-proto-bmx6 bmx6-auto-gw-mode luci lime-docs lime-docs-minimal luci-mod-admin-full lime-map-agent lime-proto-batadv lime-proto-anygw dnsmasq-lease-share dnsmasq-distributed-hosts lime-webui lime-hwd-ground-routing -dnsmasq -luci-app-firewall -luci-proto-ppp -luci" 7 | export REPOS="""src/gz reboot_core http://downloads.openwrt.org/releases/{{ ib_version }}/targets/{{ target }}/packages 8 | src/gz reboot_base http://downloads.openwrt.org/releases/{{ ib_version }}/packages/{{ pkg_arch }}/base 9 | src/gz reboot_luci http://downloads.openwrt.org/releases/{{ ib_version }}/packages/{{ pkg_arch }}/luci 10 | src/gz reboot_packages http://downloads.openwrt.org/releases/{{ ib_version }}/packages/{{ pkg_arch }}/packages 11 | src/gz reboot_routing http://downloads.openwrt.org/releases/{{ ib_version }}/packages/{{ pkg_arch }}/routing 12 | src/gz reboot_telephony http://downloads.openwrt.org/releases/{{ ib_version }}/packages/{{ pkg_arch }}/telephony 13 | src imagebuilder file:packages 14 | src/gz libremesh_v1706 http://downloads.libremesh.org/releases/{{ version }}/packages/{{ pkg_arch }}/libremesh/ 15 | src/gz libremap http://downloads.libremesh.org/releases/{{ version }}/packages/{{ pkg_arch }}/libremap/ 16 | src/gz lm_profiles http://chef.libremesh.org/network-profiles/""" 17 | 18 | ./meta image 19 | -------------------------------------------------------------------------------- /example-libremesh_master.sh: -------------------------------------------------------------------------------- 1 | export VERSION="master" 2 | export IB_VERSION="18.06.6" 3 | export DISTRO="lime" 4 | export TARGET="ar71xx/generic" 5 | export PROFILE="tl-wdr3600-v1" 6 | export PACKAGES="lime-system lime-proto-babeld lime-proto-batadv lime-proto-anygw lime-hwd-openwrt-wan shared-state-babeld_hosts shared-state-bat_hosts shared-state-nodes_and_links check-date-http lime-app lime-docs-minimal lime-docs lime-hwd-ground-routing lime-debug -dnsmasq -firewall -odhcpd-ipv6only -ppp" 7 | export REPOS="""src/gz v18066_core http://downloads.openwrt.org/releases/{{ ib_version }}/targets/{{ target }}/packages 8 | src/gz v18066_base http://downloads.openwrt.org/releases/{{ ib_version }}/packages/{{ pkg_arch }}/base 9 | src/gz v18066_luci http://downloads.openwrt.org/releases/{{ ib_version }}/packages/{{ pkg_arch }}/luci 10 | src/gz v18066_packages http://downloads.openwrt.org/releases/{{ ib_version }}/packages/{{ pkg_arch }}/packages 11 | src/gz v18066_routing http://downloads.openwrt.org/releases/{{ ib_version }}/packages/{{ pkg_arch }}/routing 12 | src/gz v18066_telephony http://downloads.openwrt.org/releases/{{ ib_version }}/packages/{{ pkg_arch }}/telephony 13 | src imagebuilder file:packages 14 | src/gz libremesh_master http://snapshots.libremesh.org/packages/ 15 | src/gz libremap http://downloads.libremesh.org/releases/18.06.1/packages/{{ pkg_arch }}/libremap/ 16 | src/gz lm_profiles http://chef.libremesh.org/network-profiles/""" 17 | 18 | ./meta image 19 | -------------------------------------------------------------------------------- /example-snapshot.sh: -------------------------------------------------------------------------------- 1 | export DISTRO="openwrt" 2 | export VERSION="snapshot" 3 | export TARGET="ath79/generic" 4 | export PROFILE="etactica_eg200" 5 | export PACKAGES="tmux htop" 6 | 7 | ./meta image 8 | -------------------------------------------------------------------------------- /meta: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # based on https://github.com/openwrt/packages/blob/master/.travis_do.sh 4 | 5 | set -e 6 | 7 | [ -n "$DEBUG" ] && set -x && env 8 | 9 | ROOT_DIR="$PWD" # where the script is 10 | IB="imagebuilder" # search sha256sums for this string to find imagebuilder 11 | BUILD_KEY="${BUILD_KEY:-$ROOT_DIR/key-build}" 12 | DISTRO="${DISTRO:-openwrt}" # the folder where to store created files 13 | VERSION="${VERSION:-snapshot}" # default version 14 | IB_VERSION="${IB_VERSION:-$VERSION}" # ImabeBuilder version if different to distro version 15 | FILE_HOST="${FILE_HOST:-downloads.openwrt.org}" # download imagebuilders 16 | [ "$IB_VERSION" != "snapshot" ] && { 17 | VERSION_PATH="releases/$IB_VERSION" 18 | } || { 19 | VERSION_PATH="snapshots" 20 | } 21 | TARGET_PATH="$VERSION_PATH/targets/$TARGET" 22 | IB_DIR="$ROOT_DIR/imagebuilder/$DISTRO/$TARGET_PATH" # where to store imagebuilders 23 | BIN_DIR="${BIN_DIR:-$ROOT_DIR/bin/$DISTRO/$TARGET_PATH}" # where to store created images 24 | 25 | mkdir -p "$ROOT_DIR/gpg" 26 | chmod 700 "$ROOT_DIR/gpg" 27 | export GNUPGHOME="$ROOT_DIR/gpg" 28 | 29 | # parse the sha256sums file to determine the ImageBuilder name 30 | get_ib_archive_name() { 31 | if [ -e "$IB_DIR/sha256sums" ] ; then 32 | grep -- "$IB" "$IB_DIR/sha256sums" | awk '{print $2}' | sed -e "s/*//g" 33 | else 34 | false 35 | fi 36 | } 37 | 38 | # return the architecture of the ImageBuilder based on .config contents 39 | get_ib_arch() { 40 | [ -d "$IB_DIR" ] && { 41 | (cd "$IB_DIR" && 42 | grep CONFIG_TARGET_ARCH_PACKAGES .config | cut -d= -f2 | tr -d \" 43 | ) 44 | } || echo "unknown" 45 | } 46 | 47 | meta_setup() { 48 | # LEDE Build System (LEDE GnuPG key for unattended build jobs) 49 | curl 'https://git.openwrt.org/?p=keyring.git;a=blob_plain;f=gpg/626471F1.asc' | gpg --import \ 50 | && echo '54CC74307A2C6DC9CE618269CD84BCED626471F1:6:' | gpg --import-ownertrust 51 | 52 | # PGP key for 19.07 release builds 53 | curl 'https://git.openwrt.org/?p=keyring.git;a=blob_plain;f=gpg/2074BE7A.asc' | gpg --import \ 54 | && echo 'D9C6901F45C9B86858687DFF28A39BC32074BE7A:6:' | gpg --import-ownertrust 55 | 56 | # LEDE Release Builder (17.01 "Reboot" Signing Key) 57 | curl 'https://git.openwrt.org/?p=keyring.git;a=blob_plain;f=gpg/D52BBB6B.asc' | gpg --import \ 58 | && echo 'B09BE781AE8A0CD4702FDCD3833C6010D52BBB6B:6:' | gpg --import-ownertrust 59 | 60 | # OpenWrt Release Builder (18.06 Signing Key) 61 | curl 'https://git.openwrt.org/?p=keyring.git;a=blob_plain;f=gpg/17E1CE16.asc' | gpg --import \ 62 | && echo '6768C55E79B032D77A28DA5F0F20257417E1CE16:6:' | gpg --import-ownertrust 63 | 64 | # OpenWrt Release Builder (18.06 Signing Key v2) 65 | curl 'https://git.openwrt.org/?p=keyring.git;a=blob_plain;f=gpg/15807931.asc' | gpg --import \ 66 | && echo 'AD0507363D2BCE9C9E36CEC4FBCB78F015807931:6:' | gpg --import-ownertrust 67 | 68 | # LEDE Build System (LEDE usign key for unattended build jobs) 69 | curl 'https://git.openwrt.org/?p=keyring.git;a=blob_plain;f=usign/b5043e70f9a75cde' --create-dirs \ 70 | -o ./usign/b5043e70f9a75cde 71 | 72 | # Public usign key for unattended snapshot builds 73 | curl 'https://git.openwrt.org/?p=keyring.git;a=blob_plain;f=usign/b5043e70f9a75cde' --create-dirs \ 74 | -o ./usign/b5043e70f9a75cde 75 | 76 | # Public usign key for 18.06 release builds 77 | curl 'https://git.openwrt.org/?p=keyring.git;a=blob_plain;f=usign/1035ac73cc4e59e3' --create-dirs \ 78 | -o ./usign/1035ac73cc4e59e3 79 | 80 | # Public usign key for 19.07 release builds 81 | curl 'https://git.openwrt.org/?p=keyring.git;a=blob_plain;f=usign/f94b9dd6febac963' --create-dirs \ 82 | -o ./usign/f94b9dd6febac963 83 | 84 | touch "$ROOT_DIR/.meta_setup" 85 | } 86 | 87 | download() { 88 | mkdir -p "$IB_DIR" 89 | cd "$IB_DIR" 90 | 91 | echo "download checksums and signature" 92 | curl "https://$FILE_HOST/$TARGET_PATH/sha256sums" -sS -o sha256sums 93 | curl "https://$FILE_HOST/$TARGET_PATH/sha256sums.asc" -fs -o sha256sums.asc || true 94 | curl "https://$FILE_HOST/$TARGET_PATH/sha256sums.sig" -fs -o sha256sums.sig || true 95 | 96 | if [ ! -f sha256sums.asc ] && [ ! -f sha256sums.sig ]; then 97 | die "Missing sha256sums signature files" 98 | fi 99 | 100 | echo "verifying sha256sums signature" 101 | [ ! -f sha256sums.asc ] || gpg --with-fingerprint --verify sha256sums.asc sha256sums 102 | 103 | if [ -f sha256sums.sig ]; then 104 | if hash signify-openbsd 2>/dev/null; then 105 | SIGNIFY_BIN=signify-openbsd # debian 106 | else 107 | SIGNIFY_BIN=signify # alpine 108 | fi 109 | VERIFIED= 110 | for KEY in "$ROOT_DIR"/usign/*; do 111 | echo "Trying $KEY..." 112 | if "$SIGNIFY_BIN" -V -q -p "$KEY" -x sha256sums.sig -m sha256sums; then 113 | echo "...verified" 114 | VERIFIED=1 115 | break 116 | fi 117 | done 118 | if [ -z "$VERIFIED" ]; then 119 | die "Could not verify usign signature" 120 | fi 121 | fi 122 | 123 | echo "verified sha256sums signature." 124 | if ! grep -- "$IB" sha256sums > sha256sums.small ; then 125 | die "can not find $IB file in sha256sums. Is \$IB out of date?" 126 | fi 127 | 128 | touch sha256sums.current 129 | # if missing, outdated or invalid, download again 130 | if [ "$(cat sha256sums.small)" != "$(cat sha256sums.current)" ] ; then 131 | local ib_archive_name 132 | ib_archive_name="$(get_ib_archive_name)" 133 | echo "sha256 doesn't match or ImageBuilder file wasn't downloaded yet." 134 | echo "remove outdated ImageBuilder files" 135 | find . ! -name 'sha256sums.*' -delete 136 | echo "download ImageBuilder" 137 | rsync -av "$FILE_HOST::downloads/$TARGET_PATH/$ib_archive_name" . || exit 1 138 | tar Jxf "$IB_DIR/$ib_archive_name" --strip=1 --overwrite 139 | # add Makefile which support package_list and manifest 140 | # also modify Makefile based on DISTRO and VERSION 141 | # if REPOS is defiend, add them 142 | [ -n "$REPOS" ] && custom_repos 143 | 144 | # check again and fail here if the file is still bad 145 | echo "Checking sha256sum a second time" 146 | if ! sha256sum -c ./sha256sums.small ; then 147 | die "ImageBuilder can not be verified!" 148 | fi 149 | mv sha256sums.small sha256sums.current 150 | [ -n "$KEEP_IB_TAR" ] || rm -rf "$IB_DIR/$ib_archive_name" 151 | 152 | # apply patches from patches folder 153 | [ -d "$ROOT_DIR/patches/" ] && ( 154 | for patch_file in $(find $ROOT_DIR/patches/ -type f); do 155 | patch -p1 < "$patch_file" 156 | done 157 | ) 158 | 159 | # link files folder if it exists 160 | [ -d "$ROOT_DIR/files/" ] && ( 161 | ln -s "$ROOT_DIR/files/" ./files 162 | ) 163 | 164 | # run scripts from script folder 165 | [ -d "$ROOT_DIR/scripts/" ] && ( 166 | for script_file in $(find $ROOT_DIR/scripts/ -type f); do 167 | bash "$script_file" 168 | done 169 | ) 170 | fi 171 | 172 | # copy BUILD_KEY to imagebuilder folder to sign images 173 | [ -e "$BUILD_KEY" ] && ln -sf "$BUILD_KEY" "$IB_DIR/key-build" 174 | [ -e "$BUILD_KEY.ucert" ] && ln -sf "$BUILD_KEY.ucert" "$IB_DIR/key-build.ucert" 175 | 176 | echo "ImageBuilder is up-to-date" 177 | } 178 | 179 | custom_repos() { 180 | # ability to add custom repositories 181 | echo "$REPOS" > "$IB_DIR/repositories.conf" 182 | sed -i \ 183 | -e "s/{{ pkg_arch }}/$(get_ib_arch)/" \ 184 | -e "s#{{ target }}#$TARGET#" \ 185 | -e "s/{{ ib_version }}/${IB_VERSION:-$VERSION}/" \ 186 | -e "s/{{ version }}/$VERSION/" \ 187 | "$IB_DIR/repositories.conf" 188 | } 189 | 190 | die() { 191 | echo $1 192 | exit 1 193 | } 194 | 195 | # setup this meta script if not already done 196 | [ ! -e "$ROOT_DIR/.meta_setup" ] && meta_setup 197 | 198 | # check if required vars a given 199 | [ -n "$TARGET" ] || die "missing \$TARGET" 200 | 201 | # check if local state is up to date 202 | [ -n "$NO_DOWNLOAD" ] || download 1>&2 203 | 204 | # will stop here if command is download 205 | [ "$1" != "download" ] || exit 0 206 | 207 | # run `make image` and pass variables 208 | (cd "$IB_DIR" && 209 | make "$1" \ 210 | PROFILE="$PROFILE" \ 211 | PACKAGES="$PACKAGES" \ 212 | BIN_DIR="$BIN_DIR" \ 213 | DISABLED_SERVICES="$DISABLED_SERVICES" \ 214 | EXTRA_IMAGE_NAME="$EXTRA_IMAGE_NAME" \ 215 | FILES="$FILES" 216 | ) 217 | --------------------------------------------------------------------------------