mirror of
https://github.com/balena-os/balena-supervisor.git
synced 2025-01-30 16:14:11 +00:00
Add a deploy-to-resin.js and automatically deploy to the Resin API on master builds
Also, make all of the arch builds part of the Circle workflow. Change-Type: patch Signed-off-by: Pablo Carranza Velez <pablo@resin.io>
This commit is contained in:
parent
392d963348
commit
60a8ab85f4
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
/node_modules/
|
/node_modules/
|
||||||
|
/automation/node_modules/
|
||||||
*.swp
|
*.swp
|
||||||
data
|
data
|
||||||
bin/gosuper
|
bin/gosuper
|
||||||
|
@ -4,7 +4,14 @@ RUN apk add --no-cache \
|
|||||||
make \
|
make \
|
||||||
jq \
|
jq \
|
||||||
git \
|
git \
|
||||||
bash
|
bash \
|
||||||
|
nodejs \
|
||||||
|
nodejs-npm
|
||||||
|
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
|
COPY ./automation/package.json /src/automation/package.json
|
||||||
|
RUN cd automation \
|
||||||
|
&& JOBS=max npm install \
|
||||||
|
&& npm cache clean
|
||||||
|
|
||||||
COPY . /src
|
COPY . /src
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
# * CLEANUP
|
# * CLEANUP
|
||||||
# * ENABLE_TESTS
|
# * ENABLE_TESTS
|
||||||
# * PUBNUB_SUBSCRIBE_KEY, PUBNUB_PUBLISH_KEY, MIXPANEL_TOKEN: default keys to inject in the supervisor image
|
# * PUBNUB_SUBSCRIBE_KEY, PUBNUB_PUBLISH_KEY, MIXPANEL_TOKEN: default keys to inject in the supervisor image
|
||||||
|
# * EXTRA_TAG: when PUSH_IMAGES is true, additional tag to push to the registries
|
||||||
#
|
#
|
||||||
# Builds the supervisor for the architecture defined by $ARCH.
|
# Builds the supervisor for the architecture defined by $ARCH.
|
||||||
# Will produce and push an image tagged as resin/$ARCH-supervisor:$TAG
|
# Will produce and push an image tagged as resin/$ARCH-supervisor:$TAG
|
||||||
@ -111,6 +112,13 @@ if [ "$PUSH_IMAGES" = "true" ]; then
|
|||||||
docker tag $TARGET_IMAGE registry.resinstaging.io/$TARGET_IMAGE
|
docker tag $TARGET_IMAGE registry.resinstaging.io/$TARGET_IMAGE
|
||||||
make IMAGE=registry.resinstaging.io/$TARGET_IMAGE deploy
|
make IMAGE=registry.resinstaging.io/$TARGET_IMAGE deploy
|
||||||
|
|
||||||
|
if [ -n "$EXTRA_TAG" ]; then
|
||||||
|
docker tag $TARGET_IMAGE resin/$ARCH-supervisor:$EXTRA_TAG
|
||||||
|
make IMAGE=resin/$ARCH-supervisor:$EXTRA_TAG deploy
|
||||||
|
docker tag $TARGET_IMAGE registry.resinstaging.io/resin/$ARCH-supervisor:$EXTRA_TAG
|
||||||
|
make IMAGE=registry.resinstaging.io/resin/$ARCH-supervisor:$EXTRA_TAG deploy
|
||||||
|
fi
|
||||||
|
|
||||||
# Try to push the intermediate images to improve caching in future builds
|
# Try to push the intermediate images to improve caching in future builds
|
||||||
# But we don't care much if any of this fails.
|
# But we don't care much if any of this fails.
|
||||||
( make IMAGE=$BASE_IMAGE base && make IMAGE=$BASE_IMAGE deploy ) || true
|
( make IMAGE=$BASE_IMAGE base && make IMAGE=$BASE_IMAGE deploy ) || true
|
||||||
|
91
automation/deploy-to-resin.js
Normal file
91
automation/deploy-to-resin.js
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
// Deploy a supervisor image as a supervisor_release in the Resin API
|
||||||
|
//
|
||||||
|
// Environment variables:
|
||||||
|
// This program deploys only for device types where the architecture matches $ARCH.
|
||||||
|
// It deploys to the API specified by $API_ENDPOINT and using a provided $API_TOKEN or $API_KEY
|
||||||
|
// (if both are set, API_TOKEN is preferred).
|
||||||
|
// The tag to deploy must be passed as $TAG.
|
||||||
|
//
|
||||||
|
const PineJsClient = require('pinejs-client');
|
||||||
|
const Promise = require('bluebird');
|
||||||
|
const _ = require('lodash');
|
||||||
|
const url = require('url');
|
||||||
|
|
||||||
|
const apiEndpoint = process.env.API_ENDPOINT;
|
||||||
|
const apikey = process.env.API_KEY;
|
||||||
|
const arch = process.env.ARCH;
|
||||||
|
const tag = process.env.TAG;
|
||||||
|
const apiToken = process.env.API_TOKEN;
|
||||||
|
|
||||||
|
if (_.isEmpty(apikey) && _.isEmpty(apiToken)) {
|
||||||
|
console.error('Skipping deploy due to empty API_KEY and API_TOKEN');
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_.isEmpty(apiEndpoint)) {
|
||||||
|
console.error('Please set a valid $API_ENDPOINT');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_.isEmpty(tag)) {
|
||||||
|
console.error('Please set a $TAG to deploy');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const supportedArchitectures = [ 'amd64', 'rpi', 'aarch64', 'armel', 'i386', 'armv7hf' ];
|
||||||
|
if (_.isEmpty(arch) || !_.includes(supportedArchitectures, arch)) {
|
||||||
|
console.error('Invalid architecture ' + arch);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const requestOpts = {
|
||||||
|
gzip: true,
|
||||||
|
timeout: 30000
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!_.isEmpty(apiToken)) {
|
||||||
|
requestOpts.headers = {
|
||||||
|
Authorization: 'Bearer ' + apiToken
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const apiEndpointWithPrefix = url.resolve(apiEndpoint, '/v2/')
|
||||||
|
const resinApi = new PineJsClient({
|
||||||
|
apiPrefix: apiEndpointWithPrefix,
|
||||||
|
passthrough: requestOpts
|
||||||
|
});
|
||||||
|
|
||||||
|
resinApi._request(_.extend({
|
||||||
|
url: apiEndpoint + '/config/device-types',
|
||||||
|
method: 'GET'
|
||||||
|
}, resinApi.passthrough))
|
||||||
|
.then( (deviceTypes) => {
|
||||||
|
// This is a critical step so we better do it serially
|
||||||
|
return Promise.mapSeries(deviceTypes, (deviceType) => {
|
||||||
|
if (deviceType.arch === arch) {
|
||||||
|
const customOptions = {};
|
||||||
|
if (_.isEmpty(apiToken)) {
|
||||||
|
customOptions.apikey = apikey;
|
||||||
|
}
|
||||||
|
console.log(`Deploying ${supervisor_version} for ${device_type}`);
|
||||||
|
return resinApi.post({
|
||||||
|
resource: 'supervisor_release',
|
||||||
|
body: {
|
||||||
|
image_name: `registry.resinstaging.io/resin/${arch}-supervisor`,
|
||||||
|
supervisor_version: tag,
|
||||||
|
device_type: deviceType.slug,
|
||||||
|
is_public: true
|
||||||
|
},
|
||||||
|
customOptions
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then( () => {
|
||||||
|
process.exit(0);
|
||||||
|
})
|
||||||
|
.catch( (err) => {
|
||||||
|
console.error(`Error when deploying the supervisor to ${apiEndpoint}`, err, err.stack);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
16
automation/package.json
Normal file
16
automation/package.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "resin-supervisor-automation",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Tools to build/deploy resin-supervisor",
|
||||||
|
"main": "deploy-to-resin.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "Resin Inc.",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"bluebird": "^3.5.0",
|
||||||
|
"lodash": "^4.17.4",
|
||||||
|
"pinejs-client": "^4.0.0"
|
||||||
|
}
|
||||||
|
}
|
38
circle.yml
38
circle.yml
@ -3,16 +3,13 @@ defaults: &defaults
|
|||||||
docker:
|
docker:
|
||||||
- image: library/docker:stable
|
- image: library/docker:stable
|
||||||
working_directory: /tmp/build
|
working_directory: /tmp/build
|
||||||
environment:
|
|
||||||
DOCKER_USERNAME: travisciresin
|
|
||||||
DOCKER_EMAIL: accounts+travisci+docker@resin.io
|
|
||||||
steps:
|
steps:
|
||||||
- setup_remote_docker
|
- setup_remote_docker
|
||||||
- run:
|
- run:
|
||||||
name: Check docker is running and install git
|
name: Check docker is running and install git
|
||||||
command: |
|
command: |
|
||||||
docker info
|
docker info
|
||||||
apk update && apk upgrade && apk add --nocache git
|
apk update && apk upgrade && apk add --nocache git jq
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
name: Initialize the submodules (yocto layers)
|
name: Initialize the submodules (yocto layers)
|
||||||
@ -34,9 +31,20 @@ defaults: &defaults
|
|||||||
dind=$(docker run --privileged -d builder)
|
dind=$(docker run --privileged -d builder)
|
||||||
# confirm it's running
|
# confirm it's running
|
||||||
docker ps
|
docker ps
|
||||||
|
VERSION_TAG=v$(jq .version package.json | sed 's/"//g')
|
||||||
|
if [ "${CIRCLE_BRANCH}" = "master" ]; then
|
||||||
|
EXTRA_BUILD_ARGS="-e EXTRA_TAG=$VERSION_TAG"
|
||||||
|
else
|
||||||
|
EXTRA_BUILD_ARGS=""
|
||||||
|
fi
|
||||||
# start the build for this architecture
|
# start the build for this architecture
|
||||||
docker exec -it -e TAG=${CIRCLE_BRANCH} -e ARCH=${ARCH} -e PUSH_IMAGES=${PUSH_IMAGES} ${dind} bash automation/build.sh
|
docker exec -it -e TAG=${CIRCLE_BRANCH} -e ARCH=${ARCH} -e PUSH_IMAGES=${PUSH_IMAGES} $EXTRA_BUILD_ARGS ${dind} bash automation/build.sh
|
||||||
docker exec -ti ${dind} docker images
|
if [ "${CIRCLE_BRANCH}" = "master" ] && [ "${DEPLOY_TO_RESIN}" = "true" ]; then
|
||||||
|
echo "Deploying to Resin API (staging)"
|
||||||
|
docker exec -it -e ARCH=${ARCH} -e TAG=$VERSION_TAG -e API_KEY=$STAGING_API_KEY -e API_ENDPOINT=$STAGING_API_ENDPOINT ${dind} node automation/deploy-to-resin.js
|
||||||
|
echo "Deploying to Resin API (production)"
|
||||||
|
docker exec -it -e ARCH=${ARCH} -e TAG=$VERSION_TAG -e API_KEY=$PRODUCTION_API_KEY -e API_ENDPOINT=$PRODUCTION_API_ENDPOINT ${dind} node automation/deploy-to-resin.js
|
||||||
|
fi
|
||||||
|
|
||||||
version: 2
|
version: 2
|
||||||
jobs:
|
jobs:
|
||||||
@ -47,6 +55,8 @@ jobs:
|
|||||||
DOCKER_EMAIL: accounts+travisci+docker@resin.io
|
DOCKER_EMAIL: accounts+travisci+docker@resin.io
|
||||||
ARCH: amd64
|
ARCH: amd64
|
||||||
PUSH_IMAGES: "true"
|
PUSH_IMAGES: "true"
|
||||||
|
STAGING_API_ENDPOINT: https://api.resinstaging.io
|
||||||
|
PRODUCTION_API_ENDPOINT: https://api.resin.io
|
||||||
i386:
|
i386:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
environment:
|
environment:
|
||||||
@ -54,6 +64,8 @@ jobs:
|
|||||||
DOCKER_EMAIL: accounts+travisci+docker@resin.io
|
DOCKER_EMAIL: accounts+travisci+docker@resin.io
|
||||||
ARCH: i386
|
ARCH: i386
|
||||||
PUSH_IMAGES: "true"
|
PUSH_IMAGES: "true"
|
||||||
|
STAGING_API_ENDPOINT: https://api.resinstaging.io
|
||||||
|
PRODUCTION_API_ENDPOINT: https://api.resin.io
|
||||||
armel:
|
armel:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
environment:
|
environment:
|
||||||
@ -61,6 +73,8 @@ jobs:
|
|||||||
DOCKER_EMAIL: accounts+travisci+docker@resin.io
|
DOCKER_EMAIL: accounts+travisci+docker@resin.io
|
||||||
ARCH: armel
|
ARCH: armel
|
||||||
PUSH_IMAGES: "true"
|
PUSH_IMAGES: "true"
|
||||||
|
STAGING_API_ENDPOINT: https://api.resinstaging.io
|
||||||
|
PRODUCTION_API_ENDPOINT: https://api.resin.io
|
||||||
armv7hf:
|
armv7hf:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
environment:
|
environment:
|
||||||
@ -68,6 +82,8 @@ jobs:
|
|||||||
DOCKER_EMAIL: accounts+travisci+docker@resin.io
|
DOCKER_EMAIL: accounts+travisci+docker@resin.io
|
||||||
ARCH: armv7hf
|
ARCH: armv7hf
|
||||||
PUSH_IMAGES: "true"
|
PUSH_IMAGES: "true"
|
||||||
|
STAGING_API_ENDPOINT: https://api.resinstaging.io
|
||||||
|
PRODUCTION_API_ENDPOINT: https://api.resin.io
|
||||||
aarch64:
|
aarch64:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
environment:
|
environment:
|
||||||
@ -75,6 +91,8 @@ jobs:
|
|||||||
DOCKER_EMAIL: accounts+travisci+docker@resin.io
|
DOCKER_EMAIL: accounts+travisci+docker@resin.io
|
||||||
ARCH: aarch64
|
ARCH: aarch64
|
||||||
PUSH_IMAGES: "true"
|
PUSH_IMAGES: "true"
|
||||||
|
STAGING_API_ENDPOINT: https://api.resinstaging.io
|
||||||
|
PRODUCTION_API_ENDPOINT: https://api.resin.io
|
||||||
rpi:
|
rpi:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
environment:
|
environment:
|
||||||
@ -82,10 +100,16 @@ jobs:
|
|||||||
DOCKER_EMAIL: accounts+travisci+docker@resin.io
|
DOCKER_EMAIL: accounts+travisci+docker@resin.io
|
||||||
ARCH: rpi
|
ARCH: rpi
|
||||||
PUSH_IMAGES: "true"
|
PUSH_IMAGES: "true"
|
||||||
|
STAGING_API_ENDPOINT: https://api.resinstaging.io
|
||||||
|
PRODUCTION_API_ENDPOINT: https://api.resin.io
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
version: 2
|
version: 2
|
||||||
build_them_all:
|
build_and_maybe_deploy:
|
||||||
jobs:
|
jobs:
|
||||||
- amd64
|
- amd64
|
||||||
- i386
|
- i386
|
||||||
|
- rpi
|
||||||
|
- armv7hf
|
||||||
|
- aarch64
|
||||||
|
- armel
|
||||||
|
Loading…
x
Reference in New Issue
Block a user