Merge pull request #18840 from aaronlehmann/trust-messages

Send push information to trust code out-of-band
Upstream-commit: 2892de760f412360c5effef9cfc346f2d92eaa4c
Component: engine
This commit is contained in:
Michael Crosby
2016-01-08 16:56:57 -08:00
15 changed files with 88 additions and 224 deletions

View File

@ -255,7 +255,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error {
return err
}
err = jsonmessage.DisplayJSONMessagesStream(response.Body, buildBuff, cli.outFd, cli.isTerminalOut)
err = jsonmessage.DisplayJSONMessagesStream(response.Body, buildBuff, cli.outFd, cli.isTerminalOut, nil)
if err != nil {
if jerr, ok := err.(*jsonmessage.JSONError); ok {
// If no error code is set, default to 1

View File

@ -58,7 +58,7 @@ func (cli *DockerCli) pullImageCustomOut(image string, out io.Writer) error {
}
defer responseBody.Close()
return jsonmessage.DisplayJSONMessagesStream(responseBody, out, cli.outFd, cli.isTerminalOut)
return jsonmessage.DisplayJSONMessagesStream(responseBody, out, cli.outFd, cli.isTerminalOut, nil)
}
type cidFile struct {

View File

@ -76,5 +76,5 @@ func (cli *DockerCli) CmdImport(args ...string) error {
}
defer responseBody.Close()
return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut)
return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut, nil)
}

View File

@ -37,7 +37,7 @@ func (cli *DockerCli) CmdLoad(args ...string) error {
defer response.Body.Close()
if response.JSON {
return jsonmessage.DisplayJSONMessagesStream(response.Body, cli.out, cli.outFd, cli.isTerminalOut)
return jsonmessage.DisplayJSONMessagesStream(response.Body, cli.out, cli.outFd, cli.isTerminalOut, nil)
}
_, err = io.Copy(cli.out, response.Body)

View File

@ -83,5 +83,5 @@ func (cli *DockerCli) imagePullPrivileged(authConfig types.AuthConfig, imageID,
}
defer responseBody.Close()
return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut)
return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut, nil)
}

View File

@ -49,25 +49,26 @@ func (cli *DockerCli) CmdPush(args ...string) error {
return cli.trustedPush(repoInfo, tag, authConfig, requestPrivilege)
}
return cli.imagePushPrivileged(authConfig, ref.Name(), tag, cli.out, requestPrivilege)
}
func (cli *DockerCli) imagePushPrivileged(authConfig types.AuthConfig, imageID, tag string, outputStream io.Writer, requestPrivilege client.RequestPrivilegeFunc) error {
encodedAuth, err := encodeAuthToBase64(authConfig)
responseBody, err := cli.imagePushPrivileged(authConfig, ref.Name(), tag, requestPrivilege)
if err != nil {
return err
}
defer responseBody.Close()
return jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut, nil)
}
func (cli *DockerCli) imagePushPrivileged(authConfig types.AuthConfig, imageID, tag string, requestPrivilege client.RequestPrivilegeFunc) (io.ReadCloser, error) {
encodedAuth, err := encodeAuthToBase64(authConfig)
if err != nil {
return nil, err
}
options := types.ImagePushOptions{
ImageID: imageID,
Tag: tag,
RegistryAuth: encodedAuth,
}
responseBody, err := cli.client.ImagePush(options, requestPrivilege)
if err != nil {
return err
}
defer responseBody.Close()
return jsonmessage.DisplayJSONMessagesStream(responseBody, outputStream, cli.outFd, cli.isTerminalOut)
return cli.client.ImagePush(options, requestPrivilege)
}

View File

@ -1,19 +1,16 @@
package client
import (
"bufio"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
"net"
"net/http"
"net/url"
"os"
"path"
"path/filepath"
"regexp"
"sort"
"strconv"
"time"
@ -23,8 +20,8 @@ import (
"github.com/docker/distribution/registry/client/auth"
"github.com/docker/distribution/registry/client/transport"
"github.com/docker/docker/cliconfig"
"github.com/docker/docker/pkg/ansiescape"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/distribution"
"github.com/docker/docker/pkg/jsonmessage"
flag "github.com/docker/docker/pkg/mflag"
"github.com/docker/docker/reference"
"github.com/docker/docker/registry"
@ -64,8 +61,6 @@ func isTrusted() bool {
return !untrusted
}
var targetRegexp = regexp.MustCompile(`([\S]+): digest: ([\S]+) size: ([\d]+)`)
type target struct {
reference registry.Reference
digest digest.Digest
@ -366,60 +361,31 @@ func (cli *DockerCli) trustedPull(repoInfo *registry.RepositoryInfo, ref registr
return nil
}
func targetStream(in io.Writer) (io.WriteCloser, <-chan []target) {
r, w := io.Pipe()
out := io.MultiWriter(in, w)
targetChan := make(chan []target)
go func() {
targets := []target{}
scanner := bufio.NewScanner(r)
scanner.Split(ansiescape.ScanANSILines)
for scanner.Scan() {
line := scanner.Bytes()
if matches := targetRegexp.FindSubmatch(line); len(matches) == 4 {
dgst, err := digest.ParseDigest(string(matches[2]))
if err != nil {
// Line does match what is expected, continue looking for valid lines
logrus.Debugf("Bad digest value %q in matched line, ignoring\n", string(matches[2]))
continue
}
s, err := strconv.ParseInt(string(matches[3]), 10, 64)
if err != nil {
// Line does match what is expected, continue looking for valid lines
logrus.Debugf("Bad size value %q in matched line, ignoring\n", string(matches[3]))
continue
}
targets = append(targets, target{
reference: registry.ParseReference(string(matches[1])),
digest: dgst,
size: s,
})
}
}
targetChan <- targets
}()
return ioutils.NewWriteCloserWrapper(out, w.Close), targetChan
}
func (cli *DockerCli) trustedPush(repoInfo *registry.RepositoryInfo, tag string, authConfig types.AuthConfig, requestPrivilege apiclient.RequestPrivilegeFunc) error {
streamOut, targetChan := targetStream(cli.out)
reqError := cli.imagePushPrivileged(authConfig, repoInfo.Name(), tag, streamOut, requestPrivilege)
// Close stream channel to finish target parsing
if err := streamOut.Close(); err != nil {
responseBody, err := cli.imagePushPrivileged(authConfig, repoInfo.Name(), tag, requestPrivilege)
if err != nil {
return err
}
// Check error from request
if reqError != nil {
return reqError
defer responseBody.Close()
targets := []target{}
handleTarget := func(aux *json.RawMessage) {
var pushResult distribution.PushResult
err := json.Unmarshal(*aux, &pushResult)
if err == nil && pushResult.Tag != "" && pushResult.Digest.Validate() == nil {
targets = append(targets, target{
reference: registry.ParseReference(pushResult.Tag),
digest: pushResult.Digest,
size: int64(pushResult.Size),
})
}
}
// Get target results
targets := <-targetChan
err = jsonmessage.DisplayJSONMessagesStream(responseBody, cli.out, cli.outFd, cli.isTerminalOut, handleTarget)
if err != nil {
return err
}
if tag == "" {
fmt.Fprintf(cli.out, "No tag specified, skipping trust metadata push\n")