forked from kubev2v/ovirt-imageio-populator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
169 lines (147 loc) · 5.34 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package main
import (
"flag"
"fmt"
"os"
"os/exec"
populator_machinery "github.com/kubernetes-csi/lib-volume-populator/populator-machinery"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/klog/v2"
)
const (
prefix = "forklift.konveyor.io"
mountPath = "/mnt/"
devicePath = "/dev/block"
)
var version = "unknown"
func main() {
var (
mode string
engineUrl string
engineUser string
enginePassword string
engineCA string
diskID string
fileName string
httpEndpoint string
metricsPath string
masterURL string
kubeconfig string
imageName string
showVersion bool
namespace string
)
// Main arg
flag.StringVar(&mode, "mode", "", "Mode to run in (controller, populate)")
// Populate args
flag.StringVar(&engineUrl, "engine-url", "", "ovirt-engine url (https//engine.fqdn)")
flag.StringVar(&engineUser, "engine-user", "", "ovirt-engine user (admin@ovirt@internalsso)")
flag.StringVar(&enginePassword, "engine-password", "", "ovirt-engine password")
flag.StringVar(&engineCA, "ca", "", "CA file for imageio")
flag.StringVar(&diskID, "disk-id", "", "ovirt-engine disk id")
flag.StringVar(&fileName, "file-name", "", "File name to populate")
// Controller args
flag.StringVar(&kubeconfig, "kubeconfig", "", "Path to a kubeconfig. Only required if out-of-cluster.")
flag.StringVar(&masterURL, "master", "", "The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster.")
flag.StringVar(&imageName, "image-name", "", "Image to use for populating")
// Metrics args
flag.StringVar(&httpEndpoint, "http-endpoint", "", "The TCP network address where the HTTP server for diagnostics, including metrics and leader election health check, will listen (example: `:8080`). The default is empty string, which means the server is disabled.")
flag.StringVar(&metricsPath, "metrics-path", "/metrics", "The HTTP path where prometheus metrics will be exposed. Default is `/metrics`.")
// Other args
flag.BoolVar(&showVersion, "version", false, "display the version string")
flag.StringVar(&namespace, "namespace", "default", "Namespace to deploy controller")
flag.Parse()
if showVersion {
fmt.Println(os.Args[0], version)
os.Exit(0)
}
switch mode {
case "controller":
const (
groupName = "forklift.konveyor.io"
apiVersion = "v1beta1"
kind = "OvirtImageIOPopulator"
resource = "ovirtimageiopopulators"
)
var (
gk = schema.GroupKind{Group: groupName, Kind: kind}
gvr = schema.GroupVersionResource{Group: groupName, Version: apiVersion, Resource: resource}
)
populator_machinery.RunController(masterURL, kubeconfig, imageName, httpEndpoint, metricsPath,
namespace, prefix, gk, gvr, mountPath, devicePath, getPopulatorPodArgs)
case "populate":
populate(masterURL, kubeconfig, engineUrl, engineUser, enginePassword, engineCA, diskID, fileName)
default:
klog.Fatalf("Invalid mode: %s", mode)
}
}
type OvirtImageIOPopulator struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec OvirtImageIOPopulatorSpec `json:"spec"`
}
type OvirtImageIOPopulatorSpec struct {
EngineURL string `json:"engineUrl"`
EngineUser string `json:"engineUser"`
EnginePassword string `json:"enginePassword"`
EngineCA string `json:"engineCA"`
DiskID string `json:"diskId"`
}
func getPopulatorPodArgs(rawBlock bool, u *unstructured.Unstructured) ([]string, error) {
var ovirtImageIOPopulator OvirtImageIOPopulator
err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), &ovirtImageIOPopulator)
args := []string{"--mode=populate"}
if nil != err {
return nil, err
}
if rawBlock {
args = append(args, "--file-name="+devicePath)
} else {
args = append(args, "--file-name="+mountPath)
}
args = append(args, "--engine-url="+ovirtImageIOPopulator.Spec.EngineURL)
args = append(args, "--engine-user="+ovirtImageIOPopulator.Spec.EngineUser)
args = append(args, "--engine-password="+ovirtImageIOPopulator.Spec.EnginePassword)
args = append(args, "--ca="+ovirtImageIOPopulator.Spec.EngineCA)
args = append(args, "--disk-id="+ovirtImageIOPopulator.Spec.DiskID)
return args, nil
}
func populate(masterURL, kubeconfig, engineUrl, engineUser, enginePassword, ca, diskID, fileName string) {
// TODO handle block device
// Write credentials to files
ovirtPass, err := os.Create("/tmp/ovirt.pass")
if err != nil {
klog.Fatalf("Failed to create ovirt.pass %s", err)
}
defer ovirtPass.Close()
if err != nil {
klog.Fatalf("Failed to create file %s", err)
}
ovirtPass.Write([]byte(enginePassword))
cert, err := os.Create("/tmp/ca.pem")
if err != nil {
klog.Fatalf("Failed to create ca.pem %s", err)
}
defer cert.Close()
if err != nil {
klog.Fatalf("Failed to create file %s", err)
}
cert.Write([]byte(ca))
args := []string{"download-disk",
"--engine-url=" + engineUrl,
"--username=" + engineUser,
"--password-file=/tmp/ovirt.pass",
"--cafile=" + "/tmp/ca.pem",
"-f", "raw",
diskID,
fileName + "disk.img"} // TODO we don't need "disk.img" if it's a block device
cmd := exec.Command("ovirt-img", args...)
output, err := cmd.CombinedOutput()
fmt.Printf("%s\n", output)
if err != nil {
klog.Fatal(err)
}
}