Skip to content

Commit ac27a7e

Browse files
authored
create docker image with cloud server (#113)
* create docker image with cloud server
1 parent 2825bfc commit ac27a7e

10 files changed

Lines changed: 184 additions & 8 deletions

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Build and publish image
2+
on:
3+
push:
4+
tags:
5+
- "*"
6+
pull_request:
7+
branches:
8+
- main
9+
10+
env:
11+
REGISTRY: ghcr.io
12+
13+
14+
jobs:
15+
build-and-publish-image:
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v3
19+
with:
20+
fetch-depth: 0
21+
submodules: recursive
22+
- name: build-web
23+
run: |
24+
mkdir -p `pwd`/.tmp
25+
make build-web UI_FILE=`pwd`/.tmp/ui.tar.gz
26+
- uses: docker/setup-qemu-action@v2
27+
- uses: docker/setup-buildx-action@v2
28+
- uses: docker/login-action@v2
29+
with:
30+
registry: ${{ env.REGISTRY }}
31+
username: ${{ github.actor }}
32+
password: ${{ secrets.GITHUB_TOKEN }}
33+
- name: Extract metadata (tags, labels) for docker image
34+
id: meta
35+
uses: docker/metadata-action@v4
36+
with:
37+
images: ${{ env.REGISTRY }}/${{ github.repository }}
38+
tags: |
39+
type=raw,enable={{is_default_branch}},value=vnext
40+
type=sha,enable={{is_default_branch}},prefix=vnext-,format=short
41+
type=ref,event=pr,prefix=vnext-pr,suffix=-{{sha}}
42+
type=ref,event=pr,prefix=vnext-pr
43+
type=ref,enable={{is_default_branch}},event=branch
44+
type=semver,pattern={{version}}
45+
type=semver,pattern={{major}}.{{minor}}
46+
type=semver,pattern={{major}}
47+
- name: Build and publish image
48+
uses: docker/build-push-action@v3
49+
with:
50+
context: .
51+
file: ./docker/Dockerfile
52+
platforms: linux/amd64,linux/arm64
53+
builder: ${{ steps.buildx.outputs.name }}
54+
build-args: |
55+
UI_FILE=.tmp/ui.tar.gz
56+
push: true
57+
tags: ${{ steps.meta.outputs.tags }}
58+
labels: ${{ steps.meta.outputs.labels }}
59+
- name: Clean up
60+
if: ${{ always() }}
61+
run: |
62+
shopt -s dotglob
63+
sudo rm -r *

.github/workflows/buildTestBinaries.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@ jobs:
2727
with:
2828
go-version: "^1.18" # The Go version to download (if necessary) and use.
2929

30-
- name: Set version
30+
- name: Set version and ui_file
3131
id: vars
3232
run: |
3333
git tag $(git describe --tags --abbrev=0)-$(git rev-parse --short HEAD)
3434
echo "::set-output name=version::$(git describe --tags --abbrev=0)"
35+
echo "::set-output name=ui_file::$(pwd)/.tmp/ui.tar.gz"
3536
3637
- name: Build client
3738
uses: goreleaser/goreleaser-action@v3
@@ -41,6 +42,7 @@ jobs:
4142
args: release --rm-dist --skip-publish --skip-announce
4243
env:
4344
UI_SEPARATOR: "--------UI--------"
45+
UI_FILE: ${{ steps.vars.outputs.ui_file }}
4446

4547
- name: Upload assets
4648
uses: actions/upload-artifact@v3
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Delete old ghcr images
2+
on:
3+
schedule:
4+
- cron: "15 1 * * *" # every day at 1:15am
5+
pull_request:
6+
types: [closed]
7+
8+
jobs:
9+
pull-request-ghcr-cleanup:
10+
if: ${{ github.event_name == 'pull_request' }}
11+
name: Delete images related to closed PR
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Delete images related to closed PR
15+
uses: snok/container-retention-policy@v1
16+
with:
17+
image-names: client-application
18+
cut-off: now UTC
19+
account-type: org
20+
org-name: plgd-dev
21+
filter-tags: vnext-pr${{ github.event.pull_request.number }}*
22+
token: ${{ secrets.GHCR_CLEANUP_PAT }}
23+
nightly-ghcr-cleanup:
24+
if: ${{ github.event_name == 'schedule' }}
25+
name: Delete old vnext images
26+
runs-on: ubuntu-latest
27+
steps:
28+
- name: Delete older than a month vnext images
29+
uses: snok/container-retention-policy@v1
30+
with:
31+
image-names: client-application
32+
cut-off: One month ago UTC
33+
account-type: org
34+
org-name: plgd-dev
35+
filter-tags: vnext-*
36+
skip-tags: vnext-pr*, main
37+
token: ${{ secrets.GHCR_CLEANUP_PAT }}

.github/workflows/release.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ jobs:
2929
uses: actions/setup-go@v2
3030
with:
3131
go-version: 1.18
32+
33+
- name: Set ui_file
34+
id: vars
35+
run: |
36+
echo "::set-output name=ui_file::$(pwd)/.tmp/ui.tar.gz"
3237
-
3338
name: Run GoReleaser
3439
uses: goreleaser/goreleaser-action@v2
@@ -40,5 +45,6 @@ jobs:
4045
env:
4146
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4247
UI_SEPARATOR: "--------UI--------"
48+
UI_FILE: ${{ steps.vars.outputs.ui_file }}
4349
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro' distribution
4450
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}

