Skip to content

Commit

Permalink
Add ImageTag and ImageRegistry fields to KubeVirt object
Browse files Browse the repository at this point in the history
Signed-off-by: David Vossel <[email protected]>
  • Loading branch information
davidvossel committed Mar 8, 2019
1 parent c9076c9 commit 5e3ef21
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 94 deletions.
14 changes: 14 additions & 0 deletions pkg/api/v1/openapi_generated.go

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

7 changes: 7 additions & 0 deletions pkg/api/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1050,6 +1050,13 @@ func (kl *KubeVirtList) GetListMeta() meta.List {
// ---
// +k8s:openapi-gen=true
type KubeVirtSpec struct {
// The image tag to use for the continer images installed.
// Defaults to the same tag as the operator's container image.
ImageTag string `json:"imageTag,omitempty"`
// The image registry to pull the container images from
// Defaults to the same registry the operator's container image is pulled from.
ImageRegistry string `json:"imageRegistry,omitempty"`

// The ImagePullPolicy to use.
ImagePullPolicy k8sv1.PullPolicy `json:"imagePullPolicy,omitempty" valid:"required"`
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/api/v1/types_swagger_generated.go

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

44 changes: 32 additions & 12 deletions pkg/virt-operator/kubevirt.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,10 @@ func (c *KubeVirtController) execute(key string) error {
return syncError
}

func (c *KubeVirtController) generateInstallStrategyJob(kv *v1.KubeVirt, imageTag string, imageRegistry string) *batchv1.Job {
func (c *KubeVirtController) generateInstallStrategyJob(kv *v1.KubeVirt) *batchv1.Job {

imageTag := c.getImageTag(kv)
imageRegistry := c.getImageRegistry(kv)

pullPolicy := k8sv1.PullIfNotPresent
if string(kv.Spec.ImagePullPolicy) != "" {
Expand Down Expand Up @@ -559,6 +562,20 @@ func (c *KubeVirtController) deleteAllInstallStrategy() error {
return nil
}

func (c *KubeVirtController) getImageTag(kv *v1.KubeVirt) string {
if kv.Spec.ImageTag == "" {
return c.config.ImageTag
}
return kv.Spec.ImageTag
}

func (c *KubeVirtController) getImageRegistry(kv *v1.KubeVirt) string {
if kv.Spec.ImageRegistry == "" {
return c.config.ImageRegistry
}
return kv.Spec.ImageRegistry
}

// Loads install strategies into memory, and generates jobs to
// create install strategies that don't exist yet.
func (c *KubeVirtController) loadInstallStrategy(kv *v1.KubeVirt) (*installstrategy.InstallStrategy, bool, error) {
Expand All @@ -569,27 +586,27 @@ func (c *KubeVirtController) loadInstallStrategy(kv *v1.KubeVirt) (*installstrat
}

// 1. see if we already loaded the install strategy
strategy, ok := c.getInstallStrategyFromMap(c.config.ImageTag)
strategy, ok := c.getInstallStrategyFromMap(c.getImageTag(kv))
if ok {
// we already loaded this strategy into memory
return strategy, false, nil
}

// 2. look for install strategy config map in cache.
strategy, err = installstrategy.LoadInstallStrategyFromCache(c.stores, kv.Namespace, c.config.ImageTag)
strategy, err = installstrategy.LoadInstallStrategyFromCache(c.stores, kv.Namespace, c.getImageTag(kv))
if err == nil {
c.installStrategyMutex.Lock()
defer c.installStrategyMutex.Unlock()
c.installStrategyMap[c.config.ImageTag] = strategy
log.Log.Infof("Loaded install strategy for kubevirt version %s into cache", c.config.ImageTag)
c.installStrategyMap[c.getImageTag(kv)] = strategy
log.Log.Infof("Loaded install strategy for kubevirt version %s into cache", c.getImageTag(kv))
return strategy, false, nil
}

log.Log.Infof("Install strategy config map not loaded. reason: %v", err)

// 3. See if we have a pending job in flight for this install strategy.
batch := c.clientset.BatchV1()
job := c.generateInstallStrategyJob(kv, c.config.ImageTag, c.config.ImageRegistry)
job := c.generateInstallStrategyJob(kv)

obj, exists, _ := c.stores.InstallStrategyJobCache.Get(job)
if exists {
Expand All @@ -599,7 +616,7 @@ func (c *KubeVirtController) loadInstallStrategy(kv *v1.KubeVirt) (*installstrat
// job completed but we don't have a install strategy still
// delete the job and we'll re-execute it once it is removed.

log.Log.Object(cachedJob).Errorf("Job failed to create install strategy for version %s", c.config.ImageTag)
log.Log.Object(cachedJob).Errorf("Job failed to create install strategy for version %s", c.getImageTag(kv))
if cachedJob.DeletionTimestamp == nil {

// Just in case there's an issue causing the job to fail
Expand Down Expand Up @@ -634,7 +651,7 @@ func (c *KubeVirtController) loadInstallStrategy(kv *v1.KubeVirt) (*installstrat

return nil, true, err
}
log.Log.Object(cachedJob).Errorf("Deleting job for install strategy version %s because configmap was not generated", c.config.ImageTag)
log.Log.Object(cachedJob).Errorf("Deleting job for install strategy version %s because configmap was not generated", c.getImageTag(kv))
}
// waiting on deleted job to disappear before re-creating it.
return nil, true, err
Expand All @@ -652,7 +669,7 @@ func (c *KubeVirtController) loadInstallStrategy(kv *v1.KubeVirt) (*installstrat
c.kubeVirtExpectations.InstallStrategyJob.LowerExpectations(kvkey, 1, 0)
return nil, true, err
}
log.Log.Infof("Created job to generate install strategy configmap for version %s", c.config.ImageTag)
log.Log.Infof("Created job to generate install strategy configmap for version %s", c.getImageTag(kv))

// pending is true here because we're waiting on the job
// to generate the install strategy
Expand All @@ -664,9 +681,9 @@ func (c *KubeVirtController) syncDeployment(kv *v1.KubeVirt) error {
logger.Infof("Handling deployment")

// Set versions...
if kv.Status.OperatorVersion == "" {
util.SetVersions(kv, c.config)
}
util.SetOperatorVersion(kv)
// record the version we're targetting to install
kv.Status.TargetKubeVirtVersion = c.getImageTag(kv)

// Set phase to deploying
kv.Status.Phase = v1.KubeVirtPhaseDeploying
Expand Down Expand Up @@ -718,6 +735,9 @@ func (c *KubeVirtController) syncDeployment(kv *v1.KubeVirt) error {

if objectsAdded == 0 {

// record the version just installed
kv.Status.ObservedKubeVirtVersion = c.getImageTag(kv)

// add Created condition
util.UpdateCondition(kv, v1.KubeVirtConditionCreated, k8sv1.ConditionTrue, ConditionReasonDeploymentCreated, "All resources were created.")
logger.Info("All KubeVirt resources created")
Expand Down
11 changes: 7 additions & 4 deletions pkg/virt-operator/kubevirt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import (
"kubevirt.io/kubevirt/pkg/kubecli"
"kubevirt.io/kubevirt/pkg/log"
"kubevirt.io/kubevirt/pkg/testutils"
"kubevirt.io/kubevirt/pkg/version"
"kubevirt.io/kubevirt/pkg/virt-operator/creation/components"
"kubevirt.io/kubevirt/pkg/virt-operator/creation/rbac"
"kubevirt.io/kubevirt/pkg/virt-operator/install-strategy"
Expand Down Expand Up @@ -725,7 +726,9 @@ var _ = Describe("KubeVirt Operator", func() {
Message: "All components are ready.",
},
},
OperatorVersion: "v9.9.9",
OperatorVersion: version.Get().String(),
TargetKubeVirtVersion: "v9.9.9",
ObservedKubeVirtVersion: "v9.9.9",
},
}

Expand Down Expand Up @@ -819,7 +822,7 @@ var _ = Describe("KubeVirt Operator", func() {
Status: v1.KubeVirtStatus{},
}

job := controller.generateInstallStrategyJob(kv, "v9.9.9", "somerepository")
job := controller.generateInstallStrategyJob(kv)

// will only create a new job after 10 seconds has passed.
// this is just a simple mechanism to prevent spin loops
Expand Down Expand Up @@ -850,7 +853,7 @@ var _ = Describe("KubeVirt Operator", func() {
Status: v1.KubeVirtStatus{},
}

job := controller.generateInstallStrategyJob(kv, "v9.9.9", "somerepository")
job := controller.generateInstallStrategyJob(kv)

job.Status.CompletionTime = now()

Expand All @@ -876,7 +879,7 @@ var _ = Describe("KubeVirt Operator", func() {
addKubeVirt(kv)
addInstallStrategy()

job := controller.generateInstallStrategyJob(kv, "v9.9.9", "somerepository")
job := controller.generateInstallStrategyJob(kv)

job.Status.CompletionTime = now()
addInstallStrategyJob(job)
Expand Down
79 changes: 1 addition & 78 deletions pkg/virt-operator/util/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,12 @@
package util

import (
"fmt"
"time"

secv1 "github.com/openshift/api/security/v1"

k8sv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/cache"

virtv1 "kubevirt.io/kubevirt/pkg/api/v1"
"kubevirt.io/kubevirt/pkg/kubecli"
Expand Down Expand Up @@ -116,83 +114,8 @@ func hasFinalizer(kv *virtv1.KubeVirt) bool {
return false
}

func SetVersions(kv *virtv1.KubeVirt, config KubeVirtDeploymentConfig) {

func SetOperatorVersion(kv *virtv1.KubeVirt) {
kv.Status.OperatorVersion = version.Get().String()

// Note: for now we just set targetKubeVirtVersion and observedKubeVirtVersion to the tag of the operator image
// In future this needs some more work...
kv.Status.TargetKubeVirtVersion = config.ImageTag
kv.Status.ObservedKubeVirtVersion = config.ImageTag

}

func UpdateScc(clientset kubecli.KubevirtClient, sccStore cache.Store, kv *virtv1.KubeVirt, add bool) error {

privSccObj, exists, err := sccStore.GetByKey("privileged")
if !exists {
return nil
} else if err != nil {
return err
}

privScc, ok := privSccObj.(*secv1.SecurityContextConstraints)
if !ok {
return fmt.Errorf("couldn't cast object to SecurityContextConstraints: %+v", privSccObj)
}
privSccCopy := privScc.DeepCopy()

var kubeVirtAccounts []string
prefix := "system:serviceaccount"
kubeVirtAccounts = append(kubeVirtAccounts, fmt.Sprintf("%s:%s:%s", prefix, kv.Namespace, "kubevirt-handler"))
kubeVirtAccounts = append(kubeVirtAccounts, fmt.Sprintf("%s:%s:%s", prefix, kv.Namespace, "kubevirt-apiserver"))
kubeVirtAccounts = append(kubeVirtAccounts, fmt.Sprintf("%s:%s:%s", prefix, kv.Namespace, "kubevirt-controller"))

modified := false
users := privSccCopy.Users
for _, acc := range kubeVirtAccounts {
if add {
if !contains(users, acc) {
users = append(users, acc)
modified = true
}
} else {
removed := false
users, removed = remove(users, acc)
modified = modified || removed
}
}
if modified {
privSccCopy.Users = users
_, err = clientset.SecClient().SecurityContextConstraints().Update(privSccCopy)
if err != nil {
return fmt.Errorf("unable to update scc: %v", err)
}
}

return nil
}

func contains(users []string, user string) bool {
for _, u := range users {
if u == user {
return true
}
}
return false
}

func remove(users []string, user string) ([]string, bool) {
var newUsers []string
modified := false
for _, u := range users {
if u != user {
newUsers = append(newUsers, u)
} else {
modified = true
}
}
return newUsers, modified
}

func IsOnOpenshift(clientset kubecli.KubevirtClient) (bool, error) {
Expand Down

0 comments on commit 5e3ef21

Please sign in to comment.