Skip to content

Commit

Permalink
archiving state when running containerized
Browse files Browse the repository at this point in the history
  • Loading branch information
kcq committed Nov 13, 2019
1 parent da3e9da commit 8b46e57
Show file tree
Hide file tree
Showing 12 changed files with 266 additions and 60 deletions.
5 changes: 4 additions & 1 deletion build/package/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
FROM alpine
FROM scratch
COPY dist_linux /bin
VOLUME /bin/.docker-slim-state
ENTRYPOINT ["/bin/docker-slim"]


40 changes: 35 additions & 5 deletions internal/app/master/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const (
const (
FlagCheckVersion = "check-version"
FlagDebug = "debug"
FlagInContainer = "in-container"
FlagCommandReport = "report"
FlagVerbose = "verbose"
FlagLogLevel = "log-level"
Expand All @@ -45,6 +46,7 @@ const (
FlagTLSCertPath = "tls-cert-path"
FlagHost = "host"
FlagStatePath = "state-path"
FlagArchiveState = "archive-state"
FlagRemoveFileArtifacts = "remove-file-artifacts"
FlagCopyMetaArtifacts = "copy-meta-artifacts"
FlagHTTPProbe = "http-probe"
Expand Down Expand Up @@ -155,6 +157,15 @@ func init() {
Value: "",
Usage: "DockerSlim state base path",
},
cli.BoolFlag{
Name: FlagInContainer,
Usage: "DockerSlim is running in a container",
},
cli.StringFlag{
Name: FlagArchiveState,
Value: "",
Usage: "archive DockerSlim state to the selected Docker volume (default volume - docker-slim-state). By default, enabled when DockerSlim is running in a container (disabled otherwise). Set it to \"off\" to disable explicitly.",
},
}

app.Before = func(ctx *cli.Context) error {
Expand Down Expand Up @@ -498,8 +509,10 @@ func init() {
Aliases: []string{"v"},
Usage: "Shows docker-slim and docker version information",
Action: func(ctx *cli.Context) error {
doDebug := ctx.GlobalBool(FlagDebug)
inContainer := isInContainer(ctx.GlobalBool(FlagInContainer))
clientConfig := getDockerClientConfig(ctx)
commands.OnVersion(clientConfig)
commands.OnVersion(doDebug, inContainer, clientConfig)
return nil
},
},
Expand All @@ -513,9 +526,11 @@ func init() {
Action: func(ctx *cli.Context) error {
doDebug := ctx.GlobalBool(FlagDebug)
statePath := ctx.GlobalString(FlagStatePath)
inContainer := isInContainer(ctx.GlobalBool(FlagInContainer))
archiveState := archiveState(ctx.GlobalString(FlagArchiveState), inContainer)
doShowProgress := ctx.Bool("show-progress")

commands.OnUpdate(doDebug, statePath, doShowProgress)
commands.OnUpdate(doDebug, statePath, archiveState, inContainer, doShowProgress)
return nil
},
},
Expand All @@ -532,16 +547,21 @@ func init() {

doCheckVersion := ctx.GlobalBool(FlagCheckVersion)

doDebug := ctx.GlobalBool(FlagDebug)
statePath := ctx.GlobalString(FlagStatePath)
inContainer := isInContainer(ctx.GlobalBool(FlagInContainer))
archiveState := archiveState(ctx.GlobalString(FlagArchiveState), inContainer)

imageRef := ctx.Args().First()
clientConfig := getDockerClientConfig(ctx)

commands.OnInfo(
doCheckVersion,
ctx.GlobalString(FlagCommandReport),
ctx.GlobalBool(FlagDebug),
doDebug,
statePath,
archiveState,
inContainer,
clientConfig,
imageRef)
return nil
Expand Down Expand Up @@ -619,7 +639,10 @@ func init() {

doCheckVersion := ctx.GlobalBool(FlagCheckVersion)

doDebug := ctx.GlobalBool(FlagDebug)
statePath := ctx.GlobalString(FlagStatePath)
inContainer := isInContainer(ctx.GlobalBool(FlagInContainer))
archiveState := archiveState(ctx.GlobalString(FlagArchiveState), inContainer)

imageRef := ctx.Args().First()
clientConfig := getDockerClientConfig(ctx)
Expand Down Expand Up @@ -730,8 +753,10 @@ func init() {
commands.OnBuild(
doCheckVersion,
ctx.GlobalString(FlagCommandReport),
ctx.GlobalBool(FlagDebug),
doDebug,
statePath,
archiveState,
inContainer,
clientConfig,
buildFromDockerfile,
imageRef,
Expand Down Expand Up @@ -814,7 +839,10 @@ func init() {

doCheckVersion := ctx.GlobalBool(FlagCheckVersion)

doDebug := ctx.GlobalBool(FlagDebug)
statePath := ctx.GlobalString(FlagStatePath)
inContainer := isInContainer(ctx.GlobalBool(FlagInContainer))
archiveState := archiveState(ctx.GlobalString(FlagArchiveState), inContainer)

imageRef := ctx.Args().First()
clientConfig := getDockerClientConfig(ctx)
Expand Down Expand Up @@ -912,8 +940,10 @@ func init() {
commands.OnProfile(
doCheckVersion,
ctx.GlobalString(FlagCommandReport),
ctx.GlobalBool(FlagDebug),
doDebug,
statePath,
archiveState,
inContainer,
clientConfig,
imageRef,
doHTTPProbe,
Expand Down
15 changes: 12 additions & 3 deletions internal/app/master/commands/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ func OnBuild(
cmdReportLocation string,
doDebug bool,
statePath string,
archiveState string,
inContainer bool,
clientConfig *config.DockerClient,
buildFromDockerfile string,
imageRef string,
Expand Down Expand Up @@ -158,8 +160,9 @@ func OnBuild(
err = imageInspector.Inspect()
errutil.FailOn(err)

localVolumePath, artifactLocation, statePath := fsutil.PrepareImageStateDirs(statePath, imageInspector.ImageInfo.ID)
localVolumePath, artifactLocation, statePath, stateKey := fsutil.PrepareImageStateDirs(statePath, imageInspector.ImageInfo.ID)
imageInspector.ArtifactLocation = artifactLocation
logger.Debugf("localVolumePath=%v, artifactLocation=%v, statePath=%v, stateKey=%v", localVolumePath, artifactLocation, statePath, stateKey)

fmt.Printf("docker-slim[build]: info=image id=%v size.bytes=%v size.human=%v\n",
imageInspector.ImageInfo.ID,
Expand Down Expand Up @@ -217,6 +220,7 @@ func OnBuild(
includeExes,
doIncludeShell,
doDebug,
inContainer,
true,
"docker-slim[build]:")
errutil.FailOn(err)
Expand Down Expand Up @@ -432,14 +436,19 @@ func OnBuild(
}
if !copyMetaArtifacts(logger,
toCopy,
imageInspector.ArtifactLocation, copyMetaArtifactsLocation) {
artifactLocation, copyMetaArtifactsLocation) {
fmt.Println("docker-slim[build]: info=artifacts message='could not copy meta artifacts'")
}
}

if err := doArchiveState(logger, client, artifactLocation, archiveState, stateKey); err != nil {
fmt.Println("docker-slim[build]: info=state message='could not archive state'")
logger.Errorf("error archiving state - %v", err)
}

if doRmFileArtifacts {
logger.Info("removing temporary artifacts...")
err = fsutil.Remove(artifactLocation) //TODO: remove only the "files" subdirectory
err = fsutil.Remove(artifactLocation)
errutil.WarnOn(err)
}

Expand Down
37 changes: 37 additions & 0 deletions internal/app/master/commands/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,46 @@ import (
"github.com/fsouza/go-dockerclient"
log "github.com/sirupsen/logrus"

"github.com/docker-slim/docker-slim/pkg/util/dockerutil"
"github.com/docker-slim/docker-slim/pkg/util/fsutil"
)

const (
ImagesStateRootPath = "images"
)

func doArchiveState(logger *log.Entry, client *docker.Client, localStatePath, volumeName, stateKey string) error {
if volumeName == "" {
return nil
}

err := dockerutil.HasVolume(client, volumeName)
switch {
case err == nil:
logger.Debugf("archiveState: already have volume = %v", volumeName)
case err == dockerutil.ErrNotFound:
logger.Debugf("archiveState: no volume yet = %v", volumeName)
if dockerutil.HasEmptyImage(client) == dockerutil.ErrNotFound {
err := dockerutil.BuildEmptyImage(client)
if err != nil {
logger.Debugf("archiveState: dockerutil.BuildEmptyImage() - error = %v", err)
return err
}
}

err = dockerutil.CreateVolumeWithData(client, "", volumeName, nil)
if err != nil {
logger.Debugf("archiveState: dockerutil.CreateVolumeWithData() - error = %v", err)
return err
}
default:
logger.Debugf("archiveState: dockerutil.HasVolume() - error = %v", err)
return err
}

return dockerutil.CopyToVolume(client, volumeName, localStatePath, ImagesStateRootPath, stateKey)
}

func copyMetaArtifacts(logger *log.Entry, names []string, artifactLocation, targetLocation string) bool {
if targetLocation != "" {
if !fsutil.Exists(artifactLocation) {
Expand Down
5 changes: 4 additions & 1 deletion internal/app/master/commands/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ func OnInfo(
cmdReportLocation string,
doDebug bool,
statePath string,
archiveState string,
inContainer bool,
clientConfig *config.DockerClient,
imageRef string) {
logger := log.WithFields(log.Fields{"app": "docker-slim", "command": "info"})
Expand Down Expand Up @@ -53,8 +55,9 @@ func OnInfo(
err = imageInspector.Inspect()
errutil.FailOn(err)

_, artifactLocation, statePath := fsutil.PrepareImageStateDirs(statePath, imageInspector.ImageInfo.ID)
localVolumePath, artifactLocation, statePath, stateKey := fsutil.PrepareImageStateDirs(statePath, imageInspector.ImageInfo.ID)
imageInspector.ArtifactLocation = artifactLocation
logger.Debugf("localVolumePath=%v, artifactLocation=%v, statePath=%v, stateKey=%v", localVolumePath, artifactLocation, statePath, stateKey)

fmt.Printf("docker-slim[info]: info=image id=%v size.bytes=%v size.human=%v\n",
imageInspector.ImageInfo.ID,
Expand Down
15 changes: 12 additions & 3 deletions internal/app/master/commands/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ func OnProfile(
cmdReportLocation string,
doDebug bool,
statePath string,
archiveState string,
inContainer bool,
clientConfig *config.DockerClient,
imageRef string,
doHTTPProbe bool,
Expand Down Expand Up @@ -91,8 +93,9 @@ func OnProfile(
err = imageInspector.Inspect()
errutil.FailOn(err)

localVolumePath, artifactLocation, statePath := fsutil.PrepareImageStateDirs(statePath, imageInspector.ImageInfo.ID)
localVolumePath, artifactLocation, statePath, stateKey := fsutil.PrepareImageStateDirs(statePath, imageInspector.ImageInfo.ID)
imageInspector.ArtifactLocation = artifactLocation
logger.Debugf("localVolumePath=%v, artifactLocation=%v, statePath=%v, stateKey=%v", localVolumePath, artifactLocation, statePath, stateKey)

fmt.Printf("docker-slim[profile]: info=image id=%v size.bytes=%v size.human=%v\n",
imageInspector.ImageInfo.ID,
Expand Down Expand Up @@ -128,6 +131,7 @@ func OnProfile(
includeExes,
doIncludeShell,
doDebug,
inContainer,
true,
"docker-slim[profile]:")
errutil.FailOn(err)
Expand Down Expand Up @@ -222,14 +226,19 @@ func OnProfile(
}
if !copyMetaArtifacts(logger,
toCopy,
imageInspector.ArtifactLocation, copyMetaArtifactsLocation) {
artifactLocation, copyMetaArtifactsLocation) {
fmt.Println("docker-slim[profile]: info=artifacts message='could not copy meta artifacts'")
}
}

if err := doArchiveState(logger, client, artifactLocation, archiveState, stateKey); err != nil {
fmt.Println("docker-slim[profile]: info=state message='could not archive state'")
logger.Errorf("error archiving state - %v", err)
}

if doRmFileArtifacts {
logger.Info("removing temporary artifacts...")
err = fsutil.Remove(artifactLocation) //TODO: remove only the "files" subdirectory
err = fsutil.Remove(artifactLocation)
errutil.WarnOn(err)
}

Expand Down
2 changes: 1 addition & 1 deletion internal/app/master/commands/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ import (
)

// OnUpdate implements the 'update' docker-slim command
func OnUpdate(doDebug bool, statePath string, doShowProgress bool) {
func OnUpdate(doDebug bool, statePath, archiveState string, inContainer bool, doShowProgress bool) {
update.Run(doDebug, statePath, doShowProgress)
}
2 changes: 1 addition & 1 deletion internal/app/master/commands/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
)

// OnVersion implements the 'version' docker-slim command
func OnVersion(clientConfig *config.DockerClient) {
func OnVersion(doDebug, inContainer bool, clientConfig *config.DockerClient) {
client := dockerclient.New(clientConfig)
version.Print(client, true)
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"github.com/docker-slim/docker-slim/internal/app/master/inspectors/image"
"github.com/docker-slim/docker-slim/internal/app/master/security/apparmor"
"github.com/docker-slim/docker-slim/internal/app/master/security/seccomp"
"github.com/docker-slim/docker-slim/pkg/env"
"github.com/docker-slim/docker-slim/pkg/ipc/channel"
"github.com/docker-slim/docker-slim/pkg/ipc/command"
"github.com/docker-slim/docker-slim/pkg/ipc/event"
Expand Down Expand Up @@ -140,6 +139,7 @@ func NewInspector(
includeExes map[string]bool,
doIncludeShell bool,
doDebug bool,
inContainer bool,
printState bool,
printPrefix string) (*Inspector, error) {

Expand Down Expand Up @@ -170,10 +170,9 @@ func NewInspector(
DoDebug: doDebug,
PrintState: printState,
PrintPrefix: printPrefix,
InContainer: inContainer,
}

inspector.InContainer = env.InContainer()

if overrides != nil && ((len(overrides.Entrypoint) > 0) || overrides.ClearEntrypoint) {
logger.Debugf("overriding Entrypoint %+v => %+v (%v)",
imageInspector.ImageInfo.Config.Entrypoint, overrides.Entrypoint, overrides.ClearEntrypoint)
Expand Down
29 changes: 29 additions & 0 deletions internal/app/master/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,37 @@ import (
"github.com/google/shlex"

"github.com/docker-slim/docker-slim/internal/app/master/config"
"github.com/docker-slim/docker-slim/pkg/env"
)

const (
DefaultStateArchiveVolumeName = "docker-slim-state"
)

func isInContainer(flag bool) bool {
if flag {
return true
}

return env.InContainer()
}

func archiveState(flag string, inContainer bool) string {
switch flag {
case "":
switch inContainer {
case true:
return DefaultStateArchiveVolumeName
default:
return ""
}
case "off":
return ""
default:
return flag //should validate if it can be a Docker volume name
}
}

//based on expose opt parsing in Docker
func parseDockerExposeOpt(values []string) (map[docker.Port]struct{}, error) {
exposedPorts := map[docker.Port]struct{}{}
Expand Down
Loading

0 comments on commit 8b46e57

Please sign in to comment.