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

support universal base image #95

Merged
merged 32 commits into from
Jun 25, 2020
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
64006e4
baby steps
sandoichi May 21, 2020
153c8f3
build out some more steps
sandoichi May 21, 2020
34922cb
write file with base os
sandoichi May 26, 2020
d562174
add logic to select ubi image in mage targets
sandoichi May 26, 2020
c7a9757
use ubi instead of busybox when necessary for logging container; buil…
sandoichi May 27, 2020
6db60cf
unify gh workflows and simplify steps
sandoichi May 27, 2020
a7da497
fixup! unify gh workflows and simplify steps
sandoichi May 27, 2020
8aac13d
fixup! fixup! unify gh workflows and simplify steps
sandoichi May 27, 2020
bb6dc8a
add debug print
sandoichi May 27, 2020
c7f6fd4
fixup workflow tags to push
sandoichi May 27, 2020
55e0cff
trimspace on gh package tags
sandoichi May 27, 2020
6236cd7
fixup! trimspace on gh package tags
sandoichi May 27, 2020
c4e6295
more trimspace
sandoichi May 27, 2020
b75fb46
add in logic for choosing ubi based config builder image
sandoichi May 29, 2020
97e30c2
add in dse and config builder ubi coords
sandoichi Jun 5, 2020
89540fd
add oss c* 3.11.6 image
sandoichi Jun 16, 2020
14d4c91
prefix ioutil import
sandoichi Jun 16, 2020
288402c
Add debug cat cmd to gh action
sandoichi Jun 16, 2020
7c7cfb8
Merge remote-tracking branch 'origin/master' into support-universal-b…
sandoichi Jun 16, 2020
ce01958
add conditions around checkout rules in gh workflow to avoid merging
sandoichi Jun 16, 2020
0710032
Remove debug print in gh workflow
sandoichi Jun 16, 2020
472a65e
Merge remote-tracking branch 'origin/master' into support-universal-b…
sandoichi Jun 24, 2020
3c6c780
use separate dockerfile for ubi images
sandoichi Jun 25, 2020
cb76c87
only run docker build once now
sandoichi Jun 25, 2020
7808c31
debug print in workflow
sandoichi Jun 25, 2020
ab4f8b6
more debug
sandoichi Jun 25, 2020
0aaf87b
fixup! more debug
sandoichi Jun 25, 2020
0b385eb
fixup! fixup! more debug
sandoichi Jun 25, 2020
96080eb
fixup! fixup! fixup! more debug
sandoichi Jun 25, 2020
c1ff59c
use env constant instead of string; more gh workflow debugging
sandoichi Jun 25, 2020
44fb640
workflow should be in good shape now
sandoichi Jun 25, 2020
200bff9
use correct docker tags file for gh package pushing..
sandoichi Jun 25, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
name: Cass Operator Build & Deploy
on: pull_request
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build_operator_docker:
name: Build Cass Operator Docker Image
Expand All @@ -9,8 +13,6 @@ jobs:
GOROOT: /usr/local/go1.13
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Set up Go 1.13
uses: actions/setup-go@v1
with:
Expand All @@ -31,29 +33,39 @@ jobs:
run: |
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH
mage operator:testGenerateClient
- name: Build docker
- name: Build docker - standard image
env:
MO_BRANCH: ${{ github.event.pull_request.head.ref }}
run: |
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH
mage operator:testAndBuild
cat ./build/tagsToPush.txt > ./build/fullTagsToPush.txt
echo "|" >> ./build/fullTagsToPush.txt
- name: Build docker - ubi image
env:
MO_BRANCH: ${{ github.event.pull_request.head.ref }}
MO_BASE_OS: 'registry.access.redhat.com/ubi7/ubi-minimal:7.8'
run: |
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH
mage operator:testAndBuild
cat ./build/tagsToPush.txt >> ./build/fullTagsToPush.txt
- name: Deploy to ECR
if: github.event.pull_request.head.repo.full_name == 'datastax/cass-operator'
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'datastax/cass-operator'
env:
MO_ECR_ID: ${{ secrets.ECR_ID }}
MO_ECR_SECRET: ${{ secrets.ECR_SECRET }}
MO_ECR_REPO: ${{ secrets.ECR_REPO }}
run: |
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH
export MO_TAGS=$(cat ./build/tagsToPush.txt)
export MO_TAGS=$(cat ./build/fullTagsToPush.txt)
mage operator:deployToECR
- name: Deploy to GH Packages
if: github.event.pull_request.head.repo.full_name == 'datastax/cass-operator'
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'datastax/cass-operator'
env:
MO_GH_USR: 'datastax/cass-operator'
MO_GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MO_GH_PKG_REPO: 'datastax/cass-operator/operator'
run: |
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH
export MO_TAGS=$(cat ./build/tagsToPush.txt)
export MO_TAGS=$(cat ./build/fullTagsToPush.txt)
mage operator:deployToGHPackages
56 changes: 0 additions & 56 deletions .github/workflows/operatorStableBuildAndDeploy.yml

