Skip to content

Commit

Permalink
MGMT-7549: extract openshift-install for none platform (#2456)
Browse files Browse the repository at this point in the history
- Added support in Release to extract according to platform type:
  - Extract openshift-install binary for none platform.
  - Otherwise, extract openshift-baremetal-install.
- Added none to platform_type in swagger.
- For now, non default CPU architectures (x86_64) are supported only
  with User Managed Networking.
  • Loading branch information
danielerez committed Aug 29, 2021
1 parent 4a36497 commit f9b2f3d
Show file tree
Hide file tree
Showing 14 changed files with 114 additions and 53 deletions.
2 changes: 1 addition & 1 deletion Dockerfile.assisted-service
Expand Up @@ -22,7 +22,7 @@ COPY . .
RUN CGO_ENABLED=1 GOFLAGS="" GO111MODULE=on go build -o /build/assisted-service cmd/main.go
RUN CGO_ENABLED=0 GOFLAGS="" GO111MODULE=on go build -o /build/assisted-service-operator cmd/operator/main.go

FROM quay.io/ocpmetal/oc-image:bug-1823143 as oc-image
FROM quay.io/ocpmetal/oc-image:bug-1823143-multi-arch as oc-image

# Create final image
FROM quay.io/centos/centos:stream8
Expand Down
4 changes: 4 additions & 0 deletions internal/bminventory/inventory.go
Expand Up @@ -665,6 +665,10 @@ func (b *bareMetalInventory) getNewClusterCPUArchitecture(newClusterParams *mode
return common.DefaultCPUArchitecture, nil
}

if !swag.BoolValue(newClusterParams.UserManagedNetworking) {
return "", errors.Errorf("Non x86_64 CPU architectures are supported only with User Managed Networking")
}

cpuArchitectures, err := b.versionsHandler.GetCPUArchitectures(*newClusterParams.OpenshiftVersion)
if err != nil {
return "", err
Expand Down
23 changes: 19 additions & 4 deletions internal/bminventory/inventory_test.go
Expand Up @@ -8751,17 +8751,32 @@ var _ = Describe("TestRegisterCluster", func() {

reply := bm.RegisterCluster(ctx, installer.RegisterClusterParams{
NewClusterParams: &models.ClusterCreateParams{
Name: swag.String("some-cluster-name"),
OpenshiftVersion: swag.String(common.TestDefaultConfig.OpenShiftVersion),
CPUArchitecture: "arm64",
PullSecret: swag.String("{\"auths\":{\"cloud.openshift.com\":{\"auth\":\"dG9rZW46dGVzdAo=\",\"email\":\"coyote@acme.com\"}}}"),
Name: swag.String("some-cluster-name"),
OpenshiftVersion: swag.String(common.TestDefaultConfig.OpenShiftVersion),
CPUArchitecture: "arm64",
UserManagedNetworking: swag.Bool(true),
VipDhcpAllocation: swag.Bool(false),
PullSecret: swag.String("{\"auths\":{\"cloud.openshift.com\":{\"auth\":\"dG9rZW46dGVzdAo=\",\"email\":\"coyote@acme.com\"}}}"),
},
})
Expect(reflect.TypeOf(reply)).Should(Equal(reflect.TypeOf(installer.NewRegisterClusterCreated())))
actual := reply.(*installer.RegisterClusterCreated)
Expect(actual.Payload.CPUArchitecture).To(Equal("arm64"))
})

It("Register cluster with arm64 CPU architecture - without UserManagedNetworking", func() {
reply := bm.RegisterCluster(ctx, installer.RegisterClusterParams{
NewClusterParams: &models.ClusterCreateParams{
Name: swag.String("some-cluster-name"),
OpenshiftVersion: swag.String(common.TestDefaultConfig.OpenShiftVersion),
CPUArchitecture: "arm64",
UserManagedNetworking: swag.Bool(false),
PullSecret: swag.String("{\"auths\":{\"cloud.openshift.com\":{\"auth\":\"dG9rZW46dGVzdAo=\",\"email\":\"coyote@acme.com\"}}}"),
},
})
Expect(reply).Should(BeAssignableToTypeOf(common.NewApiError(http.StatusBadRequest, errors.Errorf("error"))))
})

It("Register cluster without specified CPU architecture", func() {
mockClusterRegisterSuccess(bm, true)
mockAMSSubscription(ctx)
Expand Down
2 changes: 1 addition & 1 deletion internal/ignition/dummy.go
Expand Up @@ -32,7 +32,7 @@ func NewDummyGenerator(workDir string, cluster *common.Cluster, s3Client s3wrapp
}

// Generate creates the expected ignition and related files but with nonsense content
func (g *dummyGenerator) Generate(_ context.Context, installConfig []byte) error {
func (g *dummyGenerator) Generate(_ context.Context, installConfig []byte, platformType models.PlatformType) error {
installConfigPath := filepath.Join(g.workDir, "install-config.yaml")
err := ioutil.WriteFile(installConfigPath, installConfig, 0600)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions internal/ignition/ignition.go
Expand Up @@ -311,7 +311,7 @@ var fileNames = [...]string{

// Generator can generate ignition files and upload them to an S3-like service
type Generator interface {
Generate(ctx context.Context, installConfig []byte) error
Generate(ctx context.Context, installConfig []byte, platformType models.PlatformType) error
UploadToS3(ctx context.Context) error
UpdateEtcHosts(string) error
}
Expand Down Expand Up @@ -389,10 +389,10 @@ func (g *installerGenerator) UploadToS3(ctx context.Context) error {
}

// Generate generates ignition files and applies modifications.
func (g *installerGenerator) Generate(ctx context.Context, installConfig []byte) error {
func (g *installerGenerator) Generate(ctx context.Context, installConfig []byte, platformType models.PlatformType) error {
log := logutil.FromContext(ctx, g.log)
installerPath, err := installercache.Get(g.releaseImage, g.releaseImageMirror, g.installerDir,
g.cluster.PullSecret, log)
g.cluster.PullSecret, platformType, log)
if err != nil {
return errors.Wrap(err, "failed to get installer path")
}
Expand Down
9 changes: 5 additions & 4 deletions internal/ignition/mock_ignition.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions internal/installercache/installercache.go
Expand Up @@ -4,6 +4,7 @@ import (
"sync"

"github.com/openshift/assisted-service/internal/oc"
"github.com/openshift/assisted-service/models"
"github.com/openshift/assisted-service/pkg/executer"
"github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -38,7 +39,7 @@ func (i *installers) Get(releaseID string) *release {
// Get returns the path to an openshift-baremetal-install binary extracted from
// the referenced release image. Tries the mirror release image first if it's set. It is safe for concurrent use. A cache of
// binaries is maintained to reduce re-downloading of the same release.
func Get(releaseID, releaseIDMirror, cacheDir, pullSecret string, log logrus.FieldLogger) (string, error) {
func Get(releaseID, releaseIDMirror, cacheDir, pullSecret string, platformType models.PlatformType, log logrus.FieldLogger) (string, error) {
r := cache.Get(releaseID)
r.Lock()
defer r.Unlock()
Expand All @@ -48,7 +49,7 @@ func Get(releaseID, releaseIDMirror, cacheDir, pullSecret string, log logrus.Fie
//cache miss
if r.path == "" {
path, err = oc.NewRelease(&executer.CommonExecuter{}, oc.Config{
MaxTries: oc.DefaultTries, RetryDelay: oc.DefaltRetryDelay}).Extract(log, releaseID, releaseIDMirror, cacheDir, pullSecret)
MaxTries: oc.DefaultTries, RetryDelay: oc.DefaltRetryDelay}).Extract(log, releaseID, releaseIDMirror, cacheDir, pullSecret, platformType)
if err != nil {
return "", err
}
Expand Down
9 changes: 5 additions & 4 deletions internal/oc/mock_release.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 18 additions & 10 deletions internal/oc/release.go
Expand Up @@ -9,6 +9,7 @@ import (
"time"

"github.com/hashicorp/go-version"
"github.com/openshift/assisted-service/models"
"github.com/openshift/assisted-service/pkg/executer"
"github.com/sirupsen/logrus"
"github.com/thedevsaddam/retry"
Expand All @@ -32,7 +33,7 @@ type Release interface {
GetMustGatherImage(log logrus.FieldLogger, releaseImage string, releaseImageMirror string, pullSecret string) (string, error)
GetOpenshiftVersion(log logrus.FieldLogger, releaseImage string, releaseImageMirror string, pullSecret string) (string, error)
GetMajorMinorVersion(log logrus.FieldLogger, releaseImage string, releaseImageMirror string, pullSecret string) (string, error)
Extract(log logrus.FieldLogger, releaseImage string, releaseImageMirror string, cacheDir string, pullSecret string) (string, error)
Extract(log logrus.FieldLogger, releaseImage string, releaseImageMirror string, cacheDir string, pullSecret string, platformType models.PlatformType) (string, error)
}

type release struct {
Expand All @@ -50,7 +51,7 @@ func NewRelease(executer executer.Executer, config Config) Release {
const (
templateGetImage = "oc adm release info --image-for=%s --insecure=%t %s"
templateGetVersion = "oc adm release info -o template --template '{{.metadata.version}}' --insecure=%t %s"
templateExtract = "oc adm release extract --command=openshift-baremetal-install --to=%s --insecure=%t %s"
templateExtract = "oc adm release extract --command=%s --to=%s --insecure=%t %s"
)

// GetMCOImage gets mcoImage url from the releaseImageMirror if provided.
Expand Down Expand Up @@ -158,21 +159,21 @@ func (r *release) getOpenshiftVersionFromRelease(log logrus.FieldLogger, release

// Extract openshift-baremetal-install binary from releaseImageMirror if provided.
// Else extract from the source releaseImage
func (r *release) Extract(log logrus.FieldLogger, releaseImage string, releaseImageMirror string, cacheDir string, pullSecret string) (string, error) {
func (r *release) Extract(log logrus.FieldLogger, releaseImage string, releaseImageMirror string, cacheDir string, pullSecret string, platformType models.PlatformType) (string, error) {
var path string
var err error
if releaseImage == "" && releaseImageMirror == "" {
return "", errors.New("no releaseImage or releaseImageMirror provided")
}
if releaseImageMirror != "" {
//TODO: Get mirror registry certificate from install-config
path, err = r.extractFromRelease(log, releaseImageMirror, cacheDir, pullSecret, true)
path, err = r.extractFromRelease(log, releaseImageMirror, cacheDir, pullSecret, true, platformType)
if err != nil {
log.WithError(err).Errorf("failed to extract openshift-baremetal-install from mirror release image %s", releaseImageMirror)
return "", err
}
} else {
path, err = r.extractFromRelease(log, releaseImage, cacheDir, pullSecret, false)
path, err = r.extractFromRelease(log, releaseImage, cacheDir, pullSecret, false, platformType)
if err != nil {
log.WithError(err).Errorf("failed to extract openshift-baremetal-install from release image %s", releaseImageMirror)
return "", err
Expand All @@ -183,22 +184,29 @@ func (r *release) Extract(log logrus.FieldLogger, releaseImage string, releaseIm

// extractFromRelease returns the path to an openshift-baremetal-install binary extracted from
// the referenced release image.
func (r *release) extractFromRelease(log logrus.FieldLogger, releaseImage, cacheDir, pullSecret string, insecure bool) (string, error) {
func (r *release) extractFromRelease(log logrus.FieldLogger, releaseImage, cacheDir, pullSecret string, insecure bool, platformType models.PlatformType) (string, error) {
var binary string
if platformType == models.PlatformTypeNone {
binary = "openshift-install"
} else {
binary = "openshift-baremetal-install"
}

workdir := filepath.Join(cacheDir, releaseImage)
log.Infof("extracting openshift-baremetal-install binary to %s", workdir)
log.Infof("extracting %s binary to %s", binary, workdir)
err := os.MkdirAll(workdir, 0755)
if err != nil {
return "", err
}

cmd := fmt.Sprintf(templateExtract, workdir, insecure, releaseImage)
cmd := fmt.Sprintf(templateExtract, binary, workdir, insecure, releaseImage)
_, err = retry.Do(r.config.MaxTries, r.config.RetryDelay, execute, log, r.executer, pullSecret, cmd)
if err != nil {
return "", err
}
// set path
path := filepath.Join(workdir, "openshift-baremetal-install")
log.Info("Successfully extracted openshift-baremetal-install binary from the release to: $s", path)
path := filepath.Join(workdir, binary)
log.Info("Successfully extracted $s binary from the release to: $s", binary, path)
return path, nil
}

Expand Down
55 changes: 35 additions & 20 deletions internal/oc/release_test.go
Expand Up @@ -11,19 +11,22 @@ import (
gomock "github.com/golang/mock/gomock"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/openshift/assisted-service/models"
"github.com/openshift/assisted-service/pkg/executer"
logrus "github.com/sirupsen/logrus"
)

var (
log = logrus.New()
releaseImage = "release_image"
releaseImageMirror = "release_image_mirror"
cacheDir = "/tmp"
pullSecret = "pull secret"
fullVersion = "4.6.0-0.nightly-2020-08-31-220837"
mcoImage = "mco_image"
mustGatherImage = "must_gather_image"
log = logrus.New()
releaseImage = "release_image"
releaseImageMirror = "release_image_mirror"
cacheDir = "/tmp"
pullSecret = "pull secret"
fullVersion = "4.6.0-0.nightly-2020-08-31-220837"
mcoImage = "mco_image"
mustGatherImage = "must_gather_image"
baremetalInstallBinary = "openshift-baremetal-install"
installBinary = "openshift-install"
)

var _ = Describe("oc", func() {
Expand Down Expand Up @@ -257,56 +260,68 @@ var _ = Describe("oc", func() {
Context("Extract", func() {
It("extract baremetal-install from release image", func() {
command := fmt.Sprintf(templateExtract+" --registry-config=%s",
filepath.Join(cacheDir, releaseImage), false, releaseImage, tempFilePath)
baremetalInstallBinary, filepath.Join(cacheDir, releaseImage), false, releaseImage, tempFilePath)
args := splitStringToInterfacesArray(command)
mockExecuter.EXPECT().Execute(args[0], args[1:]...).Return("", "", 0).Times(1)

path, err := oc.Extract(log, releaseImage, "", cacheDir, pullSecret)
filePath := filepath.Join(cacheDir+"/"+releaseImage, "openshift-baremetal-install")
path, err := oc.Extract(log, releaseImage, "", cacheDir, pullSecret, models.PlatformTypeBaremetal)
filePath := filepath.Join(cacheDir+"/"+releaseImage, baremetalInstallBinary)
Expect(path).To(Equal(filePath))
Expect(err).ShouldNot(HaveOccurred())
})

It("extract baremetal-install from release image mirror", func() {
command := fmt.Sprintf(templateExtract+" --registry-config=%s",
filepath.Join(cacheDir, releaseImageMirror), true, releaseImageMirror, tempFilePath)
baremetalInstallBinary, filepath.Join(cacheDir, releaseImageMirror), true, releaseImageMirror, tempFilePath)
args := splitStringToInterfacesArray(command)
mockExecuter.EXPECT().Execute(args[0], args[1:]...).Return("", "", 0).Times(1)

path, err := oc.Extract(log, releaseImage, releaseImageMirror, cacheDir, pullSecret)
filePath := filepath.Join(cacheDir+"/"+releaseImageMirror, "openshift-baremetal-install")
path, err := oc.Extract(log, releaseImage, releaseImageMirror, cacheDir, pullSecret, models.PlatformTypeBaremetal)
filePath := filepath.Join(cacheDir+"/"+releaseImageMirror, baremetalInstallBinary)
Expect(path).To(Equal(filePath))
Expect(err).ShouldNot(HaveOccurred())
})

It("extract baremetal-install with no release image or mirror", func() {
path, err := oc.Extract(log, "", "", cacheDir, pullSecret)
path, err := oc.Extract(log, "", "", cacheDir, pullSecret, models.PlatformTypeBaremetal)
Expect(path).Should(BeEmpty())
Expect(err).Should(HaveOccurred())
})
It("extract baremetal-install from release image with retry", func() {
command := fmt.Sprintf(templateExtract+" --registry-config=%s",
filepath.Join(cacheDir, releaseImage), false, releaseImage, tempFilePath)
baremetalInstallBinary, filepath.Join(cacheDir, releaseImage), false, releaseImage, tempFilePath)
args := splitStringToInterfacesArray(command)
mockExecuter.EXPECT().Execute(args[0], args[1:]...).Return("", "Failed to extract the installer", 1).Times(1)
mockExecuter.EXPECT().Execute(args[0], args[1:]...).Return("", "", 0).Times(1)

path, err := oc.Extract(log, releaseImage, "", cacheDir, pullSecret)
filePath := filepath.Join(cacheDir+"/"+releaseImage, "openshift-baremetal-install")
path, err := oc.Extract(log, releaseImage, "", cacheDir, pullSecret, models.PlatformTypeBaremetal)
filePath := filepath.Join(cacheDir+"/"+releaseImage, baremetalInstallBinary)
Expect(path).To(Equal(filePath))
Expect(err).ShouldNot(HaveOccurred())
})

It("extract baremetal-install from release image retry exhausted", func() {
command := fmt.Sprintf(templateExtract+" --registry-config=%s",
filepath.Join(cacheDir, releaseImage), false, releaseImage, tempFilePath)
baremetalInstallBinary, filepath.Join(cacheDir, releaseImage), false, releaseImage, tempFilePath)
args := splitStringToInterfacesArray(command)
mockExecuter.EXPECT().Execute(args[0], args[1:]...).Return("", "Failed to extract the installer", 1).Times(5)

path, err := oc.Extract(log, releaseImage, "", cacheDir, pullSecret)
path, err := oc.Extract(log, releaseImage, "", cacheDir, pullSecret, models.PlatformTypeBaremetal)
Expect(path).To(Equal(""))
Expect(err).Should(HaveOccurred())
})

It("extract openshift-install from release image", func() {
command := fmt.Sprintf(templateExtract+" --registry-config=%s",
installBinary, filepath.Join(cacheDir, releaseImage), false, releaseImage, tempFilePath)
args := splitStringToInterfacesArray(command)
mockExecuter.EXPECT().Execute(args[0], args[1:]...).Return("", "", 0).Times(1)

path, err := oc.Extract(log, releaseImage, "", cacheDir, pullSecret, models.PlatformTypeNone)
filePath := filepath.Join(cacheDir+"/"+releaseImage, installBinary)
Expect(path).To(Equal(filePath))
Expect(err).ShouldNot(HaveOccurred())
})
})
})

Expand Down
5 changes: 4 additions & 1 deletion models/platform_type.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit f9b2f3d

Please sign in to comment.