Embed scripts/push-manifest.sh into linuxkit tool

This is a bit gross, but hopefully this script will be written in go sooner
rather than later and in the meantime this avoids the need to install yet
another tool on user's systems (and get it into brew etc).

Checkin the result of `go:generate` for now. Once there are no more users of
push-manifest.sh it can be moved alongside the go code (if it hasn't been
rewritten in go along the way).

Signed-off-by: Ian Campbell <ijc@docker.com>
This commit is contained in:
Ian Campbell 2017-10-06 14:00:22 +01:00
parent c84c997383
commit 3141ca0bef
3 changed files with 116 additions and 5 deletions

View File

@ -1,5 +1,5 @@
.PHONY: default all
default: bin/moby bin/linuxkit bin/rtf bin/linuxkit-push-manifest
default: bin/moby bin/linuxkit bin/rtf
all: default
VERSION="0.0" # dummy for now
@ -20,9 +20,6 @@ endif
PREFIX?=/usr/local/
bin/linuxkit-push-manifest: scripts/push-manifest.sh | bin
cp $< $@
MOBY_REPO=https://github.com/moby/tool.git
MOBY_COMMIT=177969dc4a0fb843f635e45ab8e87d2cd2c531cd
MOBY_VERSION=0.0

View File

@ -2,6 +2,8 @@ package pkglib
// Thin wrappers around Docker CLI invocations
//go:generate ./gen
import (
"fmt"
"os"
@ -66,7 +68,7 @@ func (dr dockerRunner) pushWithManifest(img, suffix string) error {
dctArg = "1"
}
cmd := exec.Command("linuxkit-push-manifest", img, dctArg)
cmd := exec.Command("/bin/sh", "-c", manifestPushScript, "manifest-push-script", img, dctArg)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if debugDockerCommands {

View File

@ -0,0 +1,112 @@
package pkglib
const manifestPushScript = `
#! /bin/sh
set -e
# This script pushes a multiarch manifest for packages and signs it.
#
# The TARGET must be of the form <org>/<image>:<tag> and this is what
# the manifest is pushed to. It assumes that there is are images of
# the form <org>/<image>:<tag>-<arch> already on hub.
#
# If TRUST is not set, the manifest will not be signed.
#
# For signing, DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE must be set.
# This should all be replaced with 'docker manifest' once it lands.
TARGET=$1
TRUST=$2
REPO=$(echo "$TARGET" | cut -d':' -f1)
TAG=$(echo "$TARGET" | cut -d':' -f2)
# Work out credentials. On macOS they are needed for manifest-tool and
# we need them for notary on all platforms.
case $(uname -s) in
Darwin)
CRED=$(echo "https://index.docker.io/v1/" | /Applications/Docker.app/Contents/Resources/bin/docker-credential-osxkeychain.bin get)
USER=$(echo "$CRED" | jq -r '.Username')
PASS=$(echo "$CRED" | jq -r '.Secret')
MT_ARGS="--username $USER --password $PASS"
;;
Linux)
CRED=$(cat ~/.docker/config.json | jq -r '.auths."https://index.docker.io/v1/".auth' | base64 -d -)
USER=$(echo $CRED | cut -d ':' -f 1)
PASS=$(echo $CRED | cut -d ':' -f 2-)
# manifest-tool can use docker credentials directly
MT_ARGS=
;;
*)
echo "Unsupported platform"
exit 1
;;
esac
# Push manifest list
OUT=$(manifest-tool $MT_ARGS push from-args \
--ignore-missing \
--platforms linux/amd64,linux/arm64 \
--template "$TARGET"-ARCH \
--target "$TARGET")
echo "$OUT"
if [ -z "$TRUST" ]; then
echo "Not signing $TARGET"
exit 0
fi
# Extract sha256 and length from the manifest-tool output
SHA256=$(echo "$OUT" | cut -d' ' -f2 | cut -d':' -f2)
LEN=$(echo "$OUT" | cut -d' ' -f3)
# Notary requires a PTY for username/password so use expect for that.
export NOTARY_DELEGATION_PASSPHRASE="$DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE"
NOTARY_CMD="notary -s https://notary.docker.io -d $HOME/.docker/trust addhash \
-p docker.io/$REPO $TAG $LEN --sha256 $SHA256 \
-r targets/releases"
echo '
spawn '"$NOTARY_CMD"'
set pid [exp_pid]
set timeout 60
expect {
timeout {
puts "Expected username prompt"
exec kill -9 $pid
exit 1
}
"username: " {
send "'"$USER"'\n"
}
}
expect {
timeout {
puts "Expected password prompt"
exec kill -9 $pid
exit 1
}
"password: " {
send "'"$PASS"'\n"
}
}
expect {
timeout {
puts "Expected password prompt"
exec kill -9 $pid
exit 1
}
eof {
}
}
set waitval [wait -i $spawn_id]
set exval [lindex $waitval 3]
exit $exval
' | expect -f -
echo
echo "New signed multi-arch image: $REPO:$TAG"
echo
`