.goreleaser.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Make sure to check the documentation at https://goreleaser.com
33
before:
44
hooks:
5-
- make build-web
5+
- bash -c "test -f {{.Env.UI_FILE}} || make build-web UI_FILE={{.Env.UI_FILE}}"
66
dist: .tmp/dist
77
builds:
88
- binary: client-application
@@ -33,7 +33,7 @@ builds:
3333
hooks:
3434
post:
3535
- bash -c "test {{.Os}} == "windows" || test {{.Os}} == "darwin" || upx --best --lzma {{.Path}}"
36-
- make inject-web CLIENT_APPLICATION_BINARY_PATH={{.Path}} UI_SEPARATOR={{.Env.UI_SEPARATOR}}
36+
- make inject-web CLIENT_APPLICATION_BINARY_PATH={{.Path}} UI_SEPARATOR={{.Env.UI_SEPARATOR}} UI_FILE={{.Env.UI_FILE}}
3737
archives:
3838
- replacements:
3939
darwin: macOS

Makefile

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ WWW_PATH=$(TMP_PATH)/www
1010
CLIENT_APPLICATION_VERSION_PATH_VARIABLE = main.Version
1111
CLIENT_APPLICATION_UI_SEPARATOR_PATH_VARIABLE = main.UISeparator
1212
CLIENT_APPLICATION_BINARY_PATH ?=
13+
UI_FILE ?= $(TMP_PATH)/ui.tar.gz
1314

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

99100
inject-web: $(CLIENT_APPLICATION_BINARY_PATH)
100101
printf "\n$(UI_SEPARATOR)\n" >> $(CLIENT_APPLICATION_BINARY_PATH)
101102
wc -c $(CLIENT_APPLICATION_BINARY_PATH)
102-
cat $(TMP_PATH)/ui.tar.gz >> $(CLIENT_APPLICATION_BINARY_PATH)
103+
cat $(UI_FILE) >> $(CLIENT_APPLICATION_BINARY_PATH)
103104
.PHONY: inject-web
104105

105-
build: clean
106-
UI_SEPARATOR=$(UI_SEPARATOR) goreleaser build --rm-dist
106+
build:
107+
UI_FILE=$(UI_FILE) UI_SEPARATOR=$(UI_SEPARATOR) goreleaser build --rm-dist --single-target --skip-validate
107108
.PHONY: build
108109

109110
test: env

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ git tag -f v0.0.1-myversion
3232
make build
3333
```
3434

35+
## Docker
36+
37+
You can run the client application in a docker container by executing the following command.
38+
39+
```sh
40+
docker run --rm -it -e NUM_DEVICES=1 -p 8080:8080 ghcr.io/plgd-dev/client-application:latest
41+
```
42+
43+
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).
44+
3545
## YAML Configuration
3646

3747
A configuration template is available on [config.yaml](./config.yaml).

docker/Dockerfile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
FROM goreleaser/goreleaser AS builder
2+
ARG UI_FILE
3+
4+
RUN apk add upx
5+
WORKDIR /go/src/github.com/plgd-dev/client-application
6+
COPY go.mod go.sum ./
7+
COPY ${UI_FILE} ${UI_FILE}
8+
COPY . .
9+
RUN make build BUILD_UI=false UI_FILE=${UI_FILE}
10+
11+
FROM ghcr.io/iotivity/iotivity-lite/cloud-server-discovery-resource-observable:latest AS service
12+
COPY ./docker/run.sh /usr/local/bin/run.sh
13+
COPY --from=builder /go/src/github.com/plgd-dev/client-application/.tmp/dist/*/client-application /usr/local/bin/client-application
14+
RUN mkdir -p /plgd
15+
WORKDIR /plgd
16+
ENTRYPOINT [ "/usr/local/bin/run.sh" ]

docker/run.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
4+
PREFIX_EXEC=""
5+
echo Spawning $NUM_DEVICES devices
6+
7+
umask 0000
8+
pids=()
9+
for ((i=0;i<$NUM_DEVICES;i++)); do
10+
LD_PRELOAD=/usr/local/lib/faketime/libfaketimeMT.so.1 /iotivity-lite/port/linux/service "device-$i" > /tmp/$i.log 2>&1 &
11+
pids+=($!)
12+
done
13+
14+
/usr/local/bin/client-application --config /plgd/config.yaml $@ > /tmp/client-application.log 2>&1 &
15+
pids+=($!)
16+
17+
terminate()
18+
{
19+
echo "Terminate"
20+
for (( i=0; i<${#pids[@]}; i++ )); do
21+
kill -SIGTERM ${pids[$i]}
22+
done
23+
}
24+
25+
trap terminate SIGTERM
26+
27+
# Naive check runs checks once a minute to see if either of the processes exited.
28+
# This illustrates part of the heavy lifting you need to do if you want to run
29+
# more than one service in a container. The container exits with an error
30+
# if it detects that either of the processes has exited.
31+
# Otherwise it loops forever, waking up every 60 seconds
32+
while sleep 10; do
33+
for (( i=0; i<${#pids[@]}; i++ ));
34+
do
35+
if ! kill -0 ${pids[$i]} 2>/dev/null; then
36+
echo "service[$i] with pid=${pids[$i]} is dead"
37+
exit 1
38+
fi
39+
done
40+
echo checking running devices
41+
done

tools/validate/validateYaml.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def find_and_validate_yaml_files(dir = ROOT_DIRECTORY):
7474
"""Find all yaml files in directory and validate them."""
7575

7676
valid = True
77-
exclude_dirs = set(["dependency", "templates"])
77+
exclude_dirs = set(["dependency", "templates", ".github"])
7878
exclude_filenames = set(["swagger.yaml"])
7979
for root, dirnames, filenames in os.walk(dir, topdown=True):
8080
dirnames[:] = [d for d in dirnames if d not in exclude_dirs]

0 commit comments

Comments
 (0)