This file was deleted.

20 changes: 17 additions & 3 deletions mage/k8s/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

const (
OperatorImage = "datastax/cass-operator:latest"
OperatorImageUBI = "datastax/cass-operator:latest-ubi"
envLoadDevImages = "M_LOAD_DEV_IMAGES"
envK8sFlavor = "M_K8S_FLAVOR"
)
Expand All @@ -38,9 +39,21 @@ var supportedFlavors = map[string]ClusterActions{
"gke": gcp.ClusterActions,
}

func getOperatorImage() string {
var img string
if baseOs := os.Getenv(operator.EnvBaseOs); baseOs != "" {
img = "datastax/cass-operator:latest-ubi"
} else {
img = "datastax/cass-operator:latest"
}
return img
}

func loadImagesFromBuildSettings(cfg ClusterActions, settings BuildSettings) {
for _, image := range settings.Dev.Images {
shutil.RunVPanic("docker", "pull", image)
// we likely don't always care if we fail to pull
// because we could be testing local images
_ = shutil.RunV("docker", "pull", image)
cfg.LoadImage(image)
}
}
Expand Down Expand Up @@ -96,7 +109,8 @@ func SetupEmptyCluster() {
clusterActions.ApplyDefaultStorage()
//TODO make this part optional
operator.BuildDocker()
clusterActions.LoadImage(OperatorImage)
operatorImg := getOperatorImage()
clusterActions.LoadImage(operatorImg)
}

