| 
									
										
										
										
											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) { | 
					
						
							|  |  |  | 	created, err := dimage.Created.UTC().MarshalText() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		created = []byte{} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	image := ociv1.Image{ | 
					
						
							|  |  |  | 		Created:      string(created), | 
					
						
							|  |  |  | 		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 { | 
					
						
							|  |  |  | 		created, err := history.Created.UTC().MarshalText() | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			created = []byte{} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ohistory := ociv1.History{ | 
					
						
							|  |  |  | 			Created:    string(created), | 
					
						
							|  |  |  | 			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{} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	createdBytes, err := time.Now().UTC().MarshalText() | 
					
						
							|  |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		image.Created = string(createdBytes) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	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 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if b.Workdir != "" { | 
					
						
							|  |  |  | 		image.Config.WorkingDir = b.Workdir | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if len(b.Env) > 0 { | 
					
						
							|  |  |  | 		for _, envSpec := range b.Env { | 
					
						
							|  |  |  | 			image.Config.Env = append(image.Config.Env, envSpec) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	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 | 
					
						
							|  |  |  | } |