Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
VMCache: Update factory to run as a VMCache server
Browse files Browse the repository at this point in the history
When VMCache is enabled, factory init will run as a VMcache server.

Fixes: #52

Signed-off-by: Hui Zhu <[email protected]>
  • Loading branch information
teawater committed Mar 1, 2019
1 parent 616da3e commit d4ad0f2
Showing 1 changed file with 134 additions and 1 deletion.
135 changes: 134 additions & 1 deletion cli/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,23 @@
package main

import (
"errors"
"context"
"fmt"
"net"
"os"
"os/signal"
"path/filepath"
"syscall"

"github.com/gogo/protobuf/types"
pb "github.com/kata-containers/runtime/protocols/cache"
vc "github.com/kata-containers/runtime/virtcontainers"
vf "github.com/kata-containers/runtime/virtcontainers/factory"
"github.com/kata-containers/runtime/virtcontainers/pkg/oci"
"github.com/pkg/errors"
"github.com/urfave/cli"
"golang.org/x/sys/unix"
"google.golang.org/grpc"
)

var factorySubCmds = []cli.Command{
Expand All @@ -30,6 +40,84 @@ var factoryCLICommand = cli.Command{
},
}

type cacheServer struct {
rpc *grpc.Server
factory vc.Factory
}

var jsonVMConfig *pb.GrpcVMConfig

// Config requests base factory config and convert it to gRPC protocol.
func (s *cacheServer) Config(ctx context.Context, empty *types.Empty) (*pb.GrpcVMConfig, error) {
if jsonVMConfig == nil {
config := s.factory.Config()

var err error
jsonVMConfig, err = config.ToGrpc()
if err != nil {
return nil, err
}
}

return jsonVMConfig, nil
}

// GetBaseVM requests a paused VM and convert it to gRPC protocol.
func (s *cacheServer) GetBaseVM(ctx context.Context, empty *types.Empty) (*pb.GrpcVM, error) {
config := s.factory.Config()

vm, err := s.factory.GetBaseVM(ctx, config)
if err != nil {
return nil, errors.Wrapf(err, "failed to GetBaseVM")
}

return vm.ToGrpc(config)
}

func getUnixListener(path string) (net.Listener, error) {
err := os.MkdirAll(filepath.Dir(path), 0755)
if err != nil {
return nil, err
}
if err = unix.Unlink(path); err != nil && !os.IsNotExist(err) {
return nil, err
}
l, err := net.Listen("unix", path)
if err != nil {
return nil, err
}
if err = os.Chmod(path, 0600); err != nil {
l.Close()
return nil, err
}
return l, nil
}

var handledSignals = []os.Signal{
syscall.SIGTERM,
syscall.SIGINT,
syscall.SIGPIPE,
}

func handleSignals(s *cacheServer, signals chan os.Signal) chan struct{} {
done := make(chan struct{}, 1)
go func() {
for {
sig := <-signals
kataLog.WithField("signal", sig).Debug("received signal")
switch sig {
case unix.SIGPIPE:
continue
default:
s.rpc.GracefulStop()
close(done)
return
}
}
}()
return done
}

var initFactoryCommand = cli.Command{
Name: "init",
Usage: "initialize a VM factory based on kata-runtime configuration",
Expand All @@ -44,6 +132,51 @@ var initFactoryCommand = cli.Command{
return errors.New("invalid runtime config")
}

if runtimeConfig.FactoryConfig.VMCacheNumber > 0 {
factoryConfig := vf.Config{
Template: runtimeConfig.FactoryConfig.Template,
Cache: runtimeConfig.FactoryConfig.VMCacheNumber,
VMCache: true,
VMConfig: vc.VMConfig{
HypervisorType: runtimeConfig.HypervisorType,
HypervisorConfig: runtimeConfig.HypervisorConfig,
AgentType: runtimeConfig.AgentType,
AgentConfig: runtimeConfig.AgentConfig,
ProxyType: runtimeConfig.ProxyType,
ProxyConfig: runtimeConfig.ProxyConfig,
},
}
f, err := vf.NewFactory(ctx, factoryConfig, false)
if err != nil {
return err
}
defer f.CloseFactory(ctx)

s := &cacheServer{
rpc: grpc.NewServer(),
factory: f,
}
pb.RegisterCacheServiceServer(s.rpc, s)

l, err := getUnixListener(runtimeConfig.FactoryConfig.VMCacheEndpoint)
if err != nil {
return err
}
defer l.Close()

signals := make(chan os.Signal, 8)
done := handleSignals(s, signals)
signal.Notify(signals, handledSignals...)

kataLog.WithField("endpoint", runtimeConfig.FactoryConfig.VMCacheEndpoint).Info("VM cache server start")
s.rpc.Serve(l)

<-done

kataLog.WithField("endpoint", runtimeConfig.FactoryConfig.VMCacheEndpoint).Info("VM cache server stop")
return nil
}

if runtimeConfig.FactoryConfig.Template {
factoryConfig := vf.Config{
Template: true,
Expand Down

0 comments on commit d4ad0f2

Please sign in to comment.