in kinder/pkg/build/alter/alter.go [280:405]
func (c *Context) alterImage(bitsInstallers []bits.Installer, bc *bits.BuildContext) error {
// get the container runtime from the base image
runtime, err := status.InspectCRIinImage(c.baseImage)
if err != nil {
return errors.Wrap(err, "error detecting CRI!")
}
log.Infof("Detected %s as container runtime", runtime)
alterHelper, err := nodes.NewAlterHelper(runtime)
if err != nil {
return err
}
// get the args for the alter container depending on the underlying CR
runArgs, containerArgs := alterHelper.GetAlterContainerArgs()
// create final alter container
// NOTE: we are using docker run + docker commit so we can install
// debians without permanently copying them into the image.
// if docker gets proper squash support, we can rm them instead
// This also allows the KubeBit implementations to perform programmatic
// install in the image
log.Debug("Starting alter container ...")
containerID, err := c.createAlterContainer(bc, runArgs, containerArgs)
// ensure we will delete it
if containerID != "" {
defer func() {
exec.NewHostCmd("docker", "rm", "-f", "-v", containerID).Run()
}()
}
if err != nil {
log.Errorf("Image alter Failed! %v", err)
return err
}
// alter the image, tagged as tagImageAs, using the our tempdir as the context
log.Debug("Starting image alter ...")
// binds the BuildContext the container
bc.BindToContainer(containerID)
// Make sure the /kind/images folder exists
if err := bc.RunInContainer("mkdir", "-p", "/kind/images"); err != nil {
return err
}
// install the bits that are used to alter the image
log.Info("Starting bits install ...")
for _, b := range bitsInstallers {
if err = b.Install(bc); err != nil {
log.Errorf("Image build Failed! %v", err)
return err
}
}
log.Info("Setup CRI ...")
if err := alterHelper.SetupCRI(bc); err != nil {
return errors.Wrapf(err, "image build Failed! Failed to setup %s", runtime)
}
log.Info("Start CRI ...")
if err := alterHelper.StartCRI(bc); err != nil {
return errors.Wrapf(err, "image build Failed! Failed to start %s", runtime)
}
log.Info("Pre-loading images ...")
if err := alterHelper.PreLoadInitImages(bc, "/kind/images"); err != nil {
return errors.Wrapf(err, "image build Failed! Failed to start %s", runtime)
}
if c.prePullAdditionalImages {
log.Info("Pre-pulling additional images ...")
// pull images required for init / join
initPath := "/kind"
images, err := alterHelper.GetImagesForKubeadmBinary(bc, filepath.Join(initPath, "bin", "kubeadm"))
if err != nil {
return err
}
if err := pullImages(alterHelper, bc, images, filepath.Join(initPath, "images"), containerID); err != nil {
return err
}
// pull images required for upgrade
upgradePath := "/kinder/upgrade"
// check if the version file for the upgrade artifacts is in place
versionFile := filepath.Join(upgradePath, "version")
version, err := bc.CombinedOutputLinesInContainer(
"bash",
"-c",
"cat "+versionFile+" 2> /dev/null",
)
// don't return the error if the version file is missing
if err == nil {
if len(version) != 1 {
return errors.Errorf("expected the version file %q to have 1 line, got: %v", versionFile, version)
}
// use the resulting upgrade path e.g. /kinder/upgrade/v1.19.0-alpha.3.36+8c4e3faed35411
upgradeImages, err := alterHelper.GetImagesForKubeadmBinary(bc, filepath.Join(upgradePath, version[0], "kubeadm"))
if err != nil {
return err
}
if err := pullImages(alterHelper, bc, upgradeImages, filepath.Join(upgradePath, version[0]), containerID); err != nil {
return err
}
}
}
log.Info("Stop CRI ...")
if err := alterHelper.StopCRI(bc); err != nil {
return errors.Wrapf(err, "image build Failed! Failed to stop %s", runtime)
}
log.Infof("Commit to %s ...", c.image)
if err = alterHelper.Commit(containerID, c.image); err != nil {
return errors.Wrap(err, "image alter Failed! Failed to commit image")
}
log.Info("Image alter completed.")
return nil
}