Skip to content

Commit

Permalink
Change smbios sidecar example to use the shim container.
Browse files Browse the repository at this point in the history
Signed-off-by: Victor Toso <victortoso@redhat.com>
  • Loading branch information
victortoso committed Jul 24, 2023
1 parent b48b561 commit d6950fb
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 119 deletions.
18 changes: 7 additions & 11 deletions cmd/example-hook-sidecar/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,14 @@ go_library(
importpath = "kubevirt.io/kubevirt/cmd/example-hook-sidecar",
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",
"//pkg/virt-launcher/virtwrap/api:go_default_library",
"//staging/src/kubevirt.io/api/core/v1: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 = "example-hook-sidecar",
name = "onDefineDomain",
embed = [":go_default_library"],
visibility = ["//visibility:public"],
)
Expand All @@ -42,9 +36,11 @@ container_image(
"@io_bazel_rules_go//go/platform:linux_arm64": "arm64",
"//conditions:default": "amd64",
}),
base = ":version-container",
directory = "/",
entrypoint = ["/example-hook-sidecar"],
files = [":example-hook-sidecar"],
base = select({
"//conditions:default": "//cmd/sidecars:sidecar-shim-image",
}),
directory = "/usr/bin/",
entrypoint = ["/sidecar-shim"],
files = [":onDefineDomain"],
visibility = ["//visibility:public"],
)
135 changes: 27 additions & 108 deletions cmd/example-hook-sidecar/smbios.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,162 +13,81 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright 2018 Red Hat, Inc.
* Copyright 2018-2023 Red Hat, Inc.
*
*/

package main

import (
"context"
"encoding/json"
"encoding/xml"
"fmt"
"net"
"log"
"os"
"path/filepath"

"github.com/spf13/pflag"
"google.golang.org/grpc"

vmSchema "kubevirt.io/api/core/v1"
"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"
domainSchema "kubevirt.io/kubevirt/pkg/virt-launcher/virtwrap/api"
"kubevirt.io/kubevirt/pkg/virt-launcher/virtwrap/api"
)

const (
baseBoardManufacturerAnnotation = "smbios.vm.kubevirt.io/baseBoardManufacturer"
onDefineDomainLoggingMessage = "Hook's OnDefineDomain callback method has been called"
)

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: "smbios",
Versions: []string{
s.Version,
},
HookPoints: []*hooksInfo.HookPoint{
{
Name: hooksInfo.OnDefineDomainHookPointName,
Priority: 0,
},
},
}, nil
}

type v1alpha1Server struct{}
type v1alpha2Server struct{}

func (s v1alpha2Server) OnDefineDomain(ctx context.Context, params *hooksV1alpha2.OnDefineDomainParams) (*hooksV1alpha2.OnDefineDomainResult, error) {
log.Log.Info(onDefineDomainLoggingMessage)
newDomainXML, err := onDefineDomain(params.GetVmi(), params.GetDomainXML())
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 := onDefineDomain(params.GetVmi(), params.GetDomainXML())
if err != nil {
return nil, err
func onDefineDomain(vmiJSON, domainXML []byte) (string, error) {
vmiSpec := vmSchema.VirtualMachineInstance{}
if err := json.Unmarshal(vmiJSON, &vmiSpec); err != nil {
return "", err
}
return &hooksV1alpha1.OnDefineDomainResult{
DomainXML: newDomainXML,
}, nil
}

func onDefineDomain(vmiJSON []byte, domainXML []byte) ([]byte, error) {
log.Log.Info(onDefineDomainLoggingMessage)

vmiSpec := vmSchema.VirtualMachineInstance{}
err := json.Unmarshal(vmiJSON, &vmiSpec)
if err != nil {
log.Log.Reason(err).Errorf("Failed to unmarshal given VMI spec: %s", vmiJSON)
panic(err)
domainSpec := api.DomainSpec{}
if err := xml.Unmarshal(domainXML, &domainSpec); err != nil {
return "", err
}

annotations := vmiSpec.GetAnnotations()

if _, found := annotations[baseBoardManufacturerAnnotation]; !found {
log.Log.Info("SM BIOS hook sidecar was requested, but no attributes provided. Returning original domain spec")
return domainXML, nil
}

domainSpec := domainSchema.DomainSpec{}
err = xml.Unmarshal(domainXML, &domainSpec)
if err != nil {
log.Log.Reason(err).Errorf("Failed to unmarshal given domain spec: %s", domainXML)
panic(err)
return string(domainXML), nil
}

domainSpec.OS.SMBios = &domainSchema.SMBios{Mode: "sysinfo"}

domainSpec.OS.SMBios = &api.SMBios{Mode: "sysinfo"}
if domainSpec.SysInfo == nil {
domainSpec.SysInfo = &domainSchema.SysInfo{}
domainSpec.SysInfo = &api.SysInfo{}
}
domainSpec.SysInfo.Type = "smbios"
if baseBoardManufacturer, found := annotations[baseBoardManufacturerAnnotation]; found {
domainSpec.SysInfo.BaseBoard = append(domainSpec.SysInfo.BaseBoard, domainSchema.Entry{
domainSpec.SysInfo.BaseBoard = append(domainSpec.SysInfo.BaseBoard, api.Entry{
Name: "manufacturer",
Value: baseBoardManufacturer,
})
}

newDomainXML, err := xml.Marshal(domainSpec)
if err != nil {
log.Log.Reason(err).Errorf("Failed to marshal updated domain spec: %+v", domainSpec)
panic(err)
return "", err
}

log.Log.Info("Successfully updated original domain spec with requested SMBIOS attributes")

return newDomainXML, nil
return string(newDomainXML), nil
}

func main() {
log.InitializeLogging("smbios-hook-sidecar")

var version string
pflag.StringVar(&version, "version", "", "hook version to use")
var vmiJSON, domainXML string
pflag.StringVar(&vmiJSON, "vmi", "", "VMI to change in JSON format")
pflag.StringVar(&domainXML, "domain", "", "Domain spec in XML format")
pflag.Parse()

socketPath := filepath.Join(hooks.HookSocketsSharedDirectory, "smbios.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)
logger := log.New(os.Stderr, "smbios", log.Ldate)
if vmiJSON == "" || domainXML == "" {
logger.Printf("Bad input vmi=%d, domain=%d", len(vmiJSON), len(domainXML))
os.Exit(1)
}
defer os.Remove(socketPath)

server := grpc.NewServer([]grpc.ServerOption{}...)

if version == "" {
panic(fmt.Errorf("usage: \n /example-hook-sidecar --version v1alpha1|v1alpha2"))
domainXML, err := onDefineDomain([]byte(vmiJSON), []byte(domainXML))
if err != nil {
panic(err)
}
hooksInfo.RegisterInfoServer(server, infoServer{Version: version})
hooksV1alpha1.RegisterCallbacksServer(server, v1alpha1Server{})
hooksV1alpha2.RegisterCallbacksServer(server, v1alpha2Server{})
log.Log.Infof("Starting hook server exposing 'info' and 'v1alpha1' services on socket %s", socketPath)
server.Serve(socket)
fmt.Println(domainXML)
}

0 comments on commit d6950fb

Please sign in to comment.