diff --git a/.docker/Dockerfile.amd64 b/.docker/Dockerfile.amd64 deleted file mode 100644 index 4107d2feae..0000000000 --- a/.docker/Dockerfile.amd64 +++ /dev/null @@ -1,8 +0,0 @@ -FROM archlinux -ENV GOPATH=/go -RUN pacman -Syyu --noconfirm go npm make git which && \ - mkdir /go -COPY . /starport -WORKDIR /starport -RUN PATH=$PATH:/go/bin && \ - make diff --git a/.docker/Dockerfile.arm64 b/.docker/Dockerfile.arm64 deleted file mode 100644 index 307a82264b..0000000000 --- a/.docker/Dockerfile.arm64 +++ /dev/null @@ -1,8 +0,0 @@ -FROM faddat/sos-base -ENV GOPATH=/go -RUN pacman -Syyu --noconfirm go npm make which && \ - mkdir /go -COPY . /starport -WORKDIR /starport -RUN PATH=$PATH:/go/bin && \ - make diff --git a/.github/workflows/devices.yml b/.github/workflows/devices.yml index 2266720a6a..585da49e54 100644 --- a/.github/workflows/devices.yml +++ b/.github/workflows/devices.yml @@ -8,60 +8,9 @@ name: Rpi on: [push, pull_request] jobs: - amd64: - name: amd64 docker - runs-on: ubuntu-latest - steps: - - name: checkout - uses: actions/checkout@v2 - - - name: Set up QEMU - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes - - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v1 - with: - version: latest - - - name: Login to DockerHub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push - run: docker buildx build --tag ${{ secrets.DOCKERHUB_USERNAME }}/starport --file .docker/Dockerfile.amd64 --platform linux/amd64 --cache-from ${{ secrets.DOCKERHUB_USERNAME }}/starport:amd64cache --cache-to ${{ secrets.DOCKERHUB_USERNAME }}/starport:amd64cache --push --progress tty . - - arm64: - name: arm64 docker - runs-on: ubuntu-latest - steps: - - name: checkout - uses: actions/checkout@v2 - - - name: Set up QEMU - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes - - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v1 - with: - version: latest - - - name: Login to DockerHub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push - run: docker buildx build --tag ${{ secrets.DOCKERHUB_USERNAME }}/starport --file .docker/Dockerfile.arm64 --platform linux/arm64 --cache-from ${{ secrets.DOCKERHUB_USERNAME }}/starport:cache --cache-to ${{ secrets.DOCKERHUB_USERNAME }}/starport:cache --push --progress tty . - pi: name: Starport Pi runs-on: ubuntu-latest - needs: arm64 steps: - name: checkout uses: actions/checkout@v2 diff --git a/.github/workflows/docker-push.yml b/.github/workflows/docker-push.yml new file mode 100644 index 0000000000..82d1c6daf0 --- /dev/null +++ b/.github/workflows/docker-push.yml @@ -0,0 +1,37 @@ +# This workflow makes a 64 bit Raspberry Pi Arch Linux Image. +# It does not have the security issues mentioned here: https://github.com/tendermint/tendermint/blob/master/docs/tendermint-core/running-in-production.md#validator-signing-on-32-bit-architectures-or-arm +# Later, more devices will be supported, as well. +# The "base" is built by: https://github.com/faddat/sos +# The base image is located at: https://hub.docker.com/r/faddat/spos + +name: Docker +on: + push: + branches: + - develop + +jobs: + docker: + name: Starport Docker Image + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v2 + + - name: Set up QEMU + run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v1 + with: + version: latest + + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push + run: docker buildx build --tag ${{ secrets.DOCKERHUB_USERNAME }}/starport --platform linux/arm64,linux/amd64 --cache-from ${{ secrets.DOCKERHUB_USERNAME }}/starport:cache --cache-to ${{ secrets.DOCKERHUB_USERNAME }}/starport:cache --push --progress tty . diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000000..2fc97aad43 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,29 @@ +# Builds the starrport DDocker image as a test, but does not push it. + +name: Docker +on: + push: + branches: + - '*' + - '!master' + pull_request: + +jobs: + docker: + name: Starport Docker Image + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v2 + + - name: Set up QEMU + run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v1 + with: + version: latest + + - name: Build + run: docker buildx build --tag ${{ secrets.DOCKERHUB_USERNAME }}/starport --platform linux/arm64,linux/amd64 --progress tty . diff --git a/.gitignore b/.gitignore index f6178df987..445e751d29 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ node_modules .DS_Store apps/ .idea +.vscode \ No newline at end of file diff --git a/.pi/Dockerfile b/.pi/Dockerfile index 91fb09b644..8da8f13327 100644 --- a/.pi/Dockerfile +++ b/.pi/Dockerfile @@ -9,4 +9,4 @@ RUN useradd --create-home starport && \ # later, update to tendermint/starport -COPY --from=tendermintdevelopment/starport:arm64 /starport/build/starport /usr/bin/starport +COPY --from=tendermintdevelopment/starport /starport/build/starport /usr/bin/starport diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..68f00e9f43 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +# Build inside lopsided/archlinux for multiplatform support +# It's an arch linux image with support for both ARM64 and AMD64 +FROM lopsided/archlinux + + +# GOPATH AND GOBIN ON PATH +ENV GOPATH=/go +ENV PATH=$PATH:/go/bin + +# INSTALL DEPENDENCIES +RUN pacman -Syyu --noconfirm go npm make git which && \ + mkdir /go + +# COPY STARPORT SOURCE CODE INTO CONTAINER +COPY . /starport +WORKDIR /starport + +# INSTALL STARPORT +RUN PATH=$PATH:/go/bin && \ + bash scripts/install + +# CMD +CMD ["/go/bin/starport"] + +# WE NEED BOTH NODE AND GO, DISTROLESS IS NOT THE WAY HERE. REVISIT LATER. +# Copy into a distroless image so that ONLY the starport binary remains +# FROM gcr.io/distroless/base +# COPY --from=builder /starport/build/starport / + +# EXPOSE 12345 +# EXPOSE 8080 +# EXPOSE 1317 +# EXPOSE 26656 +# EXPOSE 26657 + +# CMD ["/starport"] diff --git a/changelog.md b/changelog.md index ac440a56d9..b9ea472eac 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,13 @@ # Changelog +### Features: +- Distroless multiplatform docker containers for starport that can be used for `starport serve` +- UI containers for chains scaffolded with Starport +- Use SOS-lite and Docker instead of systemD + +### Fixes: +- use docker buildx as a single command with multiple platforms to make multi-manifest work properly + ## `v0.13.0` ### Features: diff --git a/starport/templates/app/launchpad/.github/workflows/build.yml.plush b/starport/templates/app/launchpad/.github/workflows/build.yml.plush index 51476587c8..1e554bde7b 100644 --- a/starport/templates/app/launchpad/.github/workflows/build.yml.plush +++ b/starport/templates/app/launchpad/.github/workflows/build.yml.plush @@ -8,73 +8,41 @@ on: [push, pull_request] # This workflow makes x86_64 binaries for mac, windows, and linux. - jobs: - mac-windows: + build: runs-on: ubuntu-latest strategy: matrix: - targetos: [windows, darwin] - name: <%= AppName %> for ${{ matrix.targetos }} + arch: [amd64, arm64] + targetos: [windows, darwin, linux] + name: <%= AppName %> ${{ matrix.arch }} for ${{ matrix.targetos }} steps: - uses: actions/checkout@v2 - - name: Setup go uses: actions/setup-go@v1 with: go-version: 1.15 env: GOOS: ${{ matrix.targetos }} - - - name: Compile - run: | - cd cmd/<%= AppName %>d - go build . - cd .. - cd <%= AppName %>cli - go build . - - - uses: actions/upload-artifact@v2 - with: - name: <%= AppName %>cli ${{ matrix.targetos }} - path: cmd/<%= AppName %>cli/<%= AppName %>cli - - - uses: actions/upload-artifact@v2 - with: - name: <%= AppName %>d ${{ matrix.targetos }} - path: cmd/<%= AppName %>d/<%= AppName %>d - - linux: - runs-on: ubuntu-latest - strategy: - matrix: - arch: [arm64, riscv64, amd64] - - name: <%= AppName %> for ${{ matrix.arch }} - steps: - - uses: actions/checkout@v2 - - - name: Setup go - uses: actions/setup-go@v1 - with: - go-version: 1.15 - env: GOARCH: ${{ matrix.arch }} - name: Compile run: | + go mod download cd cmd/<%= AppName %>d go build . cd .. cd <%= AppName %>cli go build . - - uses: actions/upload-artifact@v2 + + - uses: actions/upload-artifact@v2 with: - name: <%= AppName %>cli ${{ matrix.arch }} + name: <%= AppName %>cli ${{ matrix.targetos }} ${{ matrix.arch }} path: cmd/<%= AppName %>cli/<%= AppName %>cli - uses: actions/upload-artifact@v2 with: - name: <%= AppName %>d ${{ matrix.arch }} + name: <%= AppName %>d ${{ matrix.targetos }} ${{ matrix.arch }} path: cmd/<%= AppName %>d/<%= AppName %>d + diff --git a/starport/templates/app/launchpad/.github/workflows/docker.yml.plush b/starport/templates/app/launchpad/.github/workflows/docker.yml.plush new file mode 100644 index 0000000000..9d81d3f587 --- /dev/null +++ b/starport/templates/app/launchpad/.github/workflows/docker.yml.plush @@ -0,0 +1,31 @@ +name: Docker +on: [push, pull_request] + +jobs: + amd64: + name: <%= AppName %> Docker + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v2 + + - name: Set up QEMU + run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v1 + with: + version: latest + + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push + run: docker buildx build --tag ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %> --file Dockerfile --platform linux/amd64,linux/arm64 --cache-from ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %>:cache --cache-to ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %>:cache --push --progress tty . + + - name: Build and push UI + run: docker buildx build --tag ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %>-ui --file vue/Dockerfile --platform linux/amd64,linux/arm64 --cache-from ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %>-ui:cache --cache-to ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %>-ui:cache --push --progress tty ./vue diff --git a/starport/templates/app/launchpad/.github/workflows/pi.yml.plush b/starport/templates/app/launchpad/.github/workflows/pi.yml.plush index dc7bc7ad02..703010dee7 100644 --- a/starport/templates/app/launchpad/.github/workflows/pi.yml.plush +++ b/starport/templates/app/launchpad/.github/workflows/pi.yml.plush @@ -1,67 +1,47 @@ -# This is a basic workflow that is manually triggered - -name: <%= AppName %> Pi - -# Controls when the action will run. Workflow runs when manually triggered using the UI -# or API. -on: [push, pull_request] - - -# This workflow makes a 64 bit Raspberry Pi Ubuntu Server Image. +# This workflow makes a 64 bit Raspberry Pi Arch Linux Image. # It does not have the security issues mentioned here: https://github.com/tendermint/tendermint/blob/master/docs/tendermint-core/running-in-production.md#validator-signing-on-32-bit-architectures-or-arm # Later, more devices will be supported, as well. +# The "base" is built by: https://github.com/faddat/sos +# The base image is located at: https://hub.docker.com/r/faddat/spos +# TODO: Replace this with a system that fetches SOS-light, loop-mounts the image, modifies hostname, adds docker compose run, and exits. +name: Rpi +on: [push, pull_request] jobs: - build: - name: <%= AppName %> Pi Image + pi: + name: <%= AppName %> Pi runs-on: ubuntu-latest steps: - - name: Check out <%= AppName %> + - name: checkout uses: actions/checkout@v2 - - name: Setup go - uses: actions/setup-go@v1 - with: - go-version: 1.15 - - - name: Compile <%= AppName %> - run: | - cd cmd/<%= AppName %>d - go build . - cd .. - cd <%= AppName %>cli - go build . - env: - GOOS: linux - GOARCH: arm64 + - name: Set up QEMU + run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes - - name: Upload <%= AppName %> Arm64 CLI - uses: actions/upload-artifact@v2 + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v1 with: - name: <%= AppName %>cli arm64 - path: cmd/<%= AppName %>cli/<%= AppName %>cli + version: latest - - name: Upload <%= AppName %> Arm64 daemon - uses: actions/upload-artifact@v2 + - name: Login to DockerHub + uses: docker/login-action@v1 with: - name: <%= AppName %>d arm64 - path: cmd/<%= AppName %>d/<%= AppName %>d + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build <%= AppName %>.img - run: docker run --rm --privileged -v /dev:/dev -v ${PWD}:/build mkaczanowski/packer-builder-arm build .pi/pibuild.json + - name: Build Image in Docker + run: docker buildx build --tag <%= AppName %> --file .pi/Dockerfile --platform linux/arm64 --cache-from ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %>:picache --cache-to ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %>:picache --load --progress tty . - - name: Install PiShrink - run: | - wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh - chmod +x pishrink.sh - sudo mv pishrink.sh /usr/local/bin + - name: Build Image + run: bash .pi/build.sh - - name: Shrink <%= AppName %>.img - run: sudo pishrink.sh -a -Z -v <%= AppName %>.img + - name: Compress + run: xz -T $(nproc) images/<%= AppName %>.img - - name: Upload artifacts + - name: Upload image uses: actions/upload-artifact@v2 with: - name: <%= AppName %> PI - path: <%= AppName %>.img.xz + name: Starport Pi + path: images/<%= AppName %>.img.xz diff --git a/starport/templates/app/launchpad/.pi/Dockerfile.plush b/starport/templates/app/launchpad/.pi/Dockerfile.plush new file mode 100644 index 0000000000..2efff467c0 --- /dev/null +++ b/starport/templates/app/launchpad/.pi/Dockerfile.plush @@ -0,0 +1,8 @@ +FROM faddat/sos-lite + +# Add seeds and such after doing gaia. +# I will prototype the rest of this on gaia. +RUN echo <%= AppName %> > /etc/hostname && \ + pacman -Syyu --noconfirm docker-compose zerotier-one +# echo "docker run <%= OwnerName %>/<%= AppName %>" >> /usr/local/bin/firstboot.sh +# TODO: docker-compose diff --git a/starport/templates/app/launchpad/.pi/build.sh.plush b/starport/templates/app/launchpad/.pi/build.sh.plush new file mode 100644 index 0000000000..1d6b2f9153 --- /dev/null +++ b/starport/templates/app/launchpad/.pi/build.sh.plush @@ -0,0 +1,90 @@ +#!/bin/bash +# ======================================================================= +# Starport Development Environment Build System +# ======================================================================= + + +# This process uses tools and a design pattern first developed by the pikvm team for their pi-builder and os tools. +# the biggest differences between this process and theirs are: +# * we use docker buildx so we don't need to deal with qemu directly. +# * we are not offering as many choices to users and are designing around automation. +# Later we can make this work for more devices and platforms with nearly the same technique. +# Reasonable build targets include: https://archlinuxarm.org/platforms/armv8 +# For example, the Odroid-N2 is the same software-wise as our Router! + +# Fail on error +set -exo pipefail + +# Print each command +set -o xtrace + +# EXTRACT IMAGE +# Make a temporary directory +rm -rf .tmp || true +mkdir .tmp + +# UNCOMMENT and add username WHEN NOT USING GITHUB ACTIONS +# docker buildx build --tag <%= AppName %> --file .pi/Dockerfile --platform linux/arm64 --cache-from <%= AppName %>:cache --cache-to <%= AppName %>:cache --load --progress tty . + +# save the image to result-rootfs.tar +docker save --output ./.tmp/result-rootfs.tar <%= AppName %> + +# Extract the image using docker-extract +docker run --rm --tty --volume $(pwd)/./.tmp:/root/./.tmp --workdir /root/./.tmp/.. faddat/toolbox /tools/docker-extract --root ./.tmp/result-rootfs ./.tmp/result-rootfs.tar + +# get rid of result-rootfs.tar to save space +rm ./.tmp/result-rootfs.tar + +# Set hostname while the image is just in the filesystem. +sudo bash -c "echo <%= AppName %> > ./.tmp/result-rootfs/etc/hostname" + + +# =================================================================================== +# IMAGE: Make a .img file and compress it. +# Uses Techniques from Disconnected Systems: +# https://disconnected.systems/blog/raspberry-pi-archlinuxarm-setup/ +# =================================================================================== + + +# Unmount anything on the loop device +sudo umount /dev/loop0p2 || true +sudo umount /dev/loop0p1 || true + +# Detach from the loop device +sudo losetup -d /dev/loop0 || true + +# Create a folder for images +rm -rf images || true +mkdir -p images + +# Make the image file +fallocate -l 4G "images/<%= AppName %>.img" + +# loop-mount the image file so it becomes a disk +sudo losetup --find --show images/<%= AppName %>.img + +# partition the loop-mounted disk +sudo parted --script /dev/loop0 mklabel msdos +sudo parted --script /dev/loop0 mkpart primary fat32 0% 200M +sudo parted --script /dev/loop0 mkpart primary ext4 200M 100% + +# format the newly partitioned loop-mounted disk +sudo mkfs.vfat -F32 /dev/loop0p1 +sudo mkfs.ext4 -F /dev/loop0p2 + +# Use the toolbox to copy the rootfs into the filesystem we formatted above. +# * mount the disk's /boot and / partitions +# * use rsync to copy files into the filesystem +# make a folder so we can mount the boot partition +# soon will not use toolbox + +sudo mkdir -p mnt/boot mnt/rootfs +sudo mount /dev/loop0p1 mnt/boot +sudo mount /dev/loop0p2 mnt/rootfs +sudo rsync -a ./.tmp/result-rootfs/boot/* mnt/boot +sudo rsync -a ./.tmp/result-rootfs/* mnt/rootfs --exclude boot +sudo mkdir mnt/rootfs/boot +sudo umount mnt/boot mnt/rootfs || true + +# Drop the loop mount +sudo losetup -d /dev/loop0 diff --git a/starport/templates/app/launchpad/.pi/image.bash.plush b/starport/templates/app/launchpad/.pi/image.bash.plush deleted file mode 100644 index f64b2195fd..0000000000 --- a/starport/templates/app/launchpad/.pi/image.bash.plush +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -# This install script runs inside the chroot of your image builder. - -# Connect to the internet by configuring DNS -mv /etc/resolv.conf /etc/resolv.conf.bk -echo 'nameserver 8.8.8.8' > /etc/resolv.conf -echo 'nameserver 1.1.1.1' >> /etc/resolv.conf - -# Update packages and install Zerotier -apt update -apt install -y curl wget jq apt-transport-https gnupg gnupg-agent software-properties-common -wget http://download.zerotier.com/debian/buster/pool/main/z/zerotier-one/zerotier-one_1.4.6_arm64.deb -dpkg -i zerotier-one_1.4.6_arm64.deb -apt install -y - -# Set Up <%= AppName %> -chmod +x /usr/bin/<%= AppName %>d /usr/bin/<%= AppName %>cli -mkdir -p /<%= AppName %>/config -systemctl enable <%= AppName %>d - - -# Set up Nodejs without NVM -wget https://nodejs.org/dist/v12.18.4/node-v12.18.4-linux-arm64.tar.xz -sudo mkdir -p /usr/local/lib/nodejs -sudo tar -xJvf node-v12.18.4-linux-arm64.tar.xz -C /usr/local/lib/nodejs -echo "export PATH=/usr/local/lib/nodejs/node-v12.18.4-linux-arm64/bin:$PATH" >> ~/.profile -export PATH=/usr/local/lib/nodejs/node-v12.18.4-linux-arm64/bin:$PATH -node -v -npm version -npx -v - -# Install vue deps -cd /vue -npm i -npm run-script build - -# Enable front end -systemctl enable vue diff --git a/starport/templates/app/launchpad/.pi/pibuild.json.plush b/starport/templates/app/launchpad/.pi/pibuild.json.plush deleted file mode 100644 index e26667eb87..0000000000 --- a/starport/templates/app/launchpad/.pi/pibuild.json.plush +++ /dev/null @@ -1,77 +0,0 @@ -{ - "variables": {}, - "builders": [{ - "type": "arm", - "file_urls" : ["http://cdimage.ubuntu.com/releases/20.04.1/release/ubuntu-20.04.1-preinstalled-server-arm64+raspi.img.xz"], - "file_checksum_url": "http://cdimage.ubuntu.com/releases/20.04.1/release/SHA256SUMS", - "file_checksum_type": "sha256", - "file_target_extension": "xz", - "file_unarchive_cmd": ["xz", "--decompress", "$ARCHIVE_PATH"], - "image_build_method": "reuse", - "image_path": "<%= AppName %>.img", - "image_size": "3.1G", - "image_type": "dos", - "image_partitions": [ - { - "name": "boot", - "type": "c", - "start_sector": "2048", - "filesystem": "fat", - "size": "256M", - "mountpoint": "/boot/firmware" - }, - { - "name": "root", - "type": "83", - "start_sector": "526336", - "filesystem": "ext4", - "size": "2.8G", - "mountpoint": "/" - } - - ], - "image_chroot_env": ["PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin"], - "qemu_binary_source_path": "/usr/bin/qemu-aarch64-static", - "qemu_binary_destination_path": "/usr/bin/qemu-aarch64-static" - }], - "provisioners": [ - { - "type": "file", - "source": ".pi/<%= AppName %>d.service", - "destination": "/etc/systemd/system/<%= AppName %>d.service" - }, - { - "type": "file", - "source": ".pi/vue.service", - "destination": "/etc/systemd/system/vue.service" - }, - { - "type": "file", - "source": ".pi/image.bash", - "destination": "/tmp/image.bash" - }, - { - "type": "file", - "source": "cmd/<%= AppName %>d/<%= AppName %>d", - "destination": "/usr/bin/<%= AppName %>d" - }, - { - "type": "file", - "source": "cmd/<%= AppName %>cli/<%= AppName %>cli", - "destination": "/usr/bin/<%= AppName %>cli" - }, - { - "type": "file", - "source": "vue/", - "destination": "vue/" - }, - { - "type": "shell", - "inline": [ - "bash /tmp/image.bash", - "rm /tmp/image.bash" - ] - } - ], - "post-processors": [] -} diff --git a/starport/templates/app/launchpad/.pi/vue.service b/starport/templates/app/launchpad/.pi/vue.service deleted file mode 100644 index 2db3893415..0000000000 --- a/starport/templates/app/launchpad/.pi/vue.service +++ /dev/null @@ -1,20 +0,0 @@ -[Unit] -Description=Vue - -[Service] -ExecStart=/usr/local/lib/nodejs/node-v12.18.4-linux-arm64/bin/npm run-script serve -WorkingDirectory=/vue -Restart=always -# Restart service after 10 seconds if node service crashes -RestartSec=10 - -#CREATE A USER LATER ON -#User= -#Group= - -Environment=NODE_ENV=production -Environment=PATH=/usr/local/lib/nodejs/node-v12.18.4-linux-arm64/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin - - -[Install] -WantedBy=multi-user.target diff --git a/starport/templates/app/launchpad/.pi/{{appName}}d.service.plush b/starport/templates/app/launchpad/.pi/{{appName}}d.service.plush deleted file mode 100644 index 350c8324f8..0000000000 --- a/starport/templates/app/launchpad/.pi/{{appName}}d.service.plush +++ /dev/null @@ -1,17 +0,0 @@ -# For chains that are already live and rolling. -[Unit] -Description=<%= AppName %> -Requires=network-online.target -After=network-online.target - -[Service] -Restart=on-failure -# User=gaiad -# Group=gaiad -PermissionsStartOnly=true -ExecStart=/usr/bin/<%= AppName %>d start --home /<%= AppName %> # add seeds later--p2p.seeds dd36969b56c740bb40bb8badd4d4c6facc35dc24@206.189.115.41:26656,ba3bacc714817218562f743178228f23678b2873@5.83.160.108:26656,1e63e84945837b026f596ed8ae68708783d04ad4@51.75.145.123:26656,d2d452e7c9c43fa5ef017552688de60a5c0053ee@34.245.217.163:26656,dd36969b56c740bb40bb8badd4d4c6facc35dc24@206.189.115.41:26656,a0aca8fb801c69653a290bd44872e8457f8b0982@47.99.180.54:26656,27f8dd3bdbecbef7192291083706c156e523d8e0@3.122.248.21:26656,aee0df1a660f301d456a0c2f805b372f7341e8ec@63.35.230.143:26656,7d1f660b361d6286715c098a3a171e554e9642bb@34.254.205.37:26656,fa105c2291ac4aa452552fa4835266300a8209e1@88.198.41.62:26656,bd410d4564f7e0dd9a0eb16a64c337a059e11b80@47.103.35.130:26656 -ExecReload=/bin/kill -HUP $MAINPID -KillSignal=SIGTERM - -[Install] -WantedBy=multi-user.target diff --git a/starport/templates/app/launchpad/Dockerfile.plush b/starport/templates/app/launchpad/Dockerfile.plush new file mode 100644 index 0000000000..ece45aa3b0 --- /dev/null +++ b/starport/templates/app/launchpad/Dockerfile.plush @@ -0,0 +1,14 @@ +# Compile +FROM golang:alpine AS builder +WORKDIR /src/app/ +COPY go.mod go.sum* ./ +RUN go mod download +COPY . . +RUN for bin in cmd/*; do CGO_ENABLED=0 go build -o=/usr/local/bin/$(basename $bin) ./cmd/$(basename $bin); done + + +# Add to a distroless container +FROM gcr.io/distroless/base +COPY --from=builder /usr/local/bin /usr/local/bin +USER nonroot:nonroot +CMD ["<%= AppName %> start"] diff --git a/starport/templates/app/launchpad/readme.md.plush b/starport/templates/app/launchpad/readme.md.plush index 4bce9589a0..5193bd6eae 100644 --- a/starport/templates/app/launchpad/readme.md.plush +++ b/starport/templates/app/launchpad/readme.md.plush @@ -23,9 +23,24 @@ A list of user accounts created during genesis of your application. | name | Y | String | Local name of the key pair | | coins | Y | List of Strings | Initial coins with denominations (e.g. "100coin") | +### CI + +By default, this chain includes a github action that builds for amd64 and arm64 on Windows, Mac, and Linux. + +### Docker Images And Pi Images + +In order for Docker images and Raspberry Pi images to build successfully, please add your docker hub credentials as [secrets](https://github.com/(<%= OwnerName %>/<%= AppName %>/settings/secrets/actions) + +Add these: + +DOCKERHUB_USERNAME +DOCKERHUB_TOKEN + +You can get the token [here](https://hub.docker.com/settings/security) + ## Learn more - [Starport](https://github.com/tendermint/starport) - [Cosmos SDK documentation](https://docs.cosmos.network) - [Cosmos Tutorials](https://tutorials.cosmos.network) -- [Channel on Discord](https://discord.gg/W8trcGV) \ No newline at end of file +- [Channel on Discord](https://discord.gg/W8trcGV) diff --git a/starport/templates/app/launchpad/vue/Dockerfile b/starport/templates/app/launchpad/vue/Dockerfile new file mode 100644 index 0000000000..511980fdf4 --- /dev/null +++ b/starport/templates/app/launchpad/vue/Dockerfile @@ -0,0 +1,12 @@ +# This image is not yet distroless because distroless images expect thatthe entrypoint will be a .js file and ours is vue-cli-service +# We use lopsided/archlinux for comptability + +FROM lopsided/archlinux +COPY . . + +RUN pacman -Syyu --noconfirm npm +RUN npm install +RUN npm run build + +EXPOSE 8080 +CMD ["/usr/bin/npm","run","serve"] \ No newline at end of file diff --git a/starport/templates/app/stargate/.github/workflows/build.yml.plush b/starport/templates/app/stargate/.github/workflows/build.yml.plush new file mode 100644 index 0000000000..6554508bb2 --- /dev/null +++ b/starport/templates/app/stargate/.github/workflows/build.yml.plush @@ -0,0 +1,39 @@ +# This is a basic workflow that is manually triggered + +name: <%= AppName %> + +# Controls when the action will run. Workflow runs when manually triggered using the UI +# or API. +on: [push, pull_request] + +# This workflow makes x86_64 binaries for mac, windows, and linux. + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + arch: [amd64, arm64] + targetos: [windows, darwin, linux] + name: <%= AppName %> ${{ matrix.arch }} for ${{ matrix.targetos }} + steps: + - uses: actions/checkout@v2 + - name: Setup go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + env: + GOOS: ${{ matrix.targetos }} + GOARCH: ${{ matrix.arch }} + + - name: Compile + run: | + go mod download + cd cmd/<%= AppName %>d + go build . + + - uses: actions/upload-artifact@v2 + with: + name: <%= AppName %>d ${{ matrix.targetos }} ${{ matrix.arch }} + path: cmd/<%= AppName %>d/<%= AppName %>d + diff --git a/starport/templates/app/stargate/.github/workflows/docker.yml.plush b/starport/templates/app/stargate/.github/workflows/docker.yml.plush new file mode 100644 index 0000000000..329da72b5c --- /dev/null +++ b/starport/templates/app/stargate/.github/workflows/docker.yml.plush @@ -0,0 +1,31 @@ +name: Docker +on: [push, pull_request] + +jobs: + amd64: + name: <%= AppName %> Docker + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v2 + + - name: Set up QEMU + run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v1 + with: + version: latest + + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push blockchain + run: docker buildx build --tag ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %> --file Dockerfile --platform linux/amd64,linux/arm64 --cache-from ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %>:cache --cache-to ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %>:cache --push --progress tty . + + - name: Build and push UI + run: docker buildx build --tag ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %>-ui --file vue/Dockerfile --platform linux/amd64,linux/arm64 --cache-from ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %>-ui:cache --cache-to ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %>-ui:cache --push --progress tty ./vue diff --git a/starport/templates/app/stargate/.github/workflows/pi.yml.plush b/starport/templates/app/stargate/.github/workflows/pi.yml.plush new file mode 100644 index 0000000000..703010dee7 --- /dev/null +++ b/starport/templates/app/stargate/.github/workflows/pi.yml.plush @@ -0,0 +1,47 @@ +# This workflow makes a 64 bit Raspberry Pi Arch Linux Image. +# It does not have the security issues mentioned here: https://github.com/tendermint/tendermint/blob/master/docs/tendermint-core/running-in-production.md#validator-signing-on-32-bit-architectures-or-arm +# Later, more devices will be supported, as well. +# The "base" is built by: https://github.com/faddat/sos +# The base image is located at: https://hub.docker.com/r/faddat/spos +# TODO: Replace this with a system that fetches SOS-light, loop-mounts the image, modifies hostname, adds docker compose run, and exits. + +name: Rpi +on: [push, pull_request] + +jobs: + pi: + name: <%= AppName %> Pi + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v2 + + - name: Set up QEMU + run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes --credential yes + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v1 + with: + version: latest + + - name: Login to DockerHub + uses: docker/login-action@v1 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build Image in Docker + run: docker buildx build --tag <%= AppName %> --file .pi/Dockerfile --platform linux/arm64 --cache-from ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %>:picache --cache-to ${{ secrets.DOCKERHUB_USERNAME }}/<%= AppName %>:picache --load --progress tty . + + - name: Build Image + run: bash .pi/build.sh + + - name: Compress + run: xz -T $(nproc) images/<%= AppName %>.img + + - name: Upload image + uses: actions/upload-artifact@v2 + with: + name: Starport Pi + path: images/<%= AppName %>.img.xz diff --git a/starport/templates/app/stargate/.pi/Dockerfile.plush b/starport/templates/app/stargate/.pi/Dockerfile.plush new file mode 100644 index 0000000000..2efff467c0 --- /dev/null +++ b/starport/templates/app/stargate/.pi/Dockerfile.plush @@ -0,0 +1,8 @@ +FROM faddat/sos-lite + +# Add seeds and such after doing gaia. +# I will prototype the rest of this on gaia. +RUN echo <%= AppName %> > /etc/hostname && \ + pacman -Syyu --noconfirm docker-compose zerotier-one +# echo "docker run <%= OwnerName %>/<%= AppName %>" >> /usr/local/bin/firstboot.sh +# TODO: docker-compose diff --git a/starport/templates/app/stargate/.pi/build.sh.plush b/starport/templates/app/stargate/.pi/build.sh.plush new file mode 100644 index 0000000000..1d6b2f9153 --- /dev/null +++ b/starport/templates/app/stargate/.pi/build.sh.plush @@ -0,0 +1,90 @@ +#!/bin/bash +# ======================================================================= +# Starport Development Environment Build System +# ======================================================================= + + +# This process uses tools and a design pattern first developed by the pikvm team for their pi-builder and os tools. +# the biggest differences between this process and theirs are: +# * we use docker buildx so we don't need to deal with qemu directly. +# * we are not offering as many choices to users and are designing around automation. +# Later we can make this work for more devices and platforms with nearly the same technique. +# Reasonable build targets include: https://archlinuxarm.org/platforms/armv8 +# For example, the Odroid-N2 is the same software-wise as our Router! + +# Fail on error +set -exo pipefail + +# Print each command +set -o xtrace + +# EXTRACT IMAGE +# Make a temporary directory +rm -rf .tmp || true +mkdir .tmp + +# UNCOMMENT and add username WHEN NOT USING GITHUB ACTIONS +# docker buildx build --tag <%= AppName %> --file .pi/Dockerfile --platform linux/arm64 --cache-from <%= AppName %>:cache --cache-to <%= AppName %>:cache --load --progress tty . + +# save the image to result-rootfs.tar +docker save --output ./.tmp/result-rootfs.tar <%= AppName %> + +# Extract the image using docker-extract +docker run --rm --tty --volume $(pwd)/./.tmp:/root/./.tmp --workdir /root/./.tmp/.. faddat/toolbox /tools/docker-extract --root ./.tmp/result-rootfs ./.tmp/result-rootfs.tar + +# get rid of result-rootfs.tar to save space +rm ./.tmp/result-rootfs.tar + +# Set hostname while the image is just in the filesystem. +sudo bash -c "echo <%= AppName %> > ./.tmp/result-rootfs/etc/hostname" + + +# =================================================================================== +# IMAGE: Make a .img file and compress it. +# Uses Techniques from Disconnected Systems: +# https://disconnected.systems/blog/raspberry-pi-archlinuxarm-setup/ +# =================================================================================== + + +# Unmount anything on the loop device +sudo umount /dev/loop0p2 || true +sudo umount /dev/loop0p1 || true + +# Detach from the loop device +sudo losetup -d /dev/loop0 || true + +# Create a folder for images +rm -rf images || true +mkdir -p images + +# Make the image file +fallocate -l 4G "images/<%= AppName %>.img" + +# loop-mount the image file so it becomes a disk +sudo losetup --find --show images/<%= AppName %>.img + +# partition the loop-mounted disk +sudo parted --script /dev/loop0 mklabel msdos +sudo parted --script /dev/loop0 mkpart primary fat32 0% 200M +sudo parted --script /dev/loop0 mkpart primary ext4 200M 100% + +# format the newly partitioned loop-mounted disk +sudo mkfs.vfat -F32 /dev/loop0p1 +sudo mkfs.ext4 -F /dev/loop0p2 + +# Use the toolbox to copy the rootfs into the filesystem we formatted above. +# * mount the disk's /boot and / partitions +# * use rsync to copy files into the filesystem +# make a folder so we can mount the boot partition +# soon will not use toolbox + +sudo mkdir -p mnt/boot mnt/rootfs +sudo mount /dev/loop0p1 mnt/boot +sudo mount /dev/loop0p2 mnt/rootfs +sudo rsync -a ./.tmp/result-rootfs/boot/* mnt/boot +sudo rsync -a ./.tmp/result-rootfs/* mnt/rootfs --exclude boot +sudo mkdir mnt/rootfs/boot +sudo umount mnt/boot mnt/rootfs || true + +# Drop the loop mount +sudo losetup -d /dev/loop0 diff --git a/starport/templates/app/stargate/Dockerfile.plush b/starport/templates/app/stargate/Dockerfile.plush new file mode 100644 index 0000000000..ece45aa3b0 --- /dev/null +++ b/starport/templates/app/stargate/Dockerfile.plush @@ -0,0 +1,14 @@ +# Compile +FROM golang:alpine AS builder +WORKDIR /src/app/ +COPY go.mod go.sum* ./ +RUN go mod download +COPY . . +RUN for bin in cmd/*; do CGO_ENABLED=0 go build -o=/usr/local/bin/$(basename $bin) ./cmd/$(basename $bin); done + + +# Add to a distroless container +FROM gcr.io/distroless/base +COPY --from=builder /usr/local/bin /usr/local/bin +USER nonroot:nonroot +CMD ["<%= AppName %> start"] diff --git a/starport/templates/app/stargate/readme.md.plush b/starport/templates/app/stargate/readme.md.plush index 4bce9589a0..7fac0ff4c1 100644 --- a/starport/templates/app/stargate/readme.md.plush +++ b/starport/templates/app/stargate/readme.md.plush @@ -23,9 +23,26 @@ A list of user accounts created during genesis of your application. | name | Y | String | Local name of the key pair | | coins | Y | List of Strings | Initial coins with denominations (e.g. "100coin") | + +### CI + +By default, this chain includes a github action that builds for amd64 and arm64 on Windows, Mac, and Linux. + +### Docker Images And Pi Images + +In order for Docker images and Raspberry Pi images to build successfully, please add your docker hub credentials as [secrets](https://github.com/(<%= OwnerName %>/<%= AppName %>/settings/secrets/actions) + +Add these: + +DOCKERHUB_USERNAME +DOCKERHUB_TOKEN + +You can get the token [here](https://hub.docker.com/settings/security) + + ## Learn more - [Starport](https://github.com/tendermint/starport) - [Cosmos SDK documentation](https://docs.cosmos.network) - [Cosmos Tutorials](https://tutorials.cosmos.network) -- [Channel on Discord](https://discord.gg/W8trcGV) \ No newline at end of file +- [Channel on Discord](https://discord.gg/W8trcGV) diff --git a/starport/templates/app/stargate/vue/Dockerfile b/starport/templates/app/stargate/vue/Dockerfile new file mode 100644 index 0000000000..511980fdf4 --- /dev/null +++ b/starport/templates/app/stargate/vue/Dockerfile @@ -0,0 +1,12 @@ +# This image is not yet distroless because distroless images expect thatthe entrypoint will be a .js file and ours is vue-cli-service +# We use lopsided/archlinux for comptability + +FROM lopsided/archlinux +COPY . . + +RUN pacman -Syyu --noconfirm npm +RUN npm install +RUN npm run build + +EXPOSE 8080 +CMD ["/usr/bin/npm","run","serve"] \ No newline at end of file