Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCPBUGS-25461: Add RHEL9 and RHEL8 based oc as new targets in command extraction #1647

Merged
merged 5 commits into from Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions images/cli-artifacts/Dockerfile.rhel
Expand Up @@ -18,6 +18,10 @@ RUN cd /usr/share/openshift && \
ln -sf /usr/share/openshift/linux_$(uname -m | sed 's/aarch64/arm64/;s/x86_64/amd64/')/oc /usr/bin/oc && \
mv windows_amd64 windows && mv darwin_amd64 mac && mv darwin_arm64 mac_arm64

RUN ln -sf /usr/share/openshift/linux_amd64/oc /usr/share/openshift/linux_amd64/oc.rhel8
RUN ln -sf /usr/share/openshift/linux_arm64/oc /usr/share/openshift/linux_arm64/oc.rhel8
RUN ln -sf /usr/share/openshift/linux_ppc64le/oc /usr/share/openshift/linux_ppc64le/oc.rhel8
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any extract target for ppc64le?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I added it just to support when/if there is a demand to extract oc in ppc64le arch type but I can remove, if it creates confusion.


COPY --from=builder-rhel-9 /go/src/github.com/openshift/oc/_output/bin/linux_amd64/oc /usr/share/openshift/linux_amd64/oc.rhel9
COPY --from=builder-rhel-9 /go/src/github.com/openshift/oc/_output/bin/linux_arm64/oc /usr/share/openshift/linux_arm64/oc.rhel9
COPY --from=builder-rhel-9 /go/src/github.com/openshift/oc/_output/bin/linux_ppc64le/oc /usr/share/openshift/linux_ppc64le/oc.rhel9
Expand Down
92 changes: 85 additions & 7 deletions pkg/cli/admin/release/extract_tools.go
Expand Up @@ -58,11 +58,12 @@ type extractTarget struct {
InjectReleaseVersion bool
SignMachOBinary bool

ArchiveFormat string
AsArchive bool
AsZip bool
Readme string
LinkTo []string
ArchiveFormat string
AsArchive bool
AsZip bool
Readme string
LinkTo []string
TargetCommandName string

Mapping extract.Mapping
}
Expand Down Expand Up @@ -265,6 +266,30 @@ func (o *ExtractOptions) extractCommand(command string) error {
InjectReleaseVersion: true,
ArchiveFormat: "openshift-client-linux-amd64-%s.tar.gz",
},
{
OS: "linux",
Arch: "amd64",
Command: "oc.rhel9",
Mapping: extract.Mapping{Image: "cli-artifacts", From: "usr/share/openshift/linux_amd64/oc.rhel9"},

LinkTo: []string{"kubectl"},
Readme: readmeCLIUnix,
InjectReleaseVersion: true,
ArchiveFormat: "openshift-client-linux-amd64-rhel9-%s.tar.gz",
TargetCommandName: "oc",
},
{
OS: "linux",
Arch: "amd64",
Command: "oc.rhel8",
Mapping: extract.Mapping{Image: "cli-artifacts", From: "usr/share/openshift/linux_amd64/oc.rhel8"},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How's the symlink processing implemented here? Will the extracted binary be a symlink or the symlink target?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will the final binary be oc or oc.rhel8? I prefer oc only.

Copy link
Member Author

@ardaguclu ardaguclu Jan 4, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for review.

How's the symlink processing implemented here? Will the extracted binary be a symlink or the symlink target?

For which symlink are you asking oc -> kubectl or oc -> oc.rhel8?. If it is for oc -> oc.rhel8, it is the same principle of

ln -sf /usr/share/openshift/linux_$(uname -m | sed 's/aarch64/arm64/;s/x86_64/amd64/')/oc /usr/bin/oc && \
and
{
OS: "linux",
Arch: "amd64",
Command: "oc",
Mapping: extract.Mapping{Image: "cli-artifacts", From: "usr/share/openshift/linux_amd64/oc"},
LinkTo: []string{"kubectl"},
Readme: readmeCLIUnix,
InjectReleaseVersion: true,
ArchiveFormat: "openshift-client-linux-amd64-%s.tar.gz",
},
. Extracted binary is a real binary not a symlink.

Will the final binary be oc or oc.rhel8? I prefer oc only.

Good point and it would be nicer, I can change them to oc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ingvagabund I've added new optional TargetCommandName field to rename extracted binaries.


LinkTo: []string{"kubectl"},
Readme: readmeCLIUnix,
InjectReleaseVersion: true,
ArchiveFormat: "openshift-client-linux-amd64-rhel8-%s.tar.gz",
TargetCommandName: "oc",
},
{
OS: "linux",
Arch: "arm64",
Expand All @@ -277,6 +302,32 @@ func (o *ExtractOptions) extractCommand(command string) error {
InjectReleaseVersion: true,
ArchiveFormat: "openshift-client-linux-arm64-%s.tar.gz",
},
{
OS: "linux",
Arch: "arm64",
Command: "oc.rhel9",
NewArch: true,
Mapping: extract.Mapping{Image: "cli-artifacts", From: "usr/share/openshift/linux_arm64/oc.rhel9"},

LinkTo: []string{"kubectl"},
Readme: readmeCLIUnix,
InjectReleaseVersion: true,
ArchiveFormat: "openshift-client-linux-arm64-rhel9-%s.tar.gz",
TargetCommandName: "oc",
},
{
OS: "linux",
Arch: "arm64",
Command: "oc.rhel8",
NewArch: true,
Mapping: extract.Mapping{Image: "cli-artifacts", From: "usr/share/openshift/linux_arm64/oc.rhel8"},

LinkTo: []string{"kubectl"},
Readme: readmeCLIUnix,
InjectReleaseVersion: true,
ArchiveFormat: "openshift-client-linux-arm64-rhel8-%s.tar.gz",
TargetCommandName: "oc",
},
{
OS: "windows",
Arch: "amd64",
Expand Down Expand Up @@ -499,6 +550,7 @@ func (o *ExtractOptions) extractCommand(command string) error {
}
exactReleaseImage := refExact.String()

targetArchCommands := make(map[string]struct{})
// resolve target image references to their pull specs
missing := sets.NewString()
var validTargets []extractTarget
Expand All @@ -513,9 +565,23 @@ func (o *ExtractOptions) extractCommand(command string) error {
continue
}
}

if target.Arch == targetReleaseArch {
targetArchCommands[target.Command] = struct{}{}
}

if target.OS == "linux" && target.Arch == releaseArch {
klog.V(2).Infof("Skipping duplicate %s", target.ArchiveFormat)
continue
if _, ok := targetArchCommands[target.Command]; ok {
// Some target commands have release-arch types that defines extracting
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this corner case introduced with rhel8/rhel9 change? Or, has it been around for some time already?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has existed for a long time (from this commit 3dba61a), but it didn't cause any problem because all the targets have release-arch type until now. oc.rhel9 and oc.rhel8 have their own static arch types.

// the command in whatever release architecture type is set(e.g. linux/amd64)
// But there is also another target type for these commands specifically set to
// each architecture type(linux/amd64, linux/arm64) and it is expected that
// one of these arch types collide with release-arch type. Thus,
// to prevent duplicate extraction, we have to skip the one colliding with release-arch type.
// However, we need to skip per command name because some command may not have release-arch type.
klog.V(2).Infof("Skipping duplicate %s", target.ArchiveFormat)
continue
}
}
spec, err := findImageSpec(release.References, target.Mapping.Image, o.From)
if err != nil && !target.NewArch {
Expand All @@ -529,6 +595,11 @@ func (o *ExtractOptions) extractCommand(command string) error {
}
target.Mapping.Image = spec
target.Mapping.ImageRef = imagesource.TypedImageReference{Ref: ref, Type: imagesource.DestinationRegistry}
// if the name of the extracted binary is set to different from the
// actual command name, we set it to new target command name.
if target.TargetCommandName != "" {
target.Command = target.TargetCommandName
}
if target.AsArchive {
willArchive = true
target.Mapping.Name = fmt.Sprintf(target.ArchiveFormat, releaseName)
Expand Down Expand Up @@ -830,6 +901,13 @@ func (o *ExtractOptions) extractCommand(command string) error {
if target.NewArch {
continue
}
if command == "" && (strings.Contains(target.Mapping.From, "rhel9") || strings.Contains(target.Mapping.From, "rhel8")) {
// if user explicitly wants to extract oc.rhel9(or installer.rhel9) via --command=oc.rhel9 and
// if release does not have this binary, we can safely return error.
// On the other hand, if user wants to extract all the tooling in older versions via --tools flag,
// we shouldn't print any error indicating that oc.rhel9 does not exist in this release payload.
continue
}
missing = append(missing, target.Mapping.From)
}
sort.Strings(missing)
Expand Down