Skip to content

Commit

Permalink
Adding OVA flow for migration
Browse files Browse the repository at this point in the history
Signed-off-by: Bella Khizgiyaev <bkhizgiy@redhat.com>
  • Loading branch information
bkhizgiy authored and ahadas committed Jul 27, 2023
1 parent d80ee2f commit c33a65b
Show file tree
Hide file tree
Showing 36 changed files with 1,518 additions and 74 deletions.
1 change: 1 addition & 0 deletions cmd/ova-provider-server/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go_library(
srcs = ["ova-provider-server.go"],
importpath = "github.com/konveyor/forklift-controller/cmd/ova-provider-server",
visibility = ["//visibility:private"],
deps = ["//vendor/github.com/google/uuid"],
)

go_binary(
Expand Down
122 changes: 107 additions & 15 deletions cmd/ova-provider-server/ova-provider-server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@ package main

import (
"archive/tar"
"bytes"
"crypto/sha256"
"encoding/gob"
"encoding/hex"
"encoding/json"
"encoding/xml"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"

"github.com/google/uuid"
)

// xml struct
Expand All @@ -28,6 +35,7 @@ type Item struct {
HostResource string `xml:"HostResource,omitempty"`
Connection string `xml:"Connection,omitempty"`
Configs []VirtualConfig `xml:"Config"`
CoresPerSocket string `xml:"CoresPerSocket"`
}

type VirtualConfig struct {
Expand All @@ -43,6 +51,12 @@ type VirtualHardwareSection struct {
Configs []VirtualConfig `xml:"Config"`
}

type References struct {
File []struct {
Href string `xml:"href,attr"`
} `xml:"File"`
}

type DiskSection struct {
XMLName xml.Name `xml:"DiskSection"`
Info string `xml:"Info"`
Expand All @@ -51,12 +65,12 @@ type DiskSection struct {

type Disk struct {
XMLName xml.Name `xml:"Disk"`
Capacity string `xml:"capacity,attr"`
Capacity int64 `xml:"capacity,attr"`
CapacityAllocationUnits string `xml:"capacityAllocationUnits,attr"`
DiskId string `xml:"diskId,attr"`
FileRef string `xml:"fileRef,attr"`
Format string `xml:"format,attr"`
PopulatedSize string `xml:"populatedSize,attr"`
PopulatedSize int64 `xml:"populatedSize,attr"`
}

type NetworkSection struct {
Expand All @@ -77,6 +91,7 @@ type VirtualSystem struct {
OperatingSystemSection struct {
Info string `xml:"Info"`
Description string `xml:"Description"`
OsType string `xml:"osType,attr"`
} `xml:"OperatingSystemSection"`
HardwareSection VirtualHardwareSection `xml:"VirtualHardwareSection"`
}
Expand All @@ -86,12 +101,14 @@ type Envelope struct {
VirtualSystem []VirtualSystem `xml:"VirtualSystem"`
DiskSection DiskSection `xml:"DiskSection"`
NetworkSection NetworkSection `xml:"NetworkSection"`
References References `xml:"References"`
}

// vm struct
type VM struct {
Name string
OvaPath string
OsType string
RevisionValidated int64
PolicyVersion int
UUID string
Expand All @@ -104,6 +121,8 @@ type VM struct {
CpuCount int32
CoresPerSocket int32
MemoryMB int32
MemoryUnits string
CpuUnits string
BalloonedMemory int32
IpAddress string
NumaNodeAffinity []string
Expand All @@ -117,13 +136,15 @@ type VM struct {

// Virtual Disk.
type VmDisk struct {
ID string
Name string
FilePath string
Capacity string
Capacity int64
CapacityAllocationUnits string
DiskId string
FileRef string
Format string
PopulatedSize string
PopulatedSize int64
}

// Virtual Device.
Expand All @@ -138,18 +159,28 @@ type Conf struct {

// Virtual ethernet card.
type NIC struct {
Name string `json:"name"`
MAC string `json:"mac"`
Config []Conf
Name string `json:"name"`
MAC string `json:"mac"`
Network string
Config []Conf
}

type VmNetwork struct {
Name string
Description string
ID string
}

var vmIDMap *UUIDMap
var diskIDMap *UUIDMap
var networkIDMap *UUIDMap

func main() {

vmIDMap = NewUUIDMap()
diskIDMap = NewUUIDMap()
networkIDMap = NewUUIDMap()

http.HandleFunc("/vms", vmHandler)
http.HandleFunc("/disks", diskHandler)
http.HandleFunc("/networks", networkHandler)
Expand Down Expand Up @@ -346,20 +377,31 @@ func convertToVmStruct(envelope []Envelope, ovaPath []string) ([]VM, error) {
newVM := VM{
OvaPath: ovaPath[i],
Name: virtualSystem.Name,
OsType: virtualSystem.OperatingSystemSection.OsType,
}

for _, item := range virtualSystem.HardwareSection.Items {
if strings.Contains(item.ElementName, "Network adapter") {
newVM.NICs = append(newVM.NICs, NIC{
Name: item.ElementName,
MAC: item.Address,
Name: item.ElementName,
MAC: item.Address,
Network: item.Connection,
})
//for _conf := range item.
} else if strings.Contains(item.Description, "Number of Virtual CPUs") {
newVM.CpuCount = item.VirtualQuantity

newVM.CpuUnits = item.AllocationUnits
if item.CoresPerSocket != "" {
num, err := strconv.ParseInt(item.CoresPerSocket, 10, 32)
if err != nil {
newVM.CoresPerSocket = 1
} else {
newVM.CoresPerSocket = int32(num)
}
}
} else if strings.Contains(item.Description, "Memory Size") {
newVM.MemoryMB = item.VirtualQuantity
newVM.MemoryUnits = item.AllocationUnits

} else {
newVM.Devices = append(newVM.Devices, Device{
Expand All @@ -369,7 +411,8 @@ func convertToVmStruct(envelope []Envelope, ovaPath []string) ([]VM, error) {

}

for _, disk := range vmXml.DiskSection.Disks {
for j, disk := range vmXml.DiskSection.Disks {
name := envelope[i].References.File[j].Href
newVM.Disks = append(newVM.Disks, VmDisk{
FilePath: getDiskPath(ovaPath[i]),
Capacity: disk.Capacity,
Expand All @@ -378,13 +421,17 @@ func convertToVmStruct(envelope []Envelope, ovaPath []string) ([]VM, error) {
FileRef: disk.FileRef,
Format: disk.Format,
PopulatedSize: disk.PopulatedSize,
Name: name,
})
newVM.Disks[j].ID = diskIDMap.GetUUID(newVM.Disks[j], ovaPath[i]+"/"+name)

}

for _, network := range vmXml.NetworkSection.Networks {
newVM.Networks = append(newVM.Networks, VmNetwork{
Name: network.Name,
Description: network.Description,
ID: networkIDMap.GetUUID(network.Name, network.Name),
})
}

Expand All @@ -399,6 +446,15 @@ func convertToVmStruct(envelope []Envelope, ovaPath []string) ([]VM, error) {
newVM.CpuHotRemoveEnabled, _ = strconv.ParseBool(conf.Value)
}
}

var id string
if isValidUUID(virtualSystem.ID) {
id = virtualSystem.ID
} else {
id = vmIDMap.GetUUID(newVM, ovaPath[i])
}
newVM.UUID = id

vms = append(vms, newVM)
}
}
Expand All @@ -412,6 +468,7 @@ func convertToNetworkStruct(envelope []Envelope) ([]VmNetwork, error) {
newNetwork := VmNetwork{
Name: network.Name,
Description: network.Description,
ID: networkIDMap.GetUUID(network.Name, network.Name),
}
networks = append(networks, newNetwork)
}
Expand All @@ -422,9 +479,9 @@ func convertToNetworkStruct(envelope []Envelope) ([]VmNetwork, error) {

func convertToDiskStruct(envelope []Envelope, ovaPath []string) ([]VmDisk, error) {
var disks []VmDisk
for i := 0; i < len(envelope); i++ {
ova := envelope[i]
for _, disk := range ova.DiskSection.Disks {
for i, ova := range envelope {
for j, disk := range ova.DiskSection.Disks {
name := ova.References.File[j].Href
newDisk := VmDisk{
FilePath: getDiskPath(ovaPath[i]),
Capacity: disk.Capacity,
Expand All @@ -433,8 +490,9 @@ func convertToDiskStruct(envelope []Envelope, ovaPath []string) ([]VmDisk, error
FileRef: disk.FileRef,
Format: disk.Format,
PopulatedSize: disk.PopulatedSize,
Name: name,
}

newDisk.ID = diskIDMap.GetUUID(newDisk, ovaPath[i]+"/"+name)
disks = append(disks, newDisk)
}
}
Expand All @@ -453,3 +511,37 @@ func getDiskPath(path string) string {
}
return path
}

type UUIDMap struct {
m map[string]string
}

func NewUUIDMap() *UUIDMap {
return &UUIDMap{
m: make(map[string]string),
}
}

func (um *UUIDMap) GetUUID(object interface{}, key string) string {
var id string
id, ok := um.m[key]

if !ok {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)

if err := enc.Encode(object); err != nil {
log.Fatal(err)
}

hash := sha256.Sum256(buf.Bytes())
um.m[key] = hex.EncodeToString(hash[:])
id = um.m[key]
}
return id
}

func isValidUUID(id string) bool {
_, err := uuid.Parse(id)
return err == nil
}
1 change: 1 addition & 0 deletions hack/virt-v2v-cold-rpm-deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ bazel run \

# These are the packages we really depend on.
virt_v2v="
tar
virt-v2v
virtio-win
"
Expand Down
2 changes: 2 additions & 0 deletions pkg/apis/forklift/v1beta1/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ func (p *Plan) VSphereUsesEl9VirtV2v() (bool, error) {
switch source.Type() {
case VSphere:
return !p.Spec.Warm && destination.IsHost(), nil
case Ova:
return true, nil
default:
return false, nil
}
Expand Down
1 change: 1 addition & 0 deletions pkg/controller/map/network/handler/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ go_library(
"//pkg/apis/forklift/v1beta1",
"//pkg/controller/map/network/handler/ocp",
"//pkg/controller/map/network/handler/openstack",
"//pkg/controller/map/network/handler/ova",
"//pkg/controller/map/network/handler/ovirt",
"//pkg/controller/map/network/handler/vsphere",
"//pkg/controller/watch/handler",
Expand Down
6 changes: 6 additions & 0 deletions pkg/controller/map/network/handler/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
api "github.com/konveyor/forklift-controller/pkg/apis/forklift/v1beta1"
"github.com/konveyor/forklift-controller/pkg/controller/map/network/handler/ocp"
"github.com/konveyor/forklift-controller/pkg/controller/map/network/handler/openstack"
"github.com/konveyor/forklift-controller/pkg/controller/map/network/handler/ova"
"github.com/konveyor/forklift-controller/pkg/controller/map/network/handler/ovirt"
"github.com/konveyor/forklift-controller/pkg/controller/map/network/handler/vsphere"
"github.com/konveyor/forklift-controller/pkg/controller/watch/handler"
Expand Down Expand Up @@ -47,6 +48,11 @@ func New(
client,
channel,
provider)
case api.Ova:
h, err = ova.New(
client,
channel,
provider)
default:
err = liberr.New("provider not supported.")
}
Expand Down
22 changes: 22 additions & 0 deletions pkg/controller/map/network/handler/ova/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")

go_library(
name = "ova",
srcs = [
"doc.go",
"handler.go",
],
importpath = "github.com/konveyor/forklift-controller/pkg/controller/map/network/handler/ova",
visibility = ["//visibility:public"],
deps = [
"//pkg/apis/forklift/v1beta1",
"//pkg/controller/provider/web/ova",
"//pkg/controller/watch/handler",
"//pkg/lib/error",
"//pkg/lib/inventory/web",
"//pkg/lib/logging",
"//vendor/golang.org/x/net/context",
"//vendor/sigs.k8s.io/controller-runtime/pkg/client",
"//vendor/sigs.k8s.io/controller-runtime/pkg/event",
],
)
22 changes: 22 additions & 0 deletions pkg/controller/map/network/handler/ova/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package ova

import (
api "github.com/konveyor/forklift-controller/pkg/apis/forklift/v1beta1"
"github.com/konveyor/forklift-controller/pkg/controller/watch/handler"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
)

// Handler factory.
func New(
client client.Client,
channel chan event.GenericEvent,
provider *api.Provider) (h *Handler, err error) {
//
b, err := handler.New(client, channel, provider)
if err != nil {
return
}
h = &Handler{Handler: b}
return
}
Loading

0 comments on commit c33a65b

Please sign in to comment.