Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix OVA generation #102

Merged
merged 1 commit into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions data/AgentVM.ovf → data/MigrationAssessment.ovf
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<?xml version='1.0' encoding='UTF-8'?>
<Envelope xmlns="http://schemas.dmtf.org/ovf/envelope/1" xmlns:ovf="http://schemas.dmtf.org/ovf/envelope/1" xmlns:vmw="http://www.vmware.com/schema/ovf" xmlns:rasd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData" xmlns:vssd="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData">
<References>
<File ovf:id="file1" ovf:href="AgentVM-1.iso" ovf:size="1220542464"/>
<File ovf:id="file1" ovf:href="MigrationAssessment.iso" ovf:size="1220542464"/>
</References>
<NetworkSection>
<Info>The list of logical networks</Info>
<Network ovf:name="routable-network">
<Description>Routable network</Description>
</Network>
</NetworkSection>
<VirtualSystem ovf:id="AgentVM">
<VirtualSystem ovf:id="MigrationAssessment">
<Info>A Virtual system</Info>
<Name>MigrationAssessment</Name>
<OperatingSystemSection ovf:id="80" ovf:version="8" vmw:osType="rhel9_64Guest">
Expand Down
69 changes: 65 additions & 4 deletions internal/image/ova.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,31 @@ func (o *Ova) Validate() error {
return nil
}

func calculateTarSize(contentSize int) int {
const blockSize = 512

// Size of the tar header block
size := blockSize

// Size of the file content, rounded up to nearest 512 bytes
size += ((contentSize + blockSize - 1) / blockSize) * blockSize

return size
}

func (o *Ova) OvaSize() (int, error) {
isoSize, err := o.isoSize()
if err != nil {
return -1, err
}
ovfSize, err := o.ovfSize()
if err != nil {
return -1, err
}

return ovfSize + isoSize, nil
}

func (o *Ova) Generate() error {
tw := tar.NewWriter(o.Writer)

Expand All @@ -64,6 +89,8 @@ func (o *Ova) Generate() error {
return err
}

tw.Flush()

return nil
}

Expand All @@ -88,13 +115,13 @@ func (o *Ova) writeIso(tw *tar.Writer) error {
if err != nil {
return err
}
// Create a header for AgentVM-1.iso
// Create a header for MigrationAssessment.iso
length, err := reader.Seek(0, io.SeekEnd)
if err != nil {
return err
}
header := &tar.Header{
Name: "AgentVM-1.iso",
Name: "MigrationAssessment.iso",
Size: length,
Mode: 0600,
ModTime: time.Now(),
Expand All @@ -118,14 +145,48 @@ func (o *Ova) writeIso(tw *tar.Writer) error {
return nil
}

func (o *Ova) isoSize() (int, error) {
// Get ISO reader
reader, err := o.isoReader()
if err != nil {
return -1, err
}
length, err := reader.Seek(0, io.SeekEnd)
if err != nil {
return -1, err
}

// Reset the reader to start
_, err = reader.Seek(0, io.SeekStart)
if err != nil {
return -1, err
}

return calculateTarSize(int(length)), nil
}

func (o *Ova) ovfSize() (int, error) {
file, err := os.Open("data/MigrationAssessment.ovf")
if err != nil {
return -1, err
}
defer file.Close()
fileInfo, err := file.Stat()
if err != nil {
return -1, err
}

return calculateTarSize(int(fileInfo.Size())), nil
}

func writeOvf(tw *tar.Writer) error {
ovfContent, err := os.ReadFile("data/AgentVM.ovf")
ovfContent, err := os.ReadFile("data/MigrationAssessment.ovf")
if err != nil {
return err
}
// Create a header for AgentVM.ovf
header := &tar.Header{
Name: "AgentVM.ovf",
Name: "MigrationAssessment.ovf",
Size: int64(len(ovfContent)),
Mode: 0600,
ModTime: time.Now(),
Expand Down
15 changes: 14 additions & 1 deletion internal/service/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"fmt"
"net/http"
"strconv"

"github.com/kubev2v/migration-planner/internal/api/server"
"github.com/kubev2v/migration-planner/internal/auth"
Expand All @@ -16,12 +17,24 @@ func (h *ServiceHandler) GetImage(ctx context.Context, request server.GetImageRe
if !ok {
return server.GetImage500JSONResponse{Message: "error creating the HTTP stream"}, nil
}

ova := &image.Ova{SshKey: request.Params.SshKey, Writer: writer}

// get token if any
if user, found := auth.UserFromContext(ctx); found {
ova.Jwt = user.Token
}

// Calculate the size of the OVA, so the download show estimated time:
size, err := ova.OvaSize()
if err != nil {
return server.GetImage500JSONResponse{Message: "error creating the HTTP stream"}, nil
}

// Set proper headers of the OVA file:
writer.Header().Set("Content-Type", "application/ovf")
writer.Header().Set("Content-Length", strconv.Itoa(size))

// Generate the OVA image
if err := ova.Generate(); err != nil {
return server.GetImage500JSONResponse{Message: fmt.Sprintf("error generating image %s", err)}, nil
}
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/e2e_agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (p *plannerAgentLibvirt) prepareImage() error {
}

// Untar ISO from OVA
if err = Untar(file, defaultIsoPath, "AgentVM-1.iso"); err != nil {
if err = Untar(file, defaultIsoPath, "MigrationAssessment.iso"); err != nil {
return fmt.Errorf("error uncompressing the file: %w", err)
}

Expand Down
Loading