Skip to content
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.
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