Skip to content

Commit

Permalink
Add a way to publish images with dockerapps
Browse files Browse the repository at this point in the history
This allows an image to include references to a docker app. Details
on docker apps can be found here:

 advancedtelematic/aktualizr#1189

Signed-off-by: Andy Doan <[email protected]>
  • Loading branch information
doanac committed Apr 25, 2019
1 parent 13817d7 commit 5a0b651
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 2 deletions.
3 changes: 2 additions & 1 deletion aktualizr/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ RUN apk add --no-cache cmake git g++ make curl-dev libarchive-dev libsodium-dev
FROM alpine:latest
WORKDIR /root/

RUN apk add --no-cache bash glib libarchive libcurl libsodium nss openjdk8-jre-base ostree
RUN apk add --no-cache bash glib libarchive libcurl libsodium nss openjdk8-jre-base ostree python3 py3-requests
COPY ota-publish.sh /usr/bin/ota-publish
COPY ota-dockerapp.py /usr/bin/ota-dockerapp
COPY test.sh /test.sh
COPY --from=0 /root/aktualizr/build-git/src/sota_tools/garage-check /usr/bin/
COPY --from=0 /root/aktualizr/build-git/src/sota_tools/garage-deploy /usr/bin/
Expand Down
93 changes: 93 additions & 0 deletions aktualizr/ota-dockerapp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/usr/bin/python3
#
# Copyright (c) 2019 Foundries.io
# SPDX-License-Identifier: Apache-2.0
#
import argparse
import json
import os
import sys

from zipfile import ZipFile

import requests


def get_token(oauth_server, client, secret):
data = {'grant_type': 'client_credentials'}
url = oauth_server
if url[-1] != '/':
url += '/'
url += 'token'
r = requests.post(url, data=data, auth=(client, secret))
r.raise_for_status()
return r.json()['access_token']


def publish(args):
with ZipFile(args.credentials) as zf:
with zf.open('tufrepo.url') as f:
repourl = f.read().strip().decode()

with zf.open('treehub.json') as f:
oauth2 = json.load(f)['oauth2']

if repourl[-1] != '/':
repourl += '/'

token = get_token(
oauth2['server'], oauth2['client_id'], oauth2['client_secret'])

app = os.path.basename(args.dockerapp.name).replace('.dockerapp', '')
url = repourl + 'api/v1/user_repo/targets/' + app + '-' + args.version
r = requests.put(url,
params={'name': app, 'version': args.version},
files={'file': ('filename', args.dockerapp)},
headers={'Authorization: Bearer ' + token})
if r.status_code != 201:
sys.exit('Unable to create %s: HTTP_%d\n%s' % (
url, r.status_code, r.text))


def merge(args):
with open(args.targets_json) as f:
targets = json.load(f)['targets']

app = os.path.basename(args.dockerapp.replace('.dockerapp', ''))
name = app + '-' + args.version
assert name in targets, '%s not in targets' % name

img = targets[args.machine + '-' + args.ostree_branch + '-' + args.version]
img['custom']['docker_apps'] = {app: {'filename': name}}

with open(args.targets_json, 'w') as f:
json.dump(targets, f, indent=2)


def get_args():
parser = argparse.ArgumentParser(
'Manage dockerapps on the OTA Connect reposerver')

cmds = parser.add_subparsers(title='Commands')

p = cmds.add_parser('publish')
p.set_defaults(func=publish)
p.add_argument('dockerapp', type=argparse.FileType('r'))
p.add_argument('credentials', type=argparse.FileType('rb'))
p.add_argument('version')

p = cmds.add_parser('merge')
p.set_defaults(func=merge)
p.add_argument('targets_json')
p.add_argument('dockerapp')
p.add_argument('version')
p.add_argument('machine')
p.add_argument('ostree_branch')

return parser.parse_args()


if __name__ == '__main__':
args = get_args()
if getattr(args, 'func', None):
args.func(args)
15 changes: 14 additions & 1 deletion aktualizr/ota-publish.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ OPTIONS:
-v Optional version to add to the image information
-u Optional url to add to the image information
-r OSTree repository (e.g. ostree_repo directory or ostree_repo.tar.bz2 archive)
-a Optional dockerapp to include with image
EOF
}

Expand All @@ -32,15 +33,17 @@ function fail() {
exit -1
}

apps=""
function get_opts() {
declare -r optstr="c:m:r:u:v:h"
declare -r optstr="a:c:m:r:u:v:h"
while getopts ${optstr} opt; do
case ${opt} in
c) credentials=${OPTARG} ;;
m) machine=${OPTARG} ;;
r) ostree_repo=${OPTARG} ;;
u) url=${OPTARG} ;;
v) version=${OPTARG} ;;
a) apps="${apps} ${OPTARG}" ;;
h) usage; exit 0 ;;
*) fail ;;
esac
Expand Down Expand Up @@ -87,6 +90,11 @@ garage-push --repo ${ostree_repo} --ref ${ostree_branch} --credentials ${credent
echo "Initializing local TUF repository"
garage-sign init --repo ${tufrepo} --home-dir ${otarepo} --credentials ${credentials}

for app in $apps ; do
echo "Adding docker app to tuf repo: $app"
ota-dockerapp publish $app $credentials $version
done

echo "Pulling TUF targets from the remote TUF repository"
garage-sign targets pull --repo ${tufrepo} --home-dir ${otarepo}

Expand All @@ -95,6 +103,11 @@ garage-sign targets add --repo ${tufrepo} --home-dir ${otarepo} --name ${ostree_
--format OSTREE --version "${version}" --length 0 --url "${url}" \
--sha256 ${ostree_hash} --hardwareids ${machine}

for app in $apps ; do
echo "Merging dockerapp into target custom data: $app"
ota-dockerapp merge ${tufrepo}/roles/unsigned/targets.json $app $version $machine ${ostree_branch}
done

echo "Signing local TUF targets"
garage-sign targets sign --repo ${tufrepo} --home-dir ${otarepo} --key-name targets

Expand Down

0 comments on commit 5a0b651

Please sign in to comment.