...

Source file src/github.com/Microsoft/hcsshim/internal/vm/remotevm/builder.go

Documentation: github.com/Microsoft/hcsshim/internal/vm/remotevm

     1  //go:build windows
     2  
     3  package remotevm
     4  
     5  import (
     6  	"context"
     7  	"io"
     8  	"net"
     9  	"os/exec"
    10  
    11  	"github.com/Microsoft/hcsshim/internal/jobobject"
    12  	"github.com/Microsoft/hcsshim/internal/log"
    13  	"github.com/Microsoft/hcsshim/internal/vm"
    14  	"github.com/Microsoft/hcsshim/internal/vmservice"
    15  	"github.com/containerd/ttrpc"
    16  	ptypes "github.com/gogo/protobuf/types"
    17  	"github.com/pkg/errors"
    18  	"github.com/sirupsen/logrus"
    19  )
    20  
    21  var _ vm.UVMBuilder = &utilityVMBuilder{}
    22  
    23  type utilityVMBuilder struct {
    24  	id      string
    25  	guestOS vm.GuestOS
    26  	job     *jobobject.JobObject
    27  	config  *vmservice.VMConfig
    28  	client  vmservice.VMService
    29  }
    30  
    31  func NewUVMBuilder(ctx context.Context, id, owner, binPath, addr string, guestOS vm.GuestOS) (vm.UVMBuilder, error) {
    32  	var job *jobobject.JobObject
    33  	if binPath != "" {
    34  		log.G(ctx).WithFields(logrus.Fields{
    35  			"binary":  binPath,
    36  			"address": addr,
    37  		}).Debug("starting remotevm server process")
    38  
    39  		opts := &jobobject.Options{
    40  			Name: id,
    41  		}
    42  		job, err := jobobject.Create(ctx, opts)
    43  		if err != nil {
    44  			return nil, errors.Wrap(err, "failed to create job object for remotevm process")
    45  		}
    46  
    47  		cmd := exec.Command(binPath, "--ttrpc", addr)
    48  		p, err := cmd.StdoutPipe()
    49  		if err != nil {
    50  			return nil, errors.Wrap(err, "failed to create stdout pipe")
    51  		}
    52  
    53  		if err := cmd.Start(); err != nil {
    54  			return nil, errors.Wrap(err, "failed to start remotevm server process")
    55  		}
    56  
    57  		if err := job.Assign(uint32(cmd.Process.Pid)); err != nil {
    58  			return nil, errors.Wrap(err, "failed to assign remotevm process to job")
    59  		}
    60  
    61  		if err := job.SetTerminateOnLastHandleClose(); err != nil {
    62  			return nil, errors.Wrap(err, "failed to set terminate on last handle closed for remotevm job object")
    63  		}
    64  
    65  		// Wait for stdout to close. This is our signal that the server is successfully up and running.
    66  		_, _ = io.Copy(io.Discard, p)
    67  	}
    68  
    69  	conn, err := net.Dial("unix", addr)
    70  	if err != nil {
    71  		return nil, errors.Wrapf(err, "failed to dial remotevm address %q", addr)
    72  	}
    73  
    74  	c := ttrpc.NewClient(conn, ttrpc.WithOnClose(func() { conn.Close() }))
    75  	vmClient := vmservice.NewVMClient(c)
    76  
    77  	return &utilityVMBuilder{
    78  		id:      id,
    79  		guestOS: guestOS,
    80  		config: &vmservice.VMConfig{
    81  			MemoryConfig:    &vmservice.MemoryConfig{},
    82  			DevicesConfig:   &vmservice.DevicesConfig{},
    83  			ProcessorConfig: &vmservice.ProcessorConfig{},
    84  			SerialConfig:    &vmservice.SerialConfig{},
    85  			ExtraData:       make(map[string]string),
    86  		},
    87  		job:    job,
    88  		client: vmClient,
    89  	}, nil
    90  }
    91  
    92  func (uvmb *utilityVMBuilder) Create(ctx context.Context) (vm.UVM, error) {
    93  	// Grab what capabilities the virtstack supports up front.
    94  	capabilities, err := uvmb.client.CapabilitiesVM(ctx, &ptypes.Empty{})
    95  	if err != nil {
    96  		return nil, errors.Wrap(err, "failed to get virtstack capabilities from vmservice")
    97  	}
    98  
    99  	if _, err := uvmb.client.CreateVM(ctx, &vmservice.CreateVMRequest{Config: uvmb.config, LogID: uvmb.id}); err != nil {
   100  		return nil, errors.Wrap(err, "failed to create remote VM")
   101  	}
   102  
   103  	return &utilityVM{
   104  		id:           uvmb.id,
   105  		job:          uvmb.job,
   106  		config:       uvmb.config,
   107  		client:       uvmb.client,
   108  		capabilities: capabilities,
   109  	}, nil
   110  }
   111  

View as plain text