Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create docker image with cloud server #113

Merged
merged 8 commits into from
Apr 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions .github/workflows/build-publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Build and publish image
on:
push:
tags:
- "*"
pull_request:
branches:
- main

env:
REGISTRY: ghcr.io


jobs:
build-and-publish-image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: recursive
- name: build-web
run: |
mkdir -p `pwd`/.tmp
make build-web UI_FILE=`pwd`/.tmp/ui.tar.gz
- uses: docker/setup-qemu-action@v2
- uses: docker/setup-buildx-action@v2
- uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for docker image
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ github.repository }}
tags: |
type=raw,enable={{is_default_branch}},value=vnext
type=sha,enable={{is_default_branch}},prefix=vnext-,format=short
type=ref,event=pr,prefix=vnext-pr,suffix=-{{sha}}
type=ref,event=pr,prefix=vnext-pr
type=ref,enable={{is_default_branch}},event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
- name: Build and publish image
uses: docker/build-push-action@v3
with:
context: .
file: ./docker/Dockerfile
platforms: linux/amd64,linux/arm64
builder: ${{ steps.buildx.outputs.name }}
build-args: |
UI_FILE=.tmp/ui.tar.gz
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- name: Clean up
if: ${{ always() }}
run: |
shopt -s dotglob
sudo rm -r *
4 changes: 3 additions & 1 deletion .github/workflows/buildTestBinaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@ jobs:
with:
go-version: "^1.18" # The Go version to download (if necessary) and use.

- name: Set version
- name: Set version and ui_file
id: vars
run: |
git tag $(git describe --tags --abbrev=0)-$(git rev-parse --short HEAD)
echo "::set-output name=version::$(git describe --tags --abbrev=0)"
echo "::set-output name=ui_file::$(pwd)/.tmp/ui.tar.gz"

- name: Build client
uses: goreleaser/goreleaser-action@v3
Expand All @@ -41,6 +42,7 @@ jobs:
args: release --rm-dist --skip-publish --skip-announce
env:
UI_SEPARATOR: "--------UI--------"
UI_FILE: ${{ steps.vars.outputs.ui_file }}

- name: Upload assets
uses: actions/upload-artifact@v3
Expand Down
37 changes: 37 additions & 0 deletions .github/workflows/ghcr-cleanup.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Delete old ghcr images
on:
schedule:
- cron: "15 1 * * *" # every day at 1:15am
pull_request:
types: [closed]

jobs:
pull-request-ghcr-cleanup:
if: ${{ github.event_name == 'pull_request' }}
name: Delete images related to closed PR
runs-on: ubuntu-latest
steps:
- name: Delete images related to closed PR
uses: snok/container-retention-policy@v1
with:
image-names: client-application
cut-off: now UTC
account-type: org
org-name: plgd-dev
filter-tags: vnext-pr${{ github.event.pull_request.number }}*
token: ${{ secrets.GHCR_CLEANUP_PAT }}
nightly-ghcr-cleanup:
if: ${{ github.event_name == 'schedule' }}
name: Delete old vnext images
runs-on: ubuntu-latest
steps:
- name: Delete older than a month vnext images
jkralik marked this conversation as resolved.
Show resolved Hide resolved
uses: snok/container-retention-policy@v1
with:
image-names: client-application
cut-off: One month ago UTC
account-type: org
org-name: plgd-dev
filter-tags: vnext-*
skip-tags: vnext-pr*, main
token: ${{ secrets.GHCR_CLEANUP_PAT }}
6 changes: 6 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ jobs:
uses: actions/setup-go@v2
with:
go-version: 1.18

- name: Set ui_file
id: vars
run: |
echo "::set-output name=ui_file::$(pwd)/.tmp/ui.tar.gz"
-
name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
Expand All @@ -40,5 +45,6 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
UI_SEPARATOR: "--------UI--------"
UI_FILE: ${{ steps.vars.outputs.ui_file }}
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro' distribution
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
4 changes: 2 additions & 2 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Make sure to check the documentation at https://goreleaser.com
before:
hooks:
- make build-web
- bash -c "test -f {{.Env.UI_FILE}} || make build-web UI_FILE={{.Env.UI_FILE}}"
dist: .tmp/dist
builds:
- binary: client-application
Expand Down Expand Up @@ -33,7 +33,7 @@ builds:
hooks:
post:
- bash -c "test {{.Os}} == "windows" || test {{.Os}} == "darwin" || upx --best --lzma {{.Path}}"
- make inject-web CLIENT_APPLICATION_BINARY_PATH={{.Path}} UI_SEPARATOR={{.Env.UI_SEPARATOR}}
- make inject-web CLIENT_APPLICATION_BINARY_PATH={{.Path}} UI_SEPARATOR={{.Env.UI_SEPARATOR}} UI_FILE={{.Env.UI_FILE}}
archives:
- replacements:
darwin: macOS
Expand Down
9 changes: 5 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ WWW_PATH=$(TMP_PATH)/www
CLIENT_APPLICATION_VERSION_PATH_VARIABLE = main.Version
CLIENT_APPLICATION_UI_SEPARATOR_PATH_VARIABLE = main.UISeparator
CLIENT_APPLICATION_BINARY_PATH ?=
UI_FILE ?= $(TMP_PATH)/ui.tar.gz

