Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
7 changes: 6 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ COPY . /go/src/github.com/openshift/cluster-version-operator
WORKDIR /go/src/github.com/openshift/cluster-version-operator
RUN ./hack/build-go.sh

FROM scratch
# Using alpine instead of scratch because the Job
# used to extract updatepayload from CVO image uses
# cp command.
FROM alpine
COPY --from=build-env /go/src/github.com/openshift/cluster-version-operator/_output/linux/amd64/cluster-version-operator /bin/cluster-version-operator
COPY install /manifests

ENTRYPOINT ["/bin/cluster-version-operator"]
LABEL io.openshift.release.operator true
3 changes: 2 additions & 1 deletion Gopkg.lock

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

25 changes: 25 additions & 0 deletions hack/build-image.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env bash

set -eu

# Print errors to stderr
function print_error {
echo "ERROR: $1" >&2
}

function print_info {
echo "INFO: $1" >&2
}

# Warn when unprivileged
if [ `id --user` -ne 0 ]; then
print_error "Note: Building unprivileged may fail due to permissions"
fi

if [ -z ${VERSION+a} ]; then
print_info "Using version from git..."
VERSION=$(git describe --abbrev=8 --dirty --always)
fi

set -x
podman build -t "cluster-version-operator:${VERSION}" -f Dockerfile
6 changes: 6 additions & 0 deletions install/00_clusterversionoperator_00_namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v1
kind: Namespace
metadata:
name: openshift-cluster-version
labels:
name: openshift-cluster-version
24 changes: 24 additions & 0 deletions install/00_clusterversionoperator_01_cvoconfig.crd.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
# name must match the spec fields below, and be in the form: <plural>.<group>
name: cvoconfigs.clusterversion.openshift.io
spec:
# group name to use for REST API: /apis/<group>/<version>
group: clusterversion.openshift.io
# list of versions supported by this CustomResourceDefinition
versions:
- name: v1
# Each version can be enabled/disabled by Served flag.
served: true
# One and only one version must be marked as the storage version.
storage: true
# either Namespaced or Cluster
scope: Namespaced
names:
# plural name to be used in the URL: /apis/<group>/<version>/<plural>
plural: cvoconfigs
# singular name to be used as an alias on the CLI and for display
singular: cvoconfig
# kind is normally the CamelCased singular type. Your resource manifests use this.
kind: CVOConfig
11 changes: 11 additions & 0 deletions install/00_clusterversionoperator_02_roles.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-version-operator
roleRef:
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
namespace: openshift-cluster-version
name: default
30 changes: 30 additions & 0 deletions install/00_clusterversionoperator_03_scc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
annotations:
kubernetes.io/description: "privileged-cluster-version-operator for running cluster version operator."
name: privileged-cluster-version-operator
allowHostDirVolumePlugin: true
allowHostIPC: true
allowHostNetwork: true
allowHostPID: true
allowHostPorts: true
allowPrivilegedContainer: true
allowedCapabilities:
- "*"
fsGroup:
type: RunAsAny
groups:
- system:serviceaccounts:openshift-cluster-version
readOnlyRootFilesystem: false
runAsUser:
type: RunAsAny
seLinuxContext:
type: RunAsAny
seccompProfiles:
- "*"
supplementalGroups:
type: RunAsAny
users: []
volumes:
- "*"
48 changes: 48 additions & 0 deletions install/00_clusterversionoperator_04_deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: cluster-version-operator
namespace: openshift-cluster-version
spec:
selector:
matchLabels:
k8s-app: cluster-version-operator
template:
metadata:
name: cluster-version-operator
labels:
k8s-app: cluster-version-operator
spec:
containers:
- name: cluster-version-operator
image: docker.io/origin/origin-cluster-version-operator:v4.0.0
imagePullPolicy: Always
args:
- "start"
- "--enable-auto-update=false"
- "--v=4"
volumeMounts:
- mountPath: /etc/ssl/certs
name: etc-ssl-certs
readOnly: true
- mountPath: /etc/cvo/updatepayloads
name: etc-cvo-updatepayloads
readOnly: true
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
nodeSelector:
node-role.kubernetes.io/master: ""
tolerations:
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
volumes:
- name: etc-ssl-certs
hostPath:
path: /etc/ssl/certs
- name: etc-cvo-updatepayloads
hostPath:
path: /etc/cvo/updatepayloads
105 changes: 8 additions & 97 deletions lib/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"sort"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
Expand Down Expand Up @@ -61,116 +58,30 @@ func (m *Manifest) UnmarshalJSON(in []byte) error {
// Object returns underlying metav1.Object
func (m *Manifest) Object() metav1.Object { return m.obj }

const (
// rootDirKey is used as key for the manifest files in root dir
// passed to LoadManifests
// It is set to `000` to give it more priority if the actor sorts
// based on keys.
rootDirKey = "000"
)

// LoadManifests loads manifest from disk.
//
// root/
// manifest0
// manifest1
// 00_subdir0/
// manifest0
// manifest1
// 01_subdir1/
// manifest0
// manifest1
// LoadManifests(<abs path to>/root):
// returns map
// 000: [manifest0, manifest1]
// 00_subdir0: [manifest0, manifest1]
// 01_subdir1: [manifest0, manifest1]
//
// It skips dirs that have not files.
// It only reads dir `p` and its direct subdirs.
func LoadManifests(p string) (map[string][]Manifest, error) {
var out = make(map[string][]Manifest)

fs, err := ioutil.ReadDir(p)
if err != nil {
return nil, err
}

// We want to accumulate all the errors, not returning at the
// first error encountered when reading subdirs.
var errs []error

// load manifest files in p to rootDirKey
ms, err := loadManifestsFromDir(p)
if err != nil {
errs = append(errs, fmt.Errorf("error loading from dir %s: %v", p, err))
}
if len(ms) > 0 {
out[rootDirKey] = ms
}

// load manifests from subdirs to subdir-name
for _, f := range fs {
if !f.IsDir() {
continue
}
path := filepath.Join(p, f.Name())
ms, err := loadManifestsFromDir(path)
if err != nil {
errs = append(errs, fmt.Errorf("error loading from dir %s: %v", path, err))
continue
}
if len(ms) > 0 {
out[f.Name()] = ms
}
}

agg := utilerrors.NewAggregate(errs)
if agg != nil {
return nil, errors.New(agg.Error())
}
return out, nil
}

// loadManifestsFromDir only returns files. not subdirs are traversed.
// returns manifests in increasing order of their filename.
func loadManifestsFromDir(dir string) ([]Manifest, error) {
// ManifestsFromFiles reads files and returns Manifests in the same order.
// files should be list of absolute paths for the manifests on disk.
func ManifestsFromFiles(files []string) ([]Manifest, error) {
var manifests []Manifest
fs, err := ioutil.ReadDir(dir)
if err != nil {
return nil, err
}

// ensure sorted.
sort.Slice(fs, func(i, j int) bool {
return fs[i].Name() < fs[j].Name()
})

var errs []error
for _, f := range fs {
if f.IsDir() {
continue
}

path := filepath.Join(dir, f.Name())
file, err := os.Open(path)
for _, file := range files {
file, err := os.Open(file)
if err != nil {
errs = append(errs, fmt.Errorf("error opening %s: %v", path, err))
errs = append(errs, fmt.Errorf("error opening %s: %v", file.Name(), err))
continue
}
defer file.Close()

ms, err := parseManifests(file)
if err != nil {
errs = append(errs, fmt.Errorf("error parsing %s: %v", path, err))
errs = append(errs, fmt.Errorf("error parsing %s: %v", file.Name(), err))
continue
}
manifests = append(manifests, ms...)
}

agg := utilerrors.NewAggregate(errs)
if agg != nil {
return nil, fmt.Errorf("error loading manifests from %q: %v", dir, agg.Error())
return nil, fmt.Errorf("error loading manifests: %v", agg.Error())
}

return manifests, nil
Expand Down
Loading