Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The virt-xml tools is a command line utility for editing libvirt XML. This setup introduces a new hook to integrate virt-xml in KubeVirt. Using virt-xml allows to use a well-maintained tool to try and test unsupported options by the KubeVirt APIs. This feature is supposed to help developers to try and test unsupported options without the need to develop their own sidecar. Signed-off-by: Alice Frosi <afrosi@redhat.com>
- Loading branch information
Showing
10 changed files
with
1,134 additions
and
820 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") | ||
load( | ||
"@io_bazel_rules_docker//container:container.bzl", | ||
"container_image", | ||
) | ||
|
||
container_image( | ||
name = "version-container", | ||
tars = select({ | ||
"//conditions:default": [ | ||
"//rpm:hookxmlbase_x86_64", | ||
], | ||
}), | ||
) | ||
|
||
container_image( | ||
name = "virt-xml-hook-image", | ||
architecture = select({ | ||
"@io_bazel_rules_go//go/platform:linux_arm64": "arm64", | ||
"//conditions:default": "amd64", | ||
}), | ||
base = ":version-container", | ||
directory = "/", | ||
entrypoint = ["/virt-xml-hook"], | ||
files = [":virt-xml-hook"], | ||
visibility = ["//visibility:public"], | ||
) | ||
|
||
go_library( | ||
name = "go_default_library", | ||
srcs = ["virt_xml_hook.go"], | ||
importpath = "kubevirt.io/kubevirt/cmd/virt-xml-hook", | ||
visibility = ["//visibility:private"], | ||
deps = [ | ||
"//pkg/hooks:go_default_library", | ||
"//pkg/hooks/info:go_default_library", | ||
"//pkg/hooks/v1alpha1:go_default_library", | ||
"//pkg/hooks/v1alpha2:go_default_library", | ||
"//staging/src/kubevirt.io/client-go/log:go_default_library", | ||
"//vendor/github.com/spf13/pflag:go_default_library", | ||
"@org_golang_google_grpc//:go_default_library", | ||
], | ||
) | ||
|
||
go_binary( | ||
name = "virt-xml-hook", | ||
embed = [":go_default_library"], | ||
visibility = ["//visibility:public"], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"fmt" | ||
"net" | ||
"os" | ||
"os/exec" | ||
"strings" | ||
|
||
"github.com/spf13/pflag" | ||
"google.golang.org/grpc" | ||
|
||
"kubevirt.io/client-go/log" | ||
"kubevirt.io/kubevirt/pkg/hooks" | ||
hooksInfo "kubevirt.io/kubevirt/pkg/hooks/info" | ||
hooksV1alpha1 "kubevirt.io/kubevirt/pkg/hooks/v1alpha1" | ||
hooksV1alpha2 "kubevirt.io/kubevirt/pkg/hooks/v1alpha2" | ||
) | ||
|
||
const ( | ||
onDefineDomainLoggingMessage = "Hook's OnDefineDomain callback method has been called" | ||
usage = `updater | ||
--version v1alpha1|v1alpha2 | ||
--args ''` | ||
) | ||
|
||
type infoServer struct { | ||
Version string | ||
} | ||
|
||
func (s infoServer) Info(ctx context.Context, params *hooksInfo.InfoParams) (*hooksInfo.InfoResult, error) { | ||
log.Log.Info("Hook's Info method has been called") | ||
|
||
return &hooksInfo.InfoResult{ | ||
Name: "update-xml", | ||
Versions: []string{ | ||
s.Version, | ||
}, | ||
HookPoints: []*hooksInfo.HookPoint{ | ||
{ | ||
Name: hooksInfo.OnDefineDomainHookPointName, | ||
Priority: 0, | ||
}, | ||
}, | ||
}, nil | ||
} | ||
|
||
const virtXML = "virt-xml" | ||
|
||
type v1alpha1Server struct { | ||
args []string | ||
} | ||
|
||
type v1alpha2Server struct { | ||
args []string | ||
} | ||
|
||
func MergeKubeVirtXMLWithProvidedXML(domainXML []byte, args []string) ([]byte, error) { | ||
args = append(args, "--edit") | ||
args = append(args, "--print-xml") | ||
cmd := exec.Command(virtXML, args...) | ||
cmd.Stdin = strings.NewReader(string(domainXML)) | ||
var stderr bytes.Buffer | ||
cmd.Stderr = &stderr | ||
log.Log.Infof("Execute command: %s", cmd.String()) | ||
out, err := cmd.Output() | ||
if err != nil { | ||
log.Log.Errorf("Fail running command stdout:%s stderr: %s error:%v", out, stderr.String(), err) | ||
return []byte{}, err | ||
} | ||
|
||
return []byte(out), nil | ||
} | ||
|
||
func (s v1alpha2Server) OnDefineDomain(ctx context.Context, params *hooksV1alpha2.OnDefineDomainParams) (*hooksV1alpha2.OnDefineDomainResult, error) { | ||
log.Log.Info(onDefineDomainLoggingMessage) | ||
newDomainXML, err := MergeKubeVirtXMLWithProvidedXML(params.GetDomainXML(), s.args) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &hooksV1alpha2.OnDefineDomainResult{ | ||
DomainXML: newDomainXML, | ||
}, nil | ||
} | ||
func (s v1alpha2Server) PreCloudInitIso(_ context.Context, params *hooksV1alpha2.PreCloudInitIsoParams) (*hooksV1alpha2.PreCloudInitIsoResult, error) { | ||
return &hooksV1alpha2.PreCloudInitIsoResult{ | ||
CloudInitData: params.GetCloudInitData(), | ||
}, nil | ||
} | ||
|
||
func (s v1alpha1Server) OnDefineDomain(ctx context.Context, params *hooksV1alpha1.OnDefineDomainParams) (*hooksV1alpha1.OnDefineDomainResult, error) { | ||
log.Log.Info(onDefineDomainLoggingMessage) | ||
newDomainXML, err := MergeKubeVirtXMLWithProvidedXML(params.GetVmi(), s.args) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &hooksV1alpha1.OnDefineDomainResult{ | ||
DomainXML: newDomainXML, | ||
}, nil | ||
} | ||
|
||
func main() { | ||
log.InitializeLogging("xml update") | ||
|
||
var version string | ||
pflag.StringVar(&version, "version", "", "hook version to use") | ||
|
||
var options string | ||
pflag.StringVar(&options, "args", "", "params to pass to virt-xml") | ||
pflag.Parse() | ||
|
||
args := strings.Split(options, "|") | ||
|
||
socketPath := hooks.HookSocketsSharedDirectory + "/update.sock" | ||
socket, err := net.Listen("unix", socketPath) | ||
if err != nil { | ||
log.Log.Reason(err).Errorf("Failed to initialized socket on path: %s", socket) | ||
log.Log.Error("Check whether given directory exists and socket name is not already taken by other file") | ||
panic(err) | ||
} | ||
defer os.Remove(socketPath) | ||
|
||
server := grpc.NewServer([]grpc.ServerOption{}...) | ||
|
||
if version == "" { | ||
panic(fmt.Errorf(usage)) | ||
} | ||
if options == "" { | ||
panic(fmt.Errorf(usage)) | ||
} | ||
|
||
hooksInfo.RegisterInfoServer(server, infoServer{Version: version}) | ||
hooksV1alpha1.RegisterCallbacksServer(server, v1alpha1Server{args: args}) | ||
hooksV1alpha2.RegisterCallbacksServer(server, v1alpha2Server{args: args}) | ||
log.Log.Infof("Starting hook server exposing 'info' and 'v1alpha1' services on socket %s", socketPath) | ||
server.Serve(socket) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
--- | ||
apiVersion: kubevirt.io/v1 | ||
kind: VirtualMachineInstance | ||
metadata: | ||
annotations: | ||
hooks.kubevirt.io/hookSidecars: '[{"args": ["--version", "v1alpha2", "--args", "--disk=iotune.total_bytes_sec=52428800,iotune.total_iops_sec=1000|--edit=all"], "image":"registry:5000/kubevirt/virt-xml-hook:devel", "imagePullPolicy": "Always"}]' | ||
labels: | ||
special: vmi-with-virt-xml | ||
name: vmi-with-virt-xml | ||
spec: | ||
domain: | ||
devices: | ||
disks: | ||
- disk: | ||
bus: virtio | ||
name: containerdisk | ||
- disk: | ||
bus: virtio | ||
name: cloudinitdisk | ||
rng: {} | ||
resources: | ||
requests: | ||
memory: 1024M | ||
terminationGracePeriodSeconds: 0 | ||
volumes: | ||
- containerDisk: | ||
image: registry:5000/kubevirt/fedora-with-test-tooling-container-disk:devel | ||
name: containerdisk | ||
- cloudInitNoCloud: | ||
userData: |- | ||
#cloud-config | ||
password: fedora | ||
chpasswd: { expire: False } | ||
name: cloudinitdisk |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.