CERT_TOOL_IMAGE ?= ghcr.io/plgd-dev/hub/cert-tool:vnext
DEVSIM_IMAGE ?= ghcr.io/iotivity/iotivity-lite/cloud-server-discovery-resource-observable-debug:master
Expand Down Expand Up @@ -93,17 +94,17 @@ build-web:
mkdir -p $(WWW_PATH)
docker build --tag build-web:latest --target build-web -f ./web/Dockerfile ./web
CONTAINER_ID=`docker create build-web:latest` && docker cp $$CONTAINER_ID:/web/build/ $(WWW_PATH)/ && docker rm -f $$CONTAINER_ID
cd $(WWW_PATH)/build && tar -czf $(TMP_PATH)/ui.tar.gz .
cd $(WWW_PATH)/build && tar -czf $(UI_FILE) .
.PHONY: build-web

inject-web: $(CLIENT_APPLICATION_BINARY_PATH)
printf "\n$(UI_SEPARATOR)\n" >> $(CLIENT_APPLICATION_BINARY_PATH)
wc -c $(CLIENT_APPLICATION_BINARY_PATH)
cat $(TMP_PATH)/ui.tar.gz >> $(CLIENT_APPLICATION_BINARY_PATH)
cat $(UI_FILE) >> $(CLIENT_APPLICATION_BINARY_PATH)
.PHONY: inject-web

build: clean
UI_SEPARATOR=$(UI_SEPARATOR) goreleaser build --rm-dist
build:
UI_FILE=$(UI_FILE) UI_SEPARATOR=$(UI_SEPARATOR) goreleaser build --rm-dist --single-target --skip-validate
.PHONY: build

test: env
Expand Down
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ git tag -f v0.0.1-myversion
make build
```

## Docker

You can run the client application in a docker container by executing the following command.

```sh
docker run --rm -it -e NUM_DEVICES=1 -p 8080:8080 ghcr.io/plgd-dev/client-application:latest
```

Via environment variable NUM_DEVICES you can specify the number of devices simulators. The default value is 1. The client application will be available at [http://locahost:8080](http://locahost:8080).

## YAML Configuration

A configuration template is available on [config.yaml](./config.yaml).
Expand Down
16 changes: 16 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM goreleaser/goreleaser AS builder
ARG UI_FILE

RUN apk add upx
WORKDIR /go/src/github.com/plgd-dev/client-application
COPY go.mod go.sum ./
COPY ${UI_FILE} ${UI_FILE}
COPY . .
RUN make build BUILD_UI=false UI_FILE=${UI_FILE}

FROM ghcr.io/iotivity/iotivity-lite/cloud-server-discovery-resource-observable:latest AS service
COPY ./docker/run.sh /usr/local/bin/run.sh
COPY --from=builder /go/src/github.com/plgd-dev/client-application/.tmp/dist/*/client-application /usr/local/bin/client-application
RUN mkdir -p /plgd
WORKDIR /plgd
ENTRYPOINT [ "/usr/local/bin/run.sh" ]
41 changes: 41 additions & 0 deletions docker/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
set -e

PREFIX_EXEC=""
echo Spawning $NUM_DEVICES devices

umask 0000
pids=()
for ((i=0;i<$NUM_DEVICES;i++)); do
LD_PRELOAD=/usr/local/lib/faketime/libfaketimeMT.so.1 /iotivity-lite/port/linux/service "device-$i" > /tmp/$i.log 2>&1 &
pids+=($!)
done

/usr/local/bin/client-application --config /plgd/config.yaml $@ > /tmp/client-application.log 2>&1 &
pids+=($!)

terminate()
{
echo "Terminate"
for (( i=0; i<${#pids[@]}; i++ )); do
kill -SIGTERM ${pids[$i]}
done
}

trap terminate SIGTERM

# Naive check runs checks once a minute to see if either of the processes exited.
# This illustrates part of the heavy lifting you need to do if you want to run
# more than one service in a container. The container exits with an error
# if it detects that either of the processes has exited.
# Otherwise it loops forever, waking up every 60 seconds
while sleep 10; do
for (( i=0; i<${#pids[@]}; i++ ));
do
if ! kill -0 ${pids[$i]} 2>/dev/null; then
echo "service[$i] with pid=${pids[$i]} is dead"
exit 1
fi
done
echo checking running devices
done
2 changes: 1 addition & 1 deletion tools/validate/validateYaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def find_and_validate_yaml_files(dir = ROOT_DIRECTORY):
"""Find all yaml files in directory and validate them."""

valid = True
exclude_dirs = set(["dependency", "templates"])
exclude_dirs = set(["dependency", "templates", ".github"])
exclude_filenames = set(["swagger.yaml"])
for root, dirnames, filenames in os.walk(dir, topdown=True):
dirnames[:] = [d for d in dirnames if d not in exclude_dirs]
Expand Down