Merge e61dbc46b2 into 236ba5690e
This commit is contained in:
commit
4ea6233c3c
12
README.md
12
README.md
|
|
@ -101,6 +101,7 @@ _If you are interested in contributing to kaniko, see
|
||||||
- [Flag `--no-push`](#flag---no-push)
|
- [Flag `--no-push`](#flag---no-push)
|
||||||
- [Flag `--no-push-cache`](#flag---no-push-cache)
|
- [Flag `--no-push-cache`](#flag---no-push-cache)
|
||||||
- [Flag `--oci-layout-path`](#flag---oci-layout-path)
|
- [Flag `--oci-layout-path`](#flag---oci-layout-path)
|
||||||
|
- [Flag `--preserve-context`](#flag---preserve-context)
|
||||||
- [Flag `--push-retry`](#flag---push-retry)
|
- [Flag `--push-retry`](#flag---push-retry)
|
||||||
- [Flag `--registry-certificate`](#flag---registry-certificate)
|
- [Flag `--registry-certificate`](#flag---registry-certificate)
|
||||||
- [Flag `--registry-client-cert`](#flag---registry-client-cert)
|
- [Flag `--registry-client-cert`](#flag---registry-client-cert)
|
||||||
|
|
@ -978,6 +979,17 @@ _Note: Depending on the built image, the media type of the image manifest might
|
||||||
be either `application/vnd.oci.image.manifest.v1+json` or
|
be either `application/vnd.oci.image.manifest.v1+json` or
|
||||||
`application/vnd.docker.distribution.manifest.v2+json`._
|
`application/vnd.docker.distribution.manifest.v2+json`._
|
||||||
|
|
||||||
|
#### Flag `--preserve-context`
|
||||||
|
|
||||||
|
Set this boolean flag to `true` if you want kaniko to restore the build-context for multi-stage builds.
|
||||||
|
If set, kaniko will take a snapshot of the full filesystem before it starts building to later restore to that state. If combined with the `--cleanup` flag it will also restore the state after cleanup.
|
||||||
|
|
||||||
|
This is useful if you want to pass in secrets via files or if you want to execute commands after the build completes.
|
||||||
|
|
||||||
|
It will only take the snapshot if we are building a multistage image or if we plan to cleanup the filesystem after the build.
|
||||||
|
|
||||||
|
Defaults to `false`
|
||||||
|
|
||||||
#### Flag `--push-ignore-immutable-tag-errors`
|
#### Flag `--push-ignore-immutable-tag-errors`
|
||||||
|
|
||||||
Set this boolean flag to `true` if you want the Kaniko process to exit with
|
Set this boolean flag to `true` if you want the Kaniko process to exit with
|
||||||
|
|
|
||||||
|
|
@ -280,6 +280,7 @@ func addKanikoOptionsFlags() {
|
||||||
RootCmd.PersistentFlags().VarP(&opts.IgnorePaths, "ignore-path", "", "Ignore these paths when taking a snapshot. Set it repeatedly for multiple paths.")
|
RootCmd.PersistentFlags().VarP(&opts.IgnorePaths, "ignore-path", "", "Ignore these paths when taking a snapshot. Set it repeatedly for multiple paths.")
|
||||||
RootCmd.PersistentFlags().BoolVarP(&opts.ForceBuildMetadata, "force-build-metadata", "", false, "Force add metadata layers to build image")
|
RootCmd.PersistentFlags().BoolVarP(&opts.ForceBuildMetadata, "force-build-metadata", "", false, "Force add metadata layers to build image")
|
||||||
RootCmd.PersistentFlags().BoolVarP(&opts.SkipPushPermissionCheck, "skip-push-permission-check", "", false, "Skip check of the push permission")
|
RootCmd.PersistentFlags().BoolVarP(&opts.SkipPushPermissionCheck, "skip-push-permission-check", "", false, "Skip check of the push permission")
|
||||||
|
RootCmd.PersistentFlags().BoolVarP(&opts.PreserveContext, "preserve-context", "", false, "Preserve build context accross build stages by taking a snapshot of the full filesystem before build and restore it after we switch stages. Restores in the end too if passed together with 'cleanup'")
|
||||||
|
|
||||||
// Deprecated flags.
|
// Deprecated flags.
|
||||||
RootCmd.PersistentFlags().StringVarP(&opts.SnapshotModeDeprecated, "snapshotMode", "", "", "This flag is deprecated. Please use '--snapshot-mode'.")
|
RootCmd.PersistentFlags().StringVarP(&opts.SnapshotModeDeprecated, "snapshotMode", "", "", "This flag is deprecated. Please use '--snapshot-mode'.")
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,7 @@ type KanikoOptions struct {
|
||||||
ForceBuildMetadata bool
|
ForceBuildMetadata bool
|
||||||
InitialFSUnpacked bool
|
InitialFSUnpacked bool
|
||||||
SkipPushPermissionCheck bool
|
SkipPushPermissionCheck bool
|
||||||
|
PreserveContext bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type KanikoGitOptions struct {
|
type KanikoGitOptions struct {
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,20 @@ type stageBuilder struct {
|
||||||
pushLayerToCache cachePusher
|
pushLayerToCache cachePusher
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeSnapshotter(opts *config.KanikoOptions) (*snapshot.Snapshotter, error) {
|
||||||
|
err := util.InitIgnoreList()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to initialize ignore list")
|
||||||
|
}
|
||||||
|
|
||||||
|
hasher, err := getHasher(opts.SnapshotMode)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
l := snapshot.NewLayeredMap(hasher)
|
||||||
|
return snapshot.NewSnapshotter(l, config.RootDir), nil
|
||||||
|
}
|
||||||
|
|
||||||
// newStageBuilder returns a new type stageBuilder which contains all the information required to build the stage
|
// newStageBuilder returns a new type stageBuilder which contains all the information required to build the stage
|
||||||
func newStageBuilder(args *dockerfile.BuildArgs, opts *config.KanikoOptions, stage config.KanikoStage, crossStageDeps map[int][]string, dcm map[string]string, sid map[string]string, stageNameToIdx map[string]string, fileContext util.FileContext) (*stageBuilder, error) {
|
func newStageBuilder(args *dockerfile.BuildArgs, opts *config.KanikoOptions, stage config.KanikoStage, crossStageDeps map[int][]string, dcm map[string]string, sid map[string]string, stageNameToIdx map[string]string, fileContext util.FileContext) (*stageBuilder, error) {
|
||||||
sourceImage, err := image_util.RetrieveSourceImage(stage, opts)
|
sourceImage, err := image_util.RetrieveSourceImage(stage, opts)
|
||||||
|
|
@ -101,17 +115,10 @@ func newStageBuilder(args *dockerfile.BuildArgs, opts *config.KanikoOptions, sta
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = util.InitIgnoreList()
|
snapshotter, err := makeSnapshotter(opts)
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "failed to initialize ignore list")
|
|
||||||
}
|
|
||||||
|
|
||||||
hasher, err := getHasher(opts.SnapshotMode)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
l := snapshot.NewLayeredMap(hasher)
|
|
||||||
snapshotter := snapshot.NewSnapshotter(l, config.RootDir)
|
|
||||||
|
|
||||||
digest, err := sourceImage.Digest()
|
digest, err := sourceImage.Digest()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -688,6 +695,23 @@ func CalculateDependencies(stages []config.KanikoStage, opts *config.KanikoOptio
|
||||||
return depGraph, nil
|
return depGraph, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func restoreFilesystem(tarball string, opts *config.KanikoOptions) error {
|
||||||
|
if err := util.DeleteFilesystem(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if opts.PreserveContext {
|
||||||
|
if tarball == "" {
|
||||||
|
return fmt.Errorf("context snapshot is missing")
|
||||||
|
}
|
||||||
|
_, err := util.UnpackLocalTarArchive(tarball, config.RootDir)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to unpack context snapshot")
|
||||||
|
}
|
||||||
|
logrus.Info("Context restored")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// DoBuild executes building the Dockerfile
|
// DoBuild executes building the Dockerfile
|
||||||
func DoBuild(opts *config.KanikoOptions) (v1.Image, error) {
|
func DoBuild(opts *config.KanikoOptions) (v1.Image, error) {
|
||||||
t := timing.Start("Total Build Time")
|
t := timing.Start("Total Build Time")
|
||||||
|
|
@ -722,6 +746,24 @@ func DoBuild(opts *config.KanikoOptions) (v1.Image, error) {
|
||||||
|
|
||||||
var args *dockerfile.BuildArgs
|
var args *dockerfile.BuildArgs
|
||||||
|
|
||||||
|
var tarball string
|
||||||
|
if opts.PreserveContext {
|
||||||
|
if len(kanikoStages) > 1 || opts.Cleanup {
|
||||||
|
logrus.Info("Creating snapshot of build context")
|
||||||
|
snapshotter, err := makeSnapshotter(opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tarball, err = snapshotter.TakeSnapshotFS()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logrus.Info("Skipping context snapshot as no-one requires it")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for index, stage := range kanikoStages {
|
for index, stage := range kanikoStages {
|
||||||
sb, err := newStageBuilder(
|
sb, err := newStageBuilder(
|
||||||
args, opts, stage,
|
args, opts, stage,
|
||||||
|
|
@ -787,7 +829,8 @@ func DoBuild(opts *config.KanikoOptions) (v1.Image, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if opts.Cleanup {
|
if opts.Cleanup {
|
||||||
if err = util.DeleteFilesystem(); err != nil {
|
err = restoreFilesystem(tarball, opts)
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -819,8 +862,9 @@ func DoBuild(opts *config.KanikoOptions) (v1.Image, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the filesystem
|
// Delete the filesystem
|
||||||
if err := util.DeleteFilesystem(); err != nil {
|
err = restoreFilesystem(tarball, opts)
|
||||||
return nil, errors.Wrap(err, fmt.Sprintf("deleting file system after stage %d", index))
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue