Fix read only output when defined in a label

Also do some code cleanup.

Related to #131 we need to read the OCI config to find if the container
is read only, not rely on the yaml, as it may just be set in the label.

Signed-off-by: Justin Cormack <justin.cormack@docker.com>
This commit is contained in:
Justin Cormack 2017-07-28 14:34:18 +01:00
parent 51005b42c5
commit 3dec6855e0
2 changed files with 32 additions and 39 deletions

View File

@ -10,6 +10,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path" "path"
"path/filepath"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@ -121,6 +122,26 @@ func enforceContentTrust(fullImageName string, config *TrustConfig) bool {
return false return false
} }
func outputImage(image Image, section string, prefix string, m Moby, idMap map[string]uint32, pull bool, iw *tar.Writer) error {
log.Infof(" Create OCI config for %s", image.Image)
useTrust := enforceContentTrust(image.Image, &m.Trust)
oci, err := ConfigToOCI(image, useTrust, idMap)
if err != nil {
return fmt.Errorf("Failed to create OCI spec for %s: %v", image.Image, err)
}
config, err := json.MarshalIndent(oci, "", " ")
if err != nil {
return fmt.Errorf("Failed to create config for %s: %v", image.Image, err)
}
path := filepath.Join("containers", section, prefix+image.Name)
readonly := oci.Root.Readonly
err = ImageBundle(path, image.Image, config, iw, useTrust, pull, readonly)
if err != nil {
return fmt.Errorf("Failed to extract root filesystem for %s: %v", image.Image, err)
}
return nil
}
// Build performs the actual build process // Build performs the actual build process
func Build(m Moby, w io.Writer, pull bool, tp string) error { func Build(m Moby, w io.Writer, pull bool, tp string) error {
if MobyDir == "" { if MobyDir == "" {
@ -178,18 +199,9 @@ func Build(m Moby, w io.Writer, pull bool, tp string) error {
log.Infof("Add onboot containers:") log.Infof("Add onboot containers:")
} }
for i, image := range m.Onboot { for i, image := range m.Onboot {
log.Infof(" Create OCI config for %s", image.Image)
useTrust := enforceContentTrust(image.Image, &m.Trust)
config, err := ConfigToOCI(image, useTrust, idMap)
if err != nil {
return fmt.Errorf("Failed to create config.json for %s: %v", image.Image, err)
}
so := fmt.Sprintf("%03d", i) so := fmt.Sprintf("%03d", i)
path := "containers/onboot/" + so + "-" + image.Name if err := outputImage(image, "onboot", so+"-", m, idMap, pull, iw); err != nil {
readonly := image.Readonly != nil && *image.Readonly return err
err = ImageBundle(path, image.Image, config, iw, useTrust, pull, readonly)
if err != nil {
return fmt.Errorf("Failed to extract root filesystem for %s: %v", image.Image, err)
} }
} }
@ -197,18 +209,9 @@ func Build(m Moby, w io.Writer, pull bool, tp string) error {
log.Infof("Add onshutdown containers:") log.Infof("Add onshutdown containers:")
} }
for i, image := range m.Onshutdown { for i, image := range m.Onshutdown {
log.Infof(" Create OCI config for %s", image.Image)
useTrust := enforceContentTrust(image.Image, &m.Trust)
config, err := ConfigToOCI(image, useTrust, idMap)
if err != nil {
return fmt.Errorf("Failed to create config.json for %s: %v", image.Image, err)
}
so := fmt.Sprintf("%03d", i) so := fmt.Sprintf("%03d", i)
path := "containers/onshutdown/" + so + "-" + image.Name if err := outputImage(image, "onshutdown", so+"-", m, idMap, pull, iw); err != nil {
readonly := image.Readonly != nil && *image.Readonly return err
err = ImageBundle(path, image.Image, config, iw, useTrust, pull, readonly)
if err != nil {
return fmt.Errorf("Failed to extract root filesystem for %s: %v", image.Image, err)
} }
} }
@ -216,17 +219,8 @@ func Build(m Moby, w io.Writer, pull bool, tp string) error {
log.Infof("Add service containers:") log.Infof("Add service containers:")
} }
for _, image := range m.Services { for _, image := range m.Services {
log.Infof(" Create OCI config for %s", image.Image) if err := outputImage(image, "services", "", m, idMap, pull, iw); err != nil {
useTrust := enforceContentTrust(image.Image, &m.Trust) return err
config, err := ConfigToOCI(image, useTrust, idMap)
if err != nil {
return fmt.Errorf("Failed to create config.json for %s: %v", image.Image, err)
}
path := "containers/services/" + image.Name
readonly := image.Readonly != nil && *image.Readonly
err = ImageBundle(path, image.Image, config, iw, useTrust, pull, readonly)
if err != nil {
return fmt.Errorf("Failed to extract root filesystem for %s: %v", image.Image, err)
} }
} }

View File

@ -1,7 +1,6 @@
package moby package moby
import ( import (
"encoding/json"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
@ -263,25 +262,25 @@ func NewImage(config []byte) (Image, error) {
} }
// ConfigToOCI converts a config specification to an OCI config file // ConfigToOCI converts a config specification to an OCI config file
func ConfigToOCI(image Image, trust bool, idMap map[string]uint32) ([]byte, error) { func ConfigToOCI(image Image, trust bool, idMap map[string]uint32) (specs.Spec, error) {
// TODO pass through same docker client to all functions // TODO pass through same docker client to all functions
cli, err := dockerClient() cli, err := dockerClient()
if err != nil { if err != nil {
return []byte{}, err return specs.Spec{}, err
} }
inspect, err := dockerInspectImage(cli, image.Image, trust) inspect, err := dockerInspectImage(cli, image.Image, trust)
if err != nil { if err != nil {
return []byte{}, err return specs.Spec{}, err
} }
oci, err := ConfigInspectToOCI(image, inspect, idMap) oci, err := ConfigInspectToOCI(image, inspect, idMap)
if err != nil { if err != nil {
return []byte{}, err return specs.Spec{}, err
} }
return json.MarshalIndent(oci, "", " ") return oci, nil
} }
func defaultMountpoint(tp string) string { func defaultMountpoint(tp string) string {