Rebuilding Openshift OC Client for Mac OS 12 Monterey

 Introduction

I need to upgrade the installed OS in my Macbook Pro into Mac OS 12 Monterey, and after doing that, I just found out that the OC (oc) client no longer works. OC Client is Red Hat's replacement for kubectl, which should be used to connect to Openshift Kubernetes Clusters. The oc's versions should match the installed OKD (community) / OCP (enterprise) version, unless you want some strange errors showing. We could say than openshift is an improved kubernetes, and oc is an 'improved' kubectl. 

The error

yudhi@Yudhis-MacBook-Pro Downloads % oc

fatal error: runtime: bsdthread_register error


runtime stack:

runtime.throw(0x3a97cf6, 0x21)

/usr/local/go/src/runtime/panic.go:566 +0x95 fp=0x7ff7bfeff9d0 sp=0x7ff7bfeff9b0

runtime.goenvs()

/usr/local/go/src/runtime/os_darwin.go:88 +0xa0 fp=0x7ff7bfeffa00 sp=0x7ff7bfeff9d0

runtime.schedinit()

/usr/local/go/src/runtime/proc.go:450 +0x9c fp=0x7ff7bfeffa40 sp=0x7ff7bfeffa00

runtime.rt0_go(0x7ff7bfeffa70, 0x1, 0x7ff7bfeffa70, 0x1000, 0x1, 0x7ff7bfeffba8, 0x0, 0x7ff7bfeffbab, 0x7ff7bfeffbc7, 0x7ff7bfeffbd6, ...)

/usr/local/go/src/runtime/asm_amd64.s:145 +0x14f fp=0x7ff7bfeffa48 sp=0x7ff7bfeffa40


From the error above, it seems that there is an error in OS-specific go file (shown os_darwin.go). Further googling take us to https://github.com/golang/go/issues/49425 : runtime: bsdthread_register error on macOS 12 #49425. It seems that the binary file is compiled using an old, unsupported version of go (ok, I must admit we still running archaic version of OKD).  The only cure is to recompile the oc binary.

This a bit of far, but somehow I don't see any alternative (A colleague asked me to try 3.11 oc version, which I haven't tried yet, and if my memory serves correctly the latest version have problems connecting to old OKD cluster)


Downloading Openshift source (!)


The Openshift source code can be found in the public Github repository https://github.com/openshift/origin. I choose the version (in the tags area) and tries to make sense of the downloaded directories. Go language evolves a bit quick, where the openshift at that point in time didn't have go.mod file. 


Building the oc client

Try to locate some build script, the Makefile shows that a shell script hack/build-go.sh is being used to build cmd/oc. But examining the build-go.sh shows that this file is only being used for Linux platform, no luck for Mac OS Darwin platform. So, based on the observation that  go.mod file doesn't exist in any directory, the build command should disable go modules functionality, and try to build cmd/oc utility :

GO111MODULE=off go build cmd/oc  

However this step of course failed when we just run it without understanding how does the go build system works.


Laying out the build

In the openshift repo, we got these directories containing go files : pkg, cmd, and vendor. It seems that the cmd directory is for building command-line utilities, the pkg directory consists of directories of go files, each creating an importable package, and the vendor directory also containes directories of go files, but each supposedly under its own repository path.

This is the strategy I used :

declare -x GOPATH={repo root}

mkdir src

mkdir -p src/github.com/openshift/origin

mv cmd src/

cp -rp pkg src/github.com/openshift/origin/

mv vendor/* src/


However on second thought, this could work equally well :

declare -x GOPATH=~/go

mkdir -p $GOPATH/src/github.com/openshift/origin

cp -rp cmd pkg $GOPATH/src/github.com/openshift/origin

cd vendor

cp -rp * $GOPATH/src/


And just build it using GO111MODULE=off go build github.com/openshift/origin/cmd/oc  

One error

However, this error stopping the build process :
cannot use nil as type _Ctype_CFDataRef in assignment
This error is the same as from https://github.com/google/certificate-transparency-go/issues/131, which resulted from Go changes that are specific to Apple Darwin platform related to CF*Ref types from the CoreFoundation library in the go version 1.10. For the record my Macbook uses Go 1.17.2.
The solution I took is to edit the offending file and change from nil to 0.
Another option is to use go fix tool : go tool fix -r cftype <package name>

Installing the result

Should the go build succeeded, it will create an executable named oc in current directory. Just copy it to /usr/local/bin/oc :
cp oc /usr/local/bin/oc

Conclusion

By rebuilding the oc client from source code, we now will regain the functionality of the oc command in Mac OS Monterey.

Comments

Popular posts from this blog

Long running process in Linux using PHP

Reverse Engineering Reptile Kernel module to Extract Authentication code

SAP System Copy Lessons Learned