Skip to content

Commit

Permalink
OVA: workaround for virt-v2v firmware detection
Browse files Browse the repository at this point in the history
Signed-off-by: Bella Khizgiyaev <[email protected]>
  • Loading branch information
bkhizgiy committed Mar 5, 2024
1 parent 3dae4f6 commit 14aed36
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 15 deletions.
1 change: 0 additions & 1 deletion pkg/controller/plan/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ go_library(
"//pkg/controller/base",
"//pkg/controller/plan/adapter",
"//pkg/controller/plan/adapter/base",
"//pkg/controller/plan/adapter/ova",
"//pkg/controller/plan/context",
"//pkg/controller/plan/handler",
"//pkg/controller/plan/scheduler",
Expand Down
15 changes: 6 additions & 9 deletions pkg/controller/plan/kubevirt.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import (
"github.com/konveyor/forklift-controller/pkg/apis/forklift/v1beta1/plan"
"github.com/konveyor/forklift-controller/pkg/apis/forklift/v1beta1/ref"
"github.com/konveyor/forklift-controller/pkg/controller/plan/adapter"
ovfparser "github.com/konveyor/forklift-controller/pkg/controller/plan/adapter/ova"
plancontext "github.com/konveyor/forklift-controller/pkg/controller/plan/context"
libcnd "github.com/konveyor/forklift-controller/pkg/lib/condition"
liberr "github.com/konveyor/forklift-controller/pkg/lib/error"
Expand Down Expand Up @@ -860,7 +859,7 @@ func (r *KubeVirt) UpdateVmByConvertedConfig(vm *plan.VMStatus, pod *core.Pod, s
return
}

url := fmt.Sprintf("http://%s:8080/ovf", pod.Status.PodIP)
url := fmt.Sprintf("http://%s:8080/firmware", pod.Status.PodIP)

Check warning on line 862 in pkg/controller/plan/kubevirt.go

View check run for this annotation

Codecov / codecov/patch

pkg/controller/plan/kubevirt.go#L862

Added line #L862 was not covered by tests

/* Due to the virt-v2v operation, the ovf file is only available after the command's execution,
meaning it appears following the copydisks phase.
Expand All @@ -878,17 +877,15 @@ func (r *KubeVirt) UpdateVmByConvertedConfig(vm *plan.VMStatus, pod *core.Pod, s
}
defer resp.Body.Close()

vmConfigXML, err := io.ReadAll(resp.Body)
vmFirmware, err := io.ReadAll(resp.Body)

Check warning on line 880 in pkg/controller/plan/kubevirt.go

View check run for this annotation

Codecov / codecov/patch

pkg/controller/plan/kubevirt.go#L880

Added line #L880 was not covered by tests
if err != nil {
return
}

firmware, err := ovfparser.GetFirmwareFromConfig(string(vmConfigXML))
if err != nil {
return
}

vm.Firmware = firmware
vm.Firmware = string(vmFirmware)
r.Log.Info("Settig the vm fimware",
"vm",
vm.String())

Check warning on line 888 in pkg/controller/plan/kubevirt.go

View check run for this annotation

Codecov / codecov/patch

pkg/controller/plan/kubevirt.go#L885-L888

Added lines #L885 - L888 were not covered by tests

shutdownURL := fmt.Sprintf("http://%s:8080/shutdown", pod.Status.PodIP)
resp, err = http.Post(shutdownURL, "application/json", nil)
Expand Down
54 changes: 49 additions & 5 deletions virt-v2v/cold/entrypoint.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package main

import (
"bufio"
"context"
"fmt"
"io"
"net/http"
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
)

Expand All @@ -20,6 +22,9 @@ const (
VDDK = "/opt/vmware-vix-disklib-distrib"
)

var UEFI_RE = regexp.MustCompile(`(?i)UEFI\s+bootloader?`)
var firmware = "bios"

var (
xmlFilePath string
server *http.Server
Expand Down Expand Up @@ -97,7 +102,7 @@ func main() {
virtV2vArgs = append(virtV2vArgs, "--", os.Getenv("V2V_vmName"))
}

if err := executeVirtV2v(virtV2vArgs); err != nil {
if err := executeVirtV2v(virtV2vArgs, source); err != nil {
fmt.Println("Error executing virt-v2v command ", err)
os.Exit(1)
}
Expand All @@ -111,6 +116,7 @@ func main() {
}

http.HandleFunc("/ovf", ovfHandler)
http.HandleFunc("/firmware", firmwareHandler)
http.HandleFunc("/shutdown", shutdownHandler)
server = &http.Server{Addr: ":8080"}

Expand Down Expand Up @@ -169,16 +175,26 @@ func LinkDisks(diskKind string, num int) (err error) {
return
}

func executeVirtV2v(args []string) (err error) {
func executeVirtV2v(args []string, source string) (err error) {
virtV2vCmd := exec.Command(args[0], args[1:]...)
virtV2vStdoutPipe, err := virtV2vCmd.StdoutPipe()
if err != nil {
fmt.Printf("Error setting up stdout pipe: %v\n", err)
return
}
teeOut := io.TeeReader(virtV2vStdoutPipe, os.Stdout)

tee := io.TeeReader(virtV2vStdoutPipe, os.Stdout)
virtV2vCmd.Stderr = os.Stderr
var teeErr io.Reader
if source == OVA {
virtV2vStderrPipe, err := virtV2vCmd.StderrPipe()
if err != nil {
fmt.Printf("Error setting up stdout pipe: %v\n", err)
return err
}
teeErr = io.TeeReader(virtV2vStderrPipe, os.Stderr)
} else {
virtV2vCmd.Stderr = os.Stderr
}

fmt.Println("exec ", virtV2vCmd)
if err = virtV2vCmd.Start(); err != nil {
Expand All @@ -187,7 +203,7 @@ func executeVirtV2v(args []string) (err error) {
}

virtV2vMonitorCmd := exec.Command("/usr/local/bin/virt-v2v-monitor")
virtV2vMonitorCmd.Stdin = tee
virtV2vMonitorCmd.Stdin = teeOut
virtV2vMonitorCmd.Stdout = os.Stdout
virtV2vMonitorCmd.Stderr = os.Stderr

Expand All @@ -196,6 +212,26 @@ func executeVirtV2v(args []string) (err error) {
return
}

if source == OVA {
scanner := bufio.NewScanner(teeErr)
const maxCapacity = 1024 * 1024
buf := make([]byte, 0, 64*1024)
scanner.Buffer(buf, maxCapacity)

for scanner.Scan() {
line := scanner.Bytes()
if match := UEFI_RE.FindSubmatch(line); match != nil {
fmt.Println("UEFI firmware detected")
firmware = "uefi"
}
}

if err = scanner.Err(); err != nil {
fmt.Println("Output query failed:", err)
return err
}
}

if err = virtV2vCmd.Wait(); err != nil {
fmt.Printf("Error waiting for virt-v2v to finish: %v\n", err)
return
Expand Down Expand Up @@ -236,7 +272,15 @@ func ovfHandler(w http.ResponseWriter, r *http.Request) {
fmt.Printf("Error writing response: %v\n", err)
http.Error(w, "Error writing response", http.StatusInternalServerError)
}
}

func firmwareHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
if _, err := w.Write([]byte(firmware)); err != nil {
fmt.Printf("Error writing response: %v\n", err)
http.Error(w, "Error writing response", http.StatusInternalServerError)
return
}
}

func shutdownHandler(w http.ResponseWriter, r *http.Request) {
Expand Down

0 comments on commit 14aed36

Please sign in to comment.