Skip to content

Commit

Permalink
cgo libvirt migrate to pure go libvirt
Browse files Browse the repository at this point in the history
  • Loading branch information
nieyinliang committed Oct 25, 2023
1 parent 589f965 commit 63fc481
Show file tree
Hide file tree
Showing 68 changed files with 35,006 additions and 93 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ require (
github.com/gin-gonic/gin v1.9.0
github.com/google/uuid v1.3.0
github.com/juju/errors v1.0.0
github.com/libvirt/libvirt-go v7.4.0+incompatible
github.com/projectcalico/api v0.0.0-20230222223746-44aa60c2201f
github.com/projectcalico/calico v1.11.0-cni-plugin.0.20230510161715-15d193738928
github.com/projecteru2/core v0.0.0-20230512041401-f4113e25d62c
Expand All @@ -25,6 +24,7 @@ require (
go.etcd.io/etcd/client/v3 v3.5.8
golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53
golang.org/x/sys v0.8.0
golang.org/x/tools v0.8.0
google.golang.org/grpc v1.54.1
k8s.io/apimachinery v0.26.3
)
Expand Down
5 changes: 3 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,6 @@ github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awS
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA=
github.com/leodido/go-urn v1.2.3/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/libvirt/libvirt-go v7.4.0+incompatible h1:crnSLkwPqCdXtg6jib/FxBG/hweAc/3Wxth1AehCXL4=
github.com/libvirt/libvirt-go v7.4.0+incompatible/go.mod h1:34zsnB4iGeOv7Byj6qotuW8Ya4v4Tr43ttjz/F0wjLE=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
Expand Down Expand Up @@ -449,6 +447,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand Down Expand Up @@ -551,6 +550,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y=
golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
2 changes: 1 addition & 1 deletion internal/virt/domain/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func (d *VirtDomain) Shutdown(force bool) error {
}

func (d *VirtDomain) graceShutdown(dom libvirt.Domain) error {
return dom.ShutdownFlags(libvirt.DomainShutdownDefault)
return dom.ShutdownFlags(libvirt.DomainShutdownFlags(libvirt.DomainShutdownDefault))
}

func (d *VirtDomain) forceShutdown(dom libvirt.Domain) error {
Expand Down
2 changes: 1 addition & 1 deletion internal/virt/domain/mocks/Domain.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion internal/virt/guest/mocks/Bot.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

216 changes: 216 additions & 0 deletions pkg/libvirt/console.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
package libvirt

import (
"bytes"
"context"
"io"
"sync"

"github.com/projecteru2/yavirt/pkg/log"
"github.com/projecteru2/yavirt/pkg/utils"
golibvirt "github.com/projecteru2/yavirt/third_party/libvirt"
)

type ConsoleFlags struct {
Force bool
Safe bool
Nonblock bool
}

func (cf *ConsoleFlags) genLibvirtFlags() (flags golibvirt.DomainConsoleFlags) {
if cf.Force {
flags |= golibvirt.DomainConsoleForce
}
if cf.Safe {
flags |= golibvirt.DomainConsoleSafe
}
return
}

func (cf *ConsoleFlags) genStreamFlags() (flags golibvirt.StreamFlags) {

Check failure on line 30 in pkg/libvirt/console.go

View workflow job for this annotation

GitHub Actions / lint

func `(*ConsoleFlags).genStreamFlags` is unused (unused)
if cf.Nonblock {
flags = golibvirt.StreamNonblock
}
return
}

type Console struct {
Stream *Stream
// pty to user
fromQ *utils.BytesQueue
// user to pty
toQ *utils.BytesQueue

quit chan struct{}
once sync.Once
}

func newConsole(s *Stream) *Console {
return &Console{
Stream: s,
fromQ: utils.NewBytesQueue(),
toQ: utils.NewBytesQueue(),
quit: make(chan struct{}),
}
}

func (c *Console) needExit(ctx context.Context) bool {
if ctx == nil {
ctx = context.Background()
}
select {
case <-ctx.Done():
return true
case <-c.quit:
return true
default:
return false
}
}

func (c *Console) From(ctx context.Context, r io.Reader) error {
buf := make([]byte, 64*1024)
for {
if c.needExit(ctx) {
return nil
}
// Read a single byte
n, err := r.Read(buf)
if err != nil {
if err != io.EOF {
log.Errorf("[Console:From] read error: %s", err)
}
return err
}

if n == 0 {
continue
}

bs := buf[:n]
cloneBs := bytes.Clone(bs)
copy(buf, make([]byte, len(buf)))
_, err = c.toQ.Write(cloneBs)
if err != nil {
log.Errorf("[Console:From] write error: %s", err)
return err
}
}
}

func (c *Console) To(ctx context.Context, w io.Writer) error {
buf := make([]byte, 64*1024)
for {
if c.needExit(ctx) {
return nil
}
// pty to user
n, err := c.fromQ.Read(buf)
if err != nil {
if err != io.EOF {
log.Errorf("[Console:To] read error: %s", err)
}
return err
}
if n == 0 {
continue
}
if c.needExit(ctx) {
return nil
}

_, err = w.Write(buf[:n])
if err != nil {
log.Errorf("[Console:To] write error: %s", err)
return err
}
copy(buf, make([]byte, len(buf)))
}
}

func (c *Console) GetInputToPtyReader() io.ReadWriter {
return c.fromQ
}

func (c *Console) GetOutputToUserWriter() io.ReadWriter {
return c.toQ
}

func (c *Console) Close() {
c.once.Do(func() {
defer func() {
close(c.quit)
}()
// c.Stream.EventRemoveCallback() //nolint
c.Stream.Close()
c.fromQ.Close()
c.toQ.Close()
})
}

func sendAll(stream *Stream, bs []byte) error {
for len(bs) > 0 {
// inStream
n, err := stream.Send(bs)
if err != nil {
return err
}
bs = bs[n:]
}
return nil
}

// AddReadWriter For block stream IO
func (c *Console) AddReadWriter() error {

Check failure on line 164 in pkg/libvirt/console.go

View workflow job for this annotation

GitHub Actions / lint

cognitive complexity 31 of func `(*Console).AddReadWriter` is high (> 30) (gocognit)
ctx := context.Background()
go func() {
defer log.Infof("[AddReadWriter] Send goroutine exit")
for {
if c.needExit(ctx) {
return
}
// from user input, send to pty
bs, err := c.toQ.Pop()
if err != nil {
log.Warnf("[AddReadWriter] Got error when write to console toQ queue: %s", err)
return
}
if c.needExit(ctx) {
return
}
err = sendAll(c.Stream, bs)
if err != nil {
log.Warnf("[AddReadWriter] Got error when write to console stream: %s", err)
return
}
}
}()
go func() {
defer log.Infof("[AddReadWriter] Recv goroutine exit")
buf := make([]byte, 100*1024)
for {
if c.needExit(ctx) {
return
}
n, err := c.Stream.Recv(buf)
if err != nil {
log.Warnf("[AddReadWriter] Got error when read from console stream: %s", err)
return
}
if n == 0 {
continue
}
bs := buf[:n]
if c.needExit(ctx) {
return
}
_, err = c.fromQ.Write(bs)
if err != nil {
log.Warnf("[AddReadWriter] Got error when write to console queue: %s", err)
return
}
copy(buf, make([]byte, len(buf)))
}
}()
return nil
}
Loading

0 comments on commit 63fc481

Please sign in to comment.