// Bootstrap a cluster, then run Ginkgo integration tests.
Expand Down Expand Up @@ -131,8 +145,8 @@ func SetupExampleCluster() {
mg.Deps(SetupEmptyCluster)
kubectl.CreateSecretLiteral("cassandra-superuser-secret", "devuser", "devpass").ExecVPanic()

overrides := map[string]string{"image": getOperatorImage()}
var namespace = "default"
var overrides = map[string]string{"image": "datastax/cass-operator:latest"}
err := helm_util.Install("./charts/cass-operator-chart", "cass-operator", namespace, overrides)
mageutil.PanicOnError(err)

Expand Down
5 changes: 3 additions & 2 deletions mage/operator/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ func retagAndPush(tags []string, remoteUrl string) {
func retagAndPushForGH(tags []string) {
pkgRepo := mageutil.RequireEnv(envGHPackageRepo)
reg := regexp.MustCompile(`.*\:`)
for _, tag := range tags {
for _, t := range tags {
tag := strings.TrimSpace(t)
updatedTag := reg.ReplaceAllString(tag, fmt.Sprintf("%s:", pkgRepo))
fullGHTag := fmt.Sprintf("%s/%s", ghPackagesRegistry, updatedTag)
fullGHTag := fmt.Sprintf("%s/%s", ghPackagesRegistry, strings.TrimSpace(updatedTag))
dockerTag(tag, fullGHTag)
fmt.Printf("- Pushing image %s\n", fullGHTag)
dockerutil.Push(fullGHTag).WithCfg(rootBuildDir).ExecVPanic()
Expand Down
43 changes: 32 additions & 11 deletions mage/operator/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const (
envGitBranch = "MO_BRANCH"
envVersionString = "MO_VERSION"
envGitHash = "MO_HASH"
EnvBaseOs = "MO_BASE_OS"

errorUnstagedPreGenerate = `
Unstaged changes detected.
Expand Down Expand Up @@ -73,7 +74,7 @@ func checkForUnstagedChanges(message string) {
func writeBuildFile(fileName string, contents string) {
mageutil.EnsureDir(rootBuildDir)
outputPath := filepath.Join(rootBuildDir, fileName)
err := ioutil.WriteFile(outputPath, []byte(contents+"\n"), 0666)
err := ioutil.WriteFile(outputPath, []byte(contents), 0666)
if err != nil {
fmt.Printf("Failed to write file at %s\n", outputPath)
panic(err)
Expand Down Expand Up @@ -345,17 +346,35 @@ func calcFullVersion(settings cfgutil.BuildSettings, git GitData) FullVersion {
}
}

func runDockerBuild(version FullVersion) []string {
func calcVersionAndTags(version FullVersion) (string, []string) {
repoPath := "datastax/cass-operator"
versionedTag := fmt.Sprintf("%s:%v", repoPath, version)
tagsToPush := []string{
versionedTag,
fmt.Sprintf("%s:%s", repoPath, version.Hash),
var versionedTag string
var tagsToPush []string

if baseOs := os.Getenv(EnvBaseOs); baseOs != "" {
versionedTag = fmt.Sprintf("%s:%v-ubi", repoPath, version)
tagsToPush = []string{
versionedTag,
fmt.Sprintf("%s:%s-ubi", repoPath, version.Hash),
fmt.Sprintf("%s:latest-ubi", repoPath),
}
} else {
versionedTag = fmt.Sprintf("%s:%v", repoPath, version)
tagsToPush = []string{
versionedTag,
fmt.Sprintf("%s:%s", repoPath, version.Hash),
fmt.Sprintf("%s:latest", repoPath),
}
}
tags := append(tagsToPush, fmt.Sprintf("%s:latest", repoPath))
return versionedTag, tagsToPush
}

func runDockerBuild(versionedTag string, dockerTags []string) {
buildArgs := []string{fmt.Sprintf("VERSION_STAMP=%s", versionedTag)}
dockerutil.Build(".", "", "./operator/Dockerfile", tags, buildArgs).ExecVPanic()
return tagsToPush
if baseOs := os.Getenv(EnvBaseOs); baseOs != "" {
buildArgs = append(buildArgs, fmt.Sprintf("BASE_OS=%s", baseOs))
}
dockerutil.Build(".", "", "./operator/Dockerfile", dockerTags, buildArgs).ExecVPanic()
}

func runGoBuild(version string) {
Expand Down Expand Up @@ -419,12 +438,14 @@ func BuildDocker() {
settings := cfgutil.ReadBuildSettings()
git := getGitData()
version := calcFullVersion(settings, git)
operatorTags := runDockerBuild(version)

versionedTag, dockerTags := calcVersionAndTags(version)
runDockerBuild(versionedTag, dockerTags)
// Write the versioned image tags to a file in our build
// directory so that other targets in the build process can identify
// what was built. This is particularly important to know
// for targets that retag and deploy to external docker repositories
outputText := strings.Join(operatorTags, "|")
outputText := strings.Join(dockerTags, "|")
writeBuildFile("tagsToPush.txt", outputText)
}

Expand Down
7 changes: 6 additions & 1 deletion operator/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
##########
# "builder" compiles and tests the code
# This stage name is important to the Cloud Platform CI/CD infrastructure, and should be preserved
ARG BASE_OS=alpine:3.9
FROM golang:1.13-stretch as builder

# Disable cgo - this makes static binaries that will work on an Alpine image
Expand Down Expand Up @@ -45,9 +46,13 @@ RUN MO_VERSION=${VERSION_STAMP} mage operator:buildGo

# Second stage
# Produce a smaller image than the one used to build the code
FROM alpine:3.9
FROM ${BASE_OS}

ENV GOPATH=/go

ARG BASE_OS=""
RUN mkdir -p /var/lib/cass-operator/
RUN echo "${BASE_OS}" > /var/lib/cass-operator/base_os
WORKDIR /go

# All we need from the builder image is operator executable
Expand Down
35 changes: 35 additions & 0 deletions operator/cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ func main() {
ctx := context.Background()
// Become the leader before proceeding
err = leader.Become(ctx, "cass-operator-lock")

if err != nil {
log.Error(err, "could not become leader")
os.Exit(1)
Expand All @@ -139,6 +140,10 @@ func main() {
log.Error(err, "Failed to ensure webhook CA configuration")
}

if err = readBaseOsIntoEnv(); err != nil {
log.Error(err, "Failed to read base OS into env")
}

// Set default manager options
options := manager.Options{
Namespace: namespace,
Expand Down Expand Up @@ -207,6 +212,36 @@ func main() {
}
}

func readBaseOsIntoEnv() error {
baseOsArgFilePath := "/var/lib/cass-operator/base_os"

info, err := os.Stat(baseOsArgFilePath)
if os.IsNotExist(err) {
msg := fmt.Sprintf("Could not locate base OS arg file at %s", baseOsArgFilePath)
err = fmt.Errorf("%s. %v", msg, err)
return err
}

if info.IsDir() {
msg := fmt.Sprintf("Base OS arg path is a directory not a file: %s", baseOsArgFilePath)
err = fmt.Errorf("%s. %v", msg, err)
return err
}

rawVal, err := ioutil.ReadFile(baseOsArgFilePath)
if err != nil {
msg := fmt.Sprintf("Failed to read base OS arg file at %s", baseOsArgFilePath)
err = fmt.Errorf("%s. %v", msg, err)
return err
}

baseOs := strings.TrimSpace(string(rawVal))
os.Setenv("BASE_IMAGE_OS", baseOs)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason not to use the EnvBaseImageOs constant here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

nope, good catch!

log.Info(fmt.Sprintf("BASE_IMAGE_OS set to '%s'", baseOs))

return nil
}

// addMetrics will create the Services and Service Monitors to allow the operator export the metrics by using
// the Prometheus operator
func addMetrics(ctx context.Context, cfg *rest.Config) {
Expand Down
Loading