mirror of
https://github.com/kubevirt/containerized-data-importer.git
synced 2025-06-03 06:30:22 +00:00

Adds go templated controller manifest Adds make targets for template generation Removes hard coded version values Enables template generation and publishing in CI
171 lines
4.8 KiB
Go
171 lines
4.8 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
|
|
"github.com/golang/glog"
|
|
. "kubevirt.io/containerized-data-importer/pkg/common"
|
|
"kubevirt.io/containerized-data-importer/pkg/controller"
|
|
|
|
clientset "kubevirt.io/containerized-data-importer/pkg/client/clientset/versioned"
|
|
informers "kubevirt.io/containerized-data-importer/pkg/client/informers/externalversions"
|
|
|
|
"github.com/pkg/errors"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
k8sinformers "k8s.io/client-go/informers"
|
|
"k8s.io/client-go/kubernetes"
|
|
"k8s.io/client-go/tools/clientcmd"
|
|
)
|
|
|
|
var (
|
|
configPath string
|
|
masterURL string
|
|
importerImage string
|
|
clonerImage string
|
|
pullPolicy string
|
|
verbose string
|
|
)
|
|
|
|
// The importer and cloner images are obtained here along with the supported flags. IMPORTER_IMAGE and CLONER_IMAGE
|
|
// are required by the controller and will cause it to fail if not defined.
|
|
// Note: kubeconfig hierarchy is 1) -kubeconfig flag, 2) $KUBECONFIG exported var. If neither is
|
|
// specified we do an in-cluster config. For testing it's easiest to export KUBECONFIG.
|
|
func init() {
|
|
const IMPORTER_IMAGE = "IMPORTER_IMAGE"
|
|
const CLONER_IMAGE = "CLONER_IMAGE"
|
|
|
|
// flags
|
|
flag.StringVar(&configPath, "kubeconfig", os.Getenv("KUBECONFIG"), "(Optional) Overrides $KUBECONFIG")
|
|
flag.StringVar(&masterURL, "server", "", "(Optional) URL address of a remote api server. Do not set for local clusters.")
|
|
flag.Parse()
|
|
|
|
// env variables
|
|
importerImage = os.Getenv(IMPORTER_IMAGE)
|
|
if importerImage == "" {
|
|
glog.Fatalf("Environment Variable %q undefined\n", IMPORTER_IMAGE)
|
|
}
|
|
|
|
clonerImage = os.Getenv(CLONER_IMAGE)
|
|
if clonerImage == "" {
|
|
glog.Fatalf("Environment Variable %q undefined\n", CLONER_IMAGE)
|
|
}
|
|
|
|
pullPolicy = DEFAULT_PULL_POLICY
|
|
if pp := os.Getenv(PULL_POLICY); len(pp) != 0 {
|
|
pullPolicy = pp
|
|
}
|
|
|
|
// get the verbose level so it can be passed to the importer pod
|
|
defVerbose := fmt.Sprintf("%d", DEFAULT_VERBOSE) // note flag values are strings
|
|
verbose = defVerbose
|
|
// visit actual flags passed in and if passed check -v and set verbose
|
|
flag.Visit(func(f *flag.Flag) {
|
|
if f.Name == "v" {
|
|
verbose = f.Value.String()
|
|
}
|
|
})
|
|
if verbose == defVerbose {
|
|
glog.V(Vuser).Infof("Note: increase the -v level in the controller deployment for more detailed logging, eg. -v=%d or -v=%d\n", Vadmin, Vdebug)
|
|
}
|
|
|
|
glog.V(Vdebug).Infof("init: complete: cdi controller will create importer using image %q\n", importerImage)
|
|
}
|
|
|
|
func main() {
|
|
defer glog.Flush()
|
|
|
|
cfg, err := clientcmd.BuildConfigFromFlags(masterURL, configPath)
|
|
if err != nil {
|
|
glog.Fatalf("Unable to get kube config: %v\n", errors.WithStack(err))
|
|
}
|
|
client, err := kubernetes.NewForConfig(cfg)
|
|
if err != nil {
|
|
glog.Fatalf("Unable to get kube client: %v\n", errors.WithStack(err))
|
|
}
|
|
|
|
cdiClient, err := clientset.NewForConfig(cfg)
|
|
if err != nil {
|
|
glog.Fatalf("Error building example clientset: %s", err.Error())
|
|
}
|
|
|
|
cdiInformerFactory := informers.NewSharedInformerFactory(cdiClient, DEFAULT_RESYNC_PERIOD)
|
|
pvcInformerFactory := k8sinformers.NewSharedInformerFactory(client, DEFAULT_RESYNC_PERIOD)
|
|
podInformerFactory := k8sinformers.NewFilteredSharedInformerFactory(client, DEFAULT_RESYNC_PERIOD, "", func(options *v1.ListOptions) {
|
|
options.LabelSelector = CDI_LABEL_SELECTOR
|
|
})
|
|
|
|
pvcInformer := pvcInformerFactory.Core().V1().PersistentVolumeClaims()
|
|
podInformer := podInformerFactory.Core().V1().Pods()
|
|
dataVolumeInformer := cdiInformerFactory.Cdi().V1alpha1().DataVolumes()
|
|
|
|
dataVolumeController := controller.NewDataVolumeController(
|
|
client,
|
|
cdiClient,
|
|
pvcInformer,
|
|
dataVolumeInformer)
|
|
|
|
importController := controller.NewImportController(client,
|
|
pvcInformer.Informer(),
|
|
podInformer.Informer(),
|
|
importerImage,
|
|
pullPolicy,
|
|
verbose)
|
|
|
|
cloneController := controller.NewCloneController(client,
|
|
pvcInformer.Informer(),
|
|
podInformer.Informer(),
|
|
clonerImage,
|
|
pullPolicy,
|
|
verbose)
|
|
|
|
glog.V(Vuser).Infoln("created cdi controllers")
|
|
|
|
stopCh := handleSignals()
|
|
|
|
go cdiInformerFactory.Start(stopCh)
|
|
go pvcInformerFactory.Start(stopCh)
|
|
go podInformerFactory.Start(stopCh)
|
|
|
|
glog.V(Vuser).Infoln("started informers")
|
|
|
|
go func() {
|
|
err = dataVolumeController.Run(3, stopCh)
|
|
if err != nil {
|
|
glog.Fatalln("Error running dataVolume controller: %+v", err)
|
|
}
|
|
}()
|
|
|
|
go func() {
|
|
err = importController.Run(1, stopCh)
|
|
if err != nil {
|
|
glog.Fatalln("Error running import controller: %+v", err)
|
|
}
|
|
}()
|
|
|
|
go func() {
|
|
err = cloneController.Run(1, stopCh)
|
|
if err != nil {
|
|
glog.Fatalln("Error running clone controller: %+v", err)
|
|
}
|
|
}()
|
|
|
|
<-stopCh
|
|
glog.V(Vadmin).Infoln("cdi controller exited")
|
|
}
|
|
|
|
// Shutdown gracefully on system signals
|
|
func handleSignals() <-chan struct{} {
|
|
sigCh := make(chan os.Signal)
|
|
stopCh := make(chan struct{})
|
|
go func() {
|
|
signal.Notify(sigCh)
|
|
<-sigCh
|
|
close(stopCh)
|
|
os.Exit(1)
|
|
}()
|
|
return stopCh
|
|
}
|