Skip to content

Commit

Permalink
WIP: Embed podman (remote) binary in crc binary
Browse files Browse the repository at this point in the history
  • Loading branch information
zeenix committed Feb 27, 2020
1 parent ac408f7 commit 8ad5bd1
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 6 deletions.
1 change: 1 addition & 0 deletions cmd/crc-embedder/cmd/embed.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ var (
hyperkit.HyperkitDownloadUrl,
constants.GetOcUrlForOs("darwin"),
constants.GetCrcTrayDownloadURL(),
constants.GetPodmanUrl(),
},
"linux": []string{
libvirt.MachineDriverDownloadUrl,
Expand Down
15 changes: 13 additions & 2 deletions pkg/crc/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ const (
CrcLandingPageURL = "https://cloud.redhat.com/openshift/install/crc/installer-provisioned" // #nosec G101
PullSecretFile = "pullsecret.json"

DefaultOcUrlBase = "https://mirror.openshift.com/pub/openshift-v4/clients/oc/latest"
CrcTrayDownloadURL = "https://github.com/code-ready/tray-macos/releases/download/v%s/crc-tray-macos.tar.gz"
DefaultOcUrlBase = "https://mirror.openshift.com/pub/openshift-v4/clients/oc/latest"
DefaultPodmanUrlBase = "https://storage.googleapis.com/libpod-master-releases"
CrcTrayDownloadURL = "https://github.com/code-ready/tray-macos/releases/download/v%s/crc-tray-macos.tar.gz"
)

var ocUrlForOs = map[string]string{
Expand All @@ -48,6 +49,16 @@ func GetOcUrl() string {
return GetOcUrlForOs(runtime.GOOS)
}

var PodmanUrlForOs = map[string]string{
"darwin": fmt.Sprintf("%s/%s", DefaultPodmanUrlBase, "podman-remote-latest-master-darwin-amd64.zip"),
"linux": fmt.Sprintf("%s/%s", DefaultPodmanUrlBase, "podman-remote-latest-master-linux---amd64.zip"),
"windows": fmt.Sprintf("%s/%s", DefaultPodmanUrlBase, "podman-remote-latest-master-windows-amd64.msi"),
}

func GetPodmanUrl() string {
return PodmanUrlForOs[runtime.GOOS]
}

var defaultBundleForOs = map[string]string{
"darwin": fmt.Sprintf("crc_hyperkit_%s.crcbundle", version.GetBundleVersion()),
"linux": fmt.Sprintf("crc_libvirt_%s.crcbundle", version.GetBundleVersion()),
Expand Down
5 changes: 3 additions & 2 deletions pkg/crc/constants/constants_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package constants
import "path/filepath"

const (
OcBinaryName = "oc"
TrayBinaryName = "CodeReady Containers.app"
OcBinaryName = "oc"
PodmanBinaryName = "podman"
TrayBinaryName = "CodeReady Containers.app"
)

var (
Expand Down
3 changes: 2 additions & 1 deletion pkg/crc/constants/constants_linux.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package constants

const (
OcBinaryName = "oc"
OcBinaryName = "oc"
PodmanBinaryName = "podman"
)
3 changes: 2 additions & 1 deletion pkg/crc/constants/constants_windows.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package constants

const (
OcBinaryName = "oc.exe"
OcBinaryName = "oc.exe"
PodmanBinaryName = "podman.exe"
)
118 changes: 118 additions & 0 deletions pkg/crc/podman/podman_cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package podman

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"

"github.com/code-ready/crc/pkg/crc/constants"
"github.com/code-ready/crc/pkg/crc/logging"
"github.com/code-ready/crc/pkg/download"
"github.com/code-ready/crc/pkg/embed"
"github.com/code-ready/crc/pkg/extract"
crcos "github.com/code-ready/crc/pkg/os"
"github.com/pkg/errors"
)

// Podman is a struct with methods designed for dealing with the podman binary
type PodmanCached struct{}

func (podman *PodmanCached) EnsureIsCached() error {
if !podman.IsCached() {
err := podman.cachePodman()
if err != nil {
return err
}

}
return nil
}

func (podman *PodmanCached) IsCached() bool {
if _, err := os.Stat(filepath.Join(constants.CrcBinDir, constants.PodmanBinaryName)); os.IsNotExist(err) {
return false
}
return true
}

func (podman *PodmanCached) getPodman(destDir string) (string, error) {
logging.Debug("Trying to extract podman from crc binary")
archiveName := filepath.Base(constants.GetPodmanUrl())
destPath := filepath.Join(destDir, archiveName)
err := embed.Extract(archiveName, destPath)
if err != nil {
logging.Debug("Downloading podman")
return download.Download(constants.GetPodmanUrl(), destDir, 0600)
}

return destPath, err
}

// cachePodman downloads and caches the podman binary into the minishift directory
func (podman *PodmanCached) cachePodman() error {
if podman.IsCached() {
return nil
}

// Create tmp dir to download the podman tarball
tmpDir, err := ioutil.TempDir("", "crc")
if err != nil {
return err
}
defer os.RemoveAll(tmpDir)
assetTmpFile, err := podman.getPodman(tmpDir)
if err != nil {
return err
}

// Extract the tarball and put it the cache directory.
err = extract.Uncompress(assetTmpFile, tmpDir)
if err != nil {
return errors.Wrapf(err, "Cannot uncompress '%s'", assetTmpFile)
}

binaryName := constants.PodmanBinaryName
binaryPath, err := findBinary(tmpDir, binaryName)
if err != nil {
return err
}

// Copy the requested asset into its final destination
outputPath := constants.CrcBinDir
err = os.MkdirAll(outputPath, 0750)
if err != nil && !os.IsExist(err) {
return errors.Wrap(err, "Cannot create the target directory.")
}

finalBinaryPath := filepath.Join(outputPath, binaryName)
err = crcos.CopyFileContents(binaryPath, finalBinaryPath, 0500)
if err != nil {
return err
}

return nil
}

func findBinary(dirPath string, binaryName string) (string, error) {
var binaryPath string = ""

err := filepath.Walk(dirPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

if filepath.Base(path) == binaryName {
binaryPath = path

return filepath.SkipDir
}

return nil
})
if binaryPath == "" && err == nil {
err = fmt.Errorf("Failed to find `{}` binary in `{}`.", binaryName, dirPath)
}

return binaryPath, err
}
26 changes: 26 additions & 0 deletions pkg/crc/preflight/preflight_checks_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/code-ready/crc/pkg/crc/constants"
"github.com/code-ready/crc/pkg/crc/logging"
"github.com/code-ready/crc/pkg/crc/oc"
"github.com/code-ready/crc/pkg/crc/podman"
"github.com/code-ready/crc/pkg/embed"
)

Expand All @@ -19,6 +20,12 @@ var genericPreflightChecks = [...]PreflightCheck{
fixDescription: "Caching oc binary",
fix: fixOcBinaryCached,
},
{
checkDescription: "Checking if podman binary is cached",
check: checkPodmanBinaryCached,
fixDescription: "Caching podman binary",
fix: fixPodmanBinaryCached,
},
{
configKeySuffix: "check-bundle-cached",
checkDescription: "Checking if CRC bundle is cached in '$HOME/.crc'",
Expand Down Expand Up @@ -70,3 +77,22 @@ func fixOcBinaryCached() error {
logging.Debug("oc binary cached")
return nil
}

// Check if podman binary is cached or not
func checkPodmanBinaryCached() error {
podman := podman.PodmanCached{}
if !podman.IsCached() {
return errors.New("podman binary is not cached")
}
logging.Debug("podman binary already cached")
return nil
}

func fixPodmanBinaryCached() error {
podman := podman.PodmanCached{}
if err := podman.EnsureIsCached(); err != nil {
return fmt.Errorf("Unable to download podman %v", err)
}
logging.Debug("podman binary cached")
return nil
}

0 comments on commit 8ad5bd1

Please sign in to comment.