mirror of
https://github.com/aljazceru/kata-containers.git
synced 2026-01-06 16:04:26 +01:00
This is a virtcontainers 1.0.8 import into Kata Containers runtime. virtcontainers is a Go library designed to manage hardware virtualized pods and containers. It is the core Clear Containers framework and will become the core Kata Containers framework, as discussed at https://github.com/kata-containers/runtime/issues/33 Some more more pointers: virtcontainers README, including some design and architecure notes: https://github.com/containers/virtcontainers/blob/master/README.md virtcontainers 1.0 API: https://github.com/containers/virtcontainers/blob/master/documentation/api/1.0/api.md Fixes #40 Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
229 lines
5.0 KiB
Go
229 lines
5.0 KiB
Go
//
|
|
// Copyright (c) 2017 Intel Corporation
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
//
|
|
|
|
package mock
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net"
|
|
"net/url"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
// DefaultMockCCShimBinPath is populated at link time.
|
|
var DefaultMockCCShimBinPath string
|
|
|
|
// DefaultMockKataShimBinPath is populated at link time.
|
|
var DefaultMockKataShimBinPath string
|
|
|
|
// DefaultMockHookBinPath is populated at link time.
|
|
var DefaultMockHookBinPath string
|
|
|
|
// ShimStdoutOutput is the expected output sent by the mock shim on stdout.
|
|
const ShimStdoutOutput = "Some output on stdout"
|
|
|
|
// ShimStderrOutput is the expected output sent by the mock shim on stderr.
|
|
const ShimStderrOutput = "Some output on stderr"
|
|
|
|
// ShimMockConfig is the configuration structure for all virtcontainers shim mock implementations.
|
|
type ShimMockConfig struct {
|
|
Name string
|
|
URLParamName string
|
|
ContainerParamName string
|
|
TokenParamName string
|
|
}
|
|
|
|
// StartShim is a common routine for starting a shim mock.
|
|
func StartShim(config ShimMockConfig) error {
|
|
logDirPath, err := ioutil.TempDir("", config.Name+"-")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
logFilePath := filepath.Join(logDirPath, "mock_"+config.Name+".log")
|
|
|
|
f, err := os.Create(logFilePath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
tokenFlag := flag.String(config.TokenParamName, "", "Container token")
|
|
urlFlag := flag.String(config.URLParamName, "", "Agent URL")
|
|
containerFlag := flag.String(config.ContainerParamName, "", "Container ID")
|
|
|
|
flag.Parse()
|
|
|
|
fmt.Fprintf(f, "INFO: Token = %s\n", *tokenFlag)
|
|
fmt.Fprintf(f, "INFO: URL = %s\n", *urlFlag)
|
|
fmt.Fprintf(f, "INFO: Container = %s\n", *containerFlag)
|
|
|
|
if *tokenFlag == "" {
|
|
err := fmt.Errorf("token should not be empty")
|
|
fmt.Fprintf(f, "%s\n", err)
|
|
return err
|
|
}
|
|
|
|
if *urlFlag == "" {
|
|
err := fmt.Errorf("url should not be empty")
|
|
fmt.Fprintf(f, "%s\n", err)
|
|
return err
|
|
}
|
|
|
|
if _, err := url.Parse(*urlFlag); err != nil {
|
|
err2 := fmt.Errorf("could not parse the URL %q: %s", *urlFlag, err)
|
|
fmt.Fprintf(f, "%s\n", err2)
|
|
return err2
|
|
}
|
|
|
|
if *containerFlag == "" {
|
|
err := fmt.Errorf("container should not be empty")
|
|
fmt.Fprintf(f, "%s\n", err)
|
|
return err
|
|
}
|
|
|
|
// Print some traces to stdout
|
|
fmt.Fprintf(os.Stdout, ShimStdoutOutput)
|
|
os.Stdout.Close()
|
|
|
|
// Print some traces to stderr
|
|
fmt.Fprintf(os.Stderr, ShimStderrOutput)
|
|
os.Stderr.Close()
|
|
|
|
fmt.Fprintf(f, "INFO: Shim exited properly\n")
|
|
|
|
return nil
|
|
}
|
|
|
|
// ProxyMock is the proxy mock interface.
|
|
// It allows for implementing different kind
|
|
// of containers proxies front end.
|
|
type ProxyMock interface {
|
|
Start(URL string) error
|
|
Stop() error
|
|
}
|
|
|
|
// ProxyUnixMock is the UNIX proxy mock
|
|
type ProxyUnixMock struct {
|
|
ClientHandler func(c net.Conn)
|
|
|
|
listener net.Listener
|
|
}
|
|
|
|
// ProxyGRPCMock is the gRPC proxy mock
|
|
type ProxyGRPCMock struct {
|
|
// GRPCImplementer is the structure implementing
|
|
// the GRPC interface we want the proxy to serve.
|
|
GRPCImplementer interface{}
|
|
|
|
// GRPCRegister is the registration routine for
|
|
// the GRPC service.
|
|
GRPCRegister func(s *grpc.Server, srv interface{})
|
|
|
|
listener net.Listener
|
|
}
|
|
|
|
// Start starts the UNIX proxy mock
|
|
func (p *ProxyUnixMock) Start(URL string) error {
|
|
if p.ClientHandler == nil {
|
|
return fmt.Errorf("Missing client handler")
|
|
}
|
|
|
|
url, err := url.Parse(URL)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
l, err := net.Listen(url.Scheme, url.Path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
p.listener = l
|
|
|
|
go func() {
|
|
defer func() {
|
|
l.Close()
|
|
}()
|
|
|
|
for {
|
|
conn, err := l.Accept()
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
go p.ClientHandler(conn)
|
|
}
|
|
}()
|
|
|
|
return nil
|
|
}
|
|
|
|
// Stop stops the UNIX proxy mock
|
|
func (p *ProxyUnixMock) Stop() error {
|
|
if p.listener == nil {
|
|
return fmt.Errorf("Missing proxy listener")
|
|
}
|
|
|
|
return p.listener.Close()
|
|
}
|
|
|
|
// Start starts the gRPC proxy mock
|
|
func (p *ProxyGRPCMock) Start(URL string) error {
|
|
if p.GRPCImplementer == nil {
|
|
return fmt.Errorf("Missing gRPC handler")
|
|
}
|
|
|
|
if p.GRPCRegister == nil {
|
|
return fmt.Errorf("Missing gRPC registration routine")
|
|
}
|
|
|
|
url, err := url.Parse(URL)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
l, err := net.Listen(url.Scheme, url.Path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
p.listener = l
|
|
|
|
grpcServer := grpc.NewServer()
|
|
p.GRPCRegister(grpcServer, p.GRPCImplementer)
|
|
|
|
go func() {
|
|
grpcServer.Serve(l)
|
|
}()
|
|
|
|
return nil
|
|
}
|
|
|
|
// Stop stops the gRPC proxy mock
|
|
func (p *ProxyGRPCMock) Stop() error {
|
|
if p.listener == nil {
|
|
return fmt.Errorf("Missing proxy listener")
|
|
}
|
|
|
|
return p.listener.Close()
|
|
}
|