Skip to content

Commit

Permalink
add new zone capability
Browse files Browse the repository at this point in the history
  • Loading branch information
Hugome committed May 27, 2023
1 parent 772820e commit 215e3e9
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 0 deletions.
98 changes: 98 additions & 0 deletions internal/provider/hypervisor/libvirt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package hypervisor

import (
"fmt"
"net/url"

"github.com/LuxChanLu/csi-libvirt/internal/provider/config"
"github.com/digitalocean/go-libvirt"
"github.com/digitalocean/go-libvirt/socket"
"github.com/digitalocean/go-libvirt/socket/dialers"
"go.uber.org/fx"
"go.uber.org/zap"
)

type Hypervisors struct {
Libvirts []*ZonedHypervisor
Logger *zap.Logger
}

type ZonedHypervisor struct {
*libvirt.Libvirt
Zone string
}

type ZonedDialer struct {
socket.Dialer
Zone string
}

func ProvideLibvirt(lc fx.Lifecycle, log *zap.Logger, dialers []*ZonedDialer, config *config.Config) *Hypervisors {
virts := make([]*ZonedHypervisor, len(dialers))
for idx, dialer := range dialers {
virts[idx] = &ZonedHypervisor{Libvirt: libvirt.NewWithDialer(dialer), Zone: dialer.Zone}
}
lc.Append(fx.StartStopHook(func() error {
for _, virt := range virts {
if err := virt.Connect(); err != nil {
return err
}
version, err := virt.ConnectGetLibVersion()
if err != nil {
return err
}
log.Info("libvirt connected", zap.Uint64("version", version))
}
return nil
}, func() error {
for _, virt := range virts {
if err := virt.Disconnect(); err != nil {
return err
}
}
return nil
}))
return &Hypervisors{Libvirts: virts, Logger: log.With(zap.String("tier", "hypervisor"))}
}

func ProvideLibvirtDialer(log *zap.Logger, config *config.Config) []*ZonedDialer {
buildDialer := func(uri string) *ZonedDialer {
endpoint, err := url.Parse(uri)
if err != nil {
log.Fatal("unable to parse libvirt endpoint", zap.String("endpoint", config.LibvirtEndpoint))
}
var dialer socket.Dialer
switch endpoint.Scheme {
case "tcp":
log.Info("connect to a tcp dialer", zap.String("hostname", endpoint.Hostname()), zap.String("port", endpoint.Port()))
opts := []dialers.RemoteOption{}
if endpoint.Port() != "" {
opts = append(opts, dialers.UsePort(endpoint.Port()))
}
dialer = dialers.NewRemote(endpoint.Hostname(), opts...)
case "unix":
log.Info("connect to a unix dialer", zap.String("endpoint", endpoint.Path))
dialer = dialers.NewLocal(dialers.WithSocket(endpoint.Path))
default:
log.Fatal("unimplemented protocol for libvirt", zap.String("protocol", endpoint.Scheme))
}
return &ZonedDialer{Dialer: dialer}
}
dialers := make([]*ZonedDialer, len(config.Zone.Zones)+1)
dialers[0] = buildDialer(config.LibvirtEndpoint)
for idx, zone := range config.Zone.Zones {
dialers[idx+1] = buildDialer(zone.LibvirtEndpoint)
dialers[idx+1].Zone = zone.Name
}
return dialers
}

func (h *Hypervisors) Zone(zone string) (*libvirt.Libvirt, error) {
for _, zonedLibvirt := range h.Libvirts {
if zonedLibvirt.Zone == zone {
return zonedLibvirt.Libvirt, nil
}
}
h.Logger.Error("unable to get a libvirt instance for a zone", zap.String("zone", zone))
return nil, fmt.Errorf("unable to get libvirt instance for zone %s", zone)
}
23 changes: 23 additions & 0 deletions internal/provider/hypervisor/libvirt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//go:build integration

package hypervisor_test

import (
"testing"

"github.com/LuxChanLu/csi-libvirt/internal/provider"
"github.com/LuxChanLu/csi-libvirt/internal/provider/config"
"github.com/stretchr/testify/assert"
"go.uber.org/fx/fxtest"
"go.uber.org/zap"
)

func TestProvideLibvirt(t *testing.T) {
logger := zap.NewNop()
cfg := config.ProvideConfig(logger)
lc := fxtest.NewLifecycle(t)
libvirt := provider.ProvideLibvirt(lc, logger, cfg)
lc.RequireStart()
defer lc.RequireStop()
assert.NotNil(t, libvirt)
}
19 changes: 19 additions & 0 deletions internal/provider/k8s.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package provider

import (
"go.uber.org/zap"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)

func ProvideK8S(log *zap.Logger) *kubernetes.Clientset {
config, err := rest.InClusterConfig()
if err != nil {
log.Fatal("failed to get in-cluster config", zap.Error(err))
}
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
log.Fatal("failed to create clientset", zap.Error(err))
}
return clientset
}

0 comments on commit 215e3e9

Please sign in to comment.