Skip to content

Commit

Permalink
forklift: introduce forklift controller
Browse files Browse the repository at this point in the history
Signed-off-by: Benny Zlotnik <bzlotnik@redhat.com>
  • Loading branch information
bennyz committed Jan 24, 2024
1 parent d6cb98f commit 116eeba
Show file tree
Hide file tree
Showing 16 changed files with 1,129 additions and 43 deletions.
1 change: 1 addition & 0 deletions cmd/cdi-controller/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ go_library(
"//pkg/util/cert/fetcher:go_default_library",
"//pkg/util/cert/generator:go_default_library",
"//staging/src/kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1:go_default_library",
"//staging/src/kubevirt.io/containerized-data-importer-api/pkg/apis/forklift/v1beta1:go_default_library",
"//vendor/github.com/kelseyhightower/envconfig:go_default_library",
"//vendor/github.com/kubernetes-csi/external-snapshotter/client/v6/apis/volumesnapshot/v1:go_default_library",
"//vendor/github.com/openshift/api/config/v1:go_default_library",
Expand Down
9 changes: 9 additions & 0 deletions cmd/cdi-controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/manager/signals"

cdiv1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1"
forklift "kubevirt.io/containerized-data-importer-api/pkg/apis/forklift/v1beta1"

"kubevirt.io/containerized-data-importer/pkg/common"
"kubevirt.io/containerized-data-importer/pkg/controller"
dvc "kubevirt.io/containerized-data-importer/pkg/controller/datavolume"
Expand All @@ -58,6 +60,7 @@ var (
clonerImage string
uploadServerImage string
uploadProxyServiceName string
ovirtPopulatorImage string
configName string
pullPolicy string
verbose string
Expand All @@ -69,6 +72,7 @@ var (
cdiv1.AddToScheme,
extv1.AddToScheme,
snapshotv1.AddToScheme,
forklift.AddToScheme,
imagev1.Install,
ocpconfigv1.Install,
routev1.Install,
Expand Down Expand Up @@ -101,6 +105,7 @@ func init() {
importerImage = getRequiredEnvVar("IMPORTER_IMAGE")
clonerImage = getRequiredEnvVar("CLONER_IMAGE")
uploadServerImage = getRequiredEnvVar("UPLOADSERVER_IMAGE")
ovirtPopulatorImage = getRequiredEnvVar("OVIRT_POPULATOR_IMAGE")
uploadProxyServiceName = getRequiredEnvVar("UPLOADPROXY_SERVICE")
installerLabels = map[string]string{}

Expand Down Expand Up @@ -299,6 +304,10 @@ func start() {
klog.Errorf("Unable to setup clone populator: %v", err)
os.Exit(1)
}
if _, err := populators.NewForkliftPopulator(ctx, mgr, log, importerImage, ovirtPopulatorImage, installerLabels); err != nil {
klog.Errorf("Unable to setup forklift populator: %v", err)
os.Exit(1)
}

klog.V(1).Infoln("created cdi controllers")

Expand Down
8 changes: 7 additions & 1 deletion cmd/openstack-populator/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")

go_library(
name = "go_default_library",
Expand All @@ -21,3 +21,9 @@ go_binary(
embed = [":go_default_library"],
visibility = ["//visibility:public"],
)

go_test(
name = "go_default_test",
srcs = ["openstack-populator_test.go"],
embed = [":go_default_library"],
)
7 changes: 1 addition & 6 deletions cmd/openstack-populator/openstack-populator.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"crypto/x509"
"errors"
"flag"
"fmt"
"io"
"net"
"net/http"
Expand Down Expand Up @@ -197,11 +196,7 @@ func getAuthType() (authType clientconfig.AuthType, err error) {
}

func getStringFromSecret(key string) string {
value, err := os.ReadFile(fmt.Sprintf("/etc/secret-volume/%s", key))
if err != nil {
klog.Info(err.Error())
return ""
}
value := os.Getenv(key)
return string(value)
}

Expand Down
136 changes: 136 additions & 0 deletions cmd/openstack-populator/openstack-populator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package main

import (
"fmt"
"io"
"net"
"net/http"
"net/http/httptest"
"os"
"testing"
)

func setupMockServer() (*httptest.Server, int, error) {
listener, err := net.Listen("tcp", ":0")
if err != nil {
return nil, 0, err
}

mux := http.NewServeMux()

port := listener.Addr().(*net.TCPAddr).Port
identityServerURL := fmt.Sprintf("http://localhost:%d", port)

mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
response := fmt.Sprintf(`{
"versions": {
"values": [
{
"id": "v3.0",
"links": [
{"rel": "self", "href": "%s/v3/"}
],
"status": "stable"
}
]
}
}`, identityServerURL)
fmt.Fprint(w, response)
})

mux.HandleFunc("/v2/images/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, `mock_data`)
})

mux.HandleFunc("/v3/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("X-Subject-Token", "MIIFvgY")
w.WriteHeader(http.StatusCreated)
response := `{
"token": {
"methods": ["password"],
"project": {
"domain": {
"id": "default",
"name": "Default"
},
"id": "8538a3f13f9541b28c2620eb19065e45",
"name": "admin"
},
"catalog": [
{
"type": "image",
"name": "glance",
"endpoints": [{
"url": "http://localhost:%d/v2/images",
"region": "RegionOne",
"interface": "public",
"id": "29beb2f1567642eb810b042b6719ea88"
}]
}],
"user": {
"domain": {
"id": "default",
"name": "Default"
},
"id": "3ec3164f750146be97f21559ee4d9c51",
"name": "admin"
},
"issued_at": "201406-10T20:55:16.806027Z"
}
}`
response = fmt.Sprintf(response, port)
fmt.Fprint(w, response)
})

server := httptest.NewUnstartedServer(mux)
server.Listener = listener

server.Start()

return server, port, nil
}

func TestPopulate(t *testing.T) {
os.Setenv("username", "testuser")
os.Setenv("password", "testpassword")
os.Setenv("projectID", "testproject")
os.Setenv("domainName", "testdomain")

server, port, err := setupMockServer()
if err != nil {
t.Fatalf("Failed to start mock server: %v", err)
}
defer server.Close()

fmt.Printf("Mock server running on port: %d\n", port)

fileName := "disk.img"
secretName := "test-secret"
imageID := "test-image-id"

populate(fileName, server.URL, secretName, imageID)

file, err := os.Open(fileName)
if err != nil {
t.Fatalf("Failed to open file: %v", err)
}
defer file.Close()

content, err := io.ReadAll(file)
if err != nil {
t.Fatalf("Failed to read file: %v", err)
}

if string(content) != "mock_data\n" {
t.Errorf("Expected %s, got %s", "mock_data\n", string(content))
}

err = os.Remove(fileName)
if err != nil {
t.Errorf("Failed to delete file: %v", err)
}
}
3 changes: 3 additions & 0 deletions hack/build/config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ QUAY_REPOSITORY=${QUAY_REPOSITORY:-cdi-operatorhub}
QUAY_NAMESPACE=${QUAY_NAMESPACE:-kubevirt}
CDI_LOGO_PATH=${CDI_LOGO_PATH:-"assets/cdi_logo.png"}

# oVirt populator image from forklift
OVIRT_POPULATOR_IMAGE_NAME=${OVIRT_POPULATOR_IMAGE_NAME:-"quay.io/kubev2v/ovirt-populator:release-v2.5.4"}

function allPkgs() {
ret=$(sed "s,kubevirt.io/containerized-data-importer,${CDI_DIR},g" <(go list ./pkg/... ./tools/... ./tests/... ./cmd/... | grep -v "pkg/client" | sort -u))
echo "$ret"
Expand Down
4 changes: 4 additions & 0 deletions hack/build/resource-generator.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ function generateResourceManifest() {
-apiserver-image="${DOCKER_PREFIX}/${APISERVER_IMAGE_NAME}:${DOCKER_TAG}" \
-uploadproxy-image="${DOCKER_PREFIX}/${UPLOADPROXY_IMAGE_NAME}:${DOCKER_TAG}" \
-uploadserver-image="${DOCKER_PREFIX}/${UPLOADSERVER_IMAGE_NAME}:${DOCKER_TAG}" \
-ovirt-populator-image="${OVIRT_POPULATOR_IMAGE_NAME}" \
-verbosity="${VERBOSITY}" \
-pull-policy="${PULL_POLICY}" \
-namespace="${CDI_NAMESPACE}"
Expand All @@ -64,6 +65,7 @@ function generateResourceManifest() {
-apiserver-image="{{ apiserver_image }}" \
-uploadproxy-image="{{ uploadproxy_image }}" \
-uploadserver-image="{{ uploadserver_image }}" \
-ovirt-populator-image="{{ ovirt_populator_image }}" \
-verbosity="${VERBOSITY}" \
-pull-policy="{{ pull_policy }}" \
-namespace="{{ cdi_namespace }}"
Expand Down Expand Up @@ -127,6 +129,7 @@ function populateResourceManifest() {
-apiserver-image="${DOCKER_PREFIX}/${APISERVER_IMAGE_NAME}:${DOCKER_TAG}" \
-uploadproxy-image="${DOCKER_PREFIX}/${UPLOADPROXY_IMAGE_NAME}:${DOCKER_TAG}" \
-uploadserver-image="${DOCKER_PREFIX}/${UPLOADSERVER_IMAGE_NAME}:${DOCKER_TAG}" \
-ovirt-populator-image="${OVIRT_POPULATOR_IMAGE_NAME}" \
-verbosity="${VERBOSITY}" \
-pull-policy="${PULL_POLICY}" \
-cr-name="${CR_NAME}" \
Expand All @@ -144,6 +147,7 @@ function populateResourceManifest() {
-controller-image="{{ controller_image }}" \
-importer-image="{{ importer_image }}" \
-cloner-image="{{ cloner_image }}" \
-ovirt-populator-image="{{ ovirt_populator_image }}" \
-apiserver-image="{{ apiserver_image }}" \
-uploadproxy-image="{{ uploadproxy_image }}" \
-uploadserver-image="{{ uploadserver_image }}" \
Expand Down
6 changes: 6 additions & 0 deletions pkg/controller/populators/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go_library(
name = "go_default_library",
srcs = [
"clone-populator.go",
"forklift-populator.go",
"import-populator.go",
"populator-base.go",
"upload-populator.go",
Expand All @@ -18,6 +19,7 @@ go_library(
"//pkg/feature-gates:go_default_library",
"//pkg/util:go_default_library",
"//staging/src/kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1:go_default_library",
"//staging/src/kubevirt.io/containerized-data-importer-api/pkg/apis/forklift/v1beta1:go_default_library",
"//vendor/github.com/go-logr/logr:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
Expand All @@ -29,6 +31,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/client-go/tools/record:go_default_library",
"//vendor/k8s.io/utils/ptr:go_default_library",
"//vendor/sigs.k8s.io/controller-runtime/pkg/client:go_default_library",
"//vendor/sigs.k8s.io/controller-runtime/pkg/controller:go_default_library",
"//vendor/sigs.k8s.io/controller-runtime/pkg/handler:go_default_library",
Expand All @@ -42,6 +45,7 @@ go_test(
name = "go_default_test",
srcs = [
"clone-populator_test.go",
"forklift-populator_test.go",
"import-populator_test.go",
"populators_suite_test.go",
"upload-populator_test.go",
Expand All @@ -54,6 +58,7 @@ go_test(
"//pkg/feature-gates:go_default_library",
"//pkg/token:go_default_library",
"//staging/src/kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1:go_default_library",
"//staging/src/kubevirt.io/containerized-data-importer-api/pkg/apis/forklift/v1beta1:go_default_library",
"//vendor/github.com/go-logr/logr:go_default_library",
"//vendor/github.com/kubernetes-csi/external-snapshotter/client/v6/apis/volumesnapshot/v1:go_default_library",
"//vendor/github.com/onsi/ginkgo/v2:go_default_library",
Expand All @@ -64,6 +69,7 @@ go_test(
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
Expand Down
Loading

0 comments on commit 116eeba

Please sign in to comment.