2017-02-11 00:48:15 +08:00
|
|
|
package buildah
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"runtime"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/Sirupsen/logrus"
|
|
|
|
docker "github.com/docker/docker/image"
|
|
|
|
ociv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
|
|
|
)
|
|
|
|
|
|
|
|
func copyDockerImageConfig(dimage *docker.Image) (ociv1.Image, error) {
|
|
|
|
image := ociv1.Image{
|
2017-02-14 00:44:47 +08:00
|
|
|
Created: dimage.Created.UTC(),
|
2017-02-11 00:48:15 +08:00
|
|
|
Author: dimage.Author,
|
|
|
|
Architecture: dimage.Architecture,
|
|
|
|
OS: dimage.OS,
|
|
|
|
Config: ociv1.ImageConfig{
|
|
|
|
User: dimage.Config.User,
|
|
|
|
ExposedPorts: map[string]struct{}{},
|
|
|
|
Env: dimage.Config.Env,
|
|
|
|
Entrypoint: dimage.Config.Entrypoint,
|
|
|
|
Cmd: dimage.Config.Cmd,
|
|
|
|
Volumes: dimage.Config.Volumes,
|
|
|
|
WorkingDir: dimage.Config.WorkingDir,
|
|
|
|
Labels: dimage.Config.Labels,
|
|
|
|
},
|
|
|
|
RootFS: ociv1.RootFS{
|
|
|
|
Type: "",
|
|
|
|
DiffIDs: []string{},
|
|
|
|
},
|
|
|
|
History: []ociv1.History{},
|
|
|
|
}
|
|
|
|
for port, what := range dimage.Config.ExposedPorts {
|
|
|
|
image.Config.ExposedPorts[string(port)] = what
|
|
|
|
}
|
|
|
|
RootFS := docker.RootFS{}
|
|
|
|
if dimage.RootFS != nil {
|
|
|
|
RootFS = *dimage.RootFS
|
|
|
|
}
|
|
|
|
if RootFS.Type == docker.TypeLayers {
|
|
|
|
image.RootFS.Type = docker.TypeLayers
|
|
|
|
for _, id := range RootFS.DiffIDs {
|
|
|
|
image.RootFS.DiffIDs = append(image.RootFS.DiffIDs, id.String())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, history := range dimage.History {
|
2017-02-14 00:44:47 +08:00
|
|
|
created := history.Created.UTC()
|
2017-02-11 00:48:15 +08:00
|
|
|
ohistory := ociv1.History{
|
2017-02-14 00:44:47 +08:00
|
|
|
Created: created,
|
2017-02-11 00:48:15 +08:00
|
|
|
CreatedBy: history.CreatedBy,
|
|
|
|
Author: history.Author,
|
|
|
|
Comment: history.Comment,
|
|
|
|
EmptyLayer: history.EmptyLayer,
|
|
|
|
}
|
|
|
|
image.History = append(image.History, ohistory)
|
|
|
|
}
|
|
|
|
return image, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (b *Builder) updatedConfig() []byte {
|
|
|
|
image := ociv1.Image{}
|
|
|
|
dimage := docker.Image{}
|
|
|
|
if len(b.Config) > 0 {
|
|
|
|
// Try to parse the image configuration. If we fail start over from scratch.
|
|
|
|
if err := json.Unmarshal(b.Config, &dimage); err == nil && dimage.DockerVersion != "" {
|
|
|
|
if image, err = copyDockerImageConfig(&dimage); err != nil {
|
|
|
|
image = ociv1.Image{}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if err := json.Unmarshal(b.Config, &image); err != nil {
|
|
|
|
image = ociv1.Image{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-02-14 00:44:47 +08:00
|
|
|
image.Created = time.Now().UTC()
|
2017-02-11 00:48:15 +08:00
|
|
|
if image.Architecture == "" {
|
|
|
|
image.Architecture = runtime.GOARCH
|
|
|
|
}
|
|
|
|
if image.OS == "" {
|
|
|
|
image.OS = runtime.GOOS
|
|
|
|
}
|
|
|
|
if b.Architecture != "" {
|
|
|
|
image.Architecture = b.Architecture
|
|
|
|
}
|
|
|
|
if b.OS != "" {
|
|
|
|
image.OS = b.OS
|
|
|
|
}
|
|
|
|
if b.Maintainer != "" {
|
|
|
|
image.Author = b.Maintainer
|
|
|
|
}
|
|
|
|
if b.User != "" {
|
|
|
|
image.Config.User = b.User
|
|
|
|
}
|
2017-02-14 00:44:47 +08:00
|
|
|
if len(b.Volumes) > 0 {
|
|
|
|
for _, volSpec := range b.Volumes {
|
|
|
|
image.Config.Volumes[volSpec] = struct{}{}
|
|
|
|
}
|
|
|
|
}
|
2017-02-11 00:48:15 +08:00
|
|
|
if b.Workdir != "" {
|
|
|
|
image.Config.WorkingDir = b.Workdir
|
|
|
|
}
|
|
|
|
if len(b.Env) > 0 {
|
2017-04-04 05:44:23 +08:00
|
|
|
image.Config.Env = append(image.Config.Env, b.Env...)
|
2017-02-11 00:48:15 +08:00
|
|
|
}
|
|
|
|
if len(b.Cmd) > 0 {
|
|
|
|
image.Config.Cmd = b.Cmd
|
|
|
|
}
|
|
|
|
if len(b.Entrypoint) > 0 {
|
|
|
|
image.Config.Entrypoint = b.Entrypoint
|
|
|
|
}
|
|
|
|
if len(b.Expose) > 0 {
|
|
|
|
if image.Config.ExposedPorts == nil {
|
|
|
|
image.Config.ExposedPorts = make(map[string]struct{})
|
|
|
|
}
|
2017-02-11 03:45:06 +08:00
|
|
|
for k := range b.Expose {
|
2017-02-11 00:48:15 +08:00
|
|
|
image.Config.ExposedPorts[k] = struct{}{}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(b.Labels) > 0 {
|
|
|
|
if image.Config.Labels == nil {
|
|
|
|
image.Config.Labels = make(map[string]string)
|
|
|
|
}
|
|
|
|
for k, v := range b.Labels {
|
|
|
|
image.Config.Labels[k] = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
updatedImageConfig, err := json.Marshal(&image)
|
|
|
|
if err != nil {
|
|
|
|
logrus.Errorf("error exporting updated image configuration, using original configuration")
|
|
|
|
return b.Config
|
|
|
|
}
|
|
|
|
return updatedImageConfig
|
|
|
|
}
|
2017-03-28 15:06:13 +08:00
|
|
|
|
|
|
|
// UpdatedEnv returns the environment list from the source image, with the
|
|
|
|
// builder's own list appended to it.
|
|
|
|
func (b *Builder) UpdatedEnv() []string {
|
|
|
|
config := b.updatedConfig()
|
|
|
|
image := ociv1.Image{}
|
|
|
|
if err := json.Unmarshal(config, &image); err != nil {
|
|
|
|
logrus.Errorf("error parsing updated image information")
|
|
|
|
return []string{}
|
|
|
|
}
|
|
|
|
return append(image.Config.Env, b.Env...)
|
|
|
|
}
|