...

Source file src/github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/main.go

Documentation: github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1

     1  //go:build windows
     2  
     3  package main
     4  
     5  import (
     6  	"context"
     7  	"errors"
     8  	"fmt"
     9  	"os"
    10  	"strings"
    11  	"time"
    12  
    13  	"github.com/Microsoft/go-winio/pkg/etw"
    14  	"github.com/Microsoft/go-winio/pkg/etwlogrus"
    15  	"github.com/Microsoft/go-winio/pkg/guid"
    16  	"github.com/Microsoft/hcsshim/internal/log"
    17  	"github.com/Microsoft/hcsshim/internal/oc"
    18  	"github.com/Microsoft/hcsshim/internal/shimdiag"
    19  	specs "github.com/opencontainers/runtime-spec/specs-go"
    20  	"github.com/sirupsen/logrus"
    21  	"github.com/urfave/cli"
    22  	"go.opencensus.io/trace"
    23  )
    24  
    25  const usage = ``
    26  const ttrpcAddressEnv = "TTRPC_ADDRESS"
    27  
    28  // Add a manifest to get proper Windows version detection.
    29  //go:generate go run github.com/josephspurrier/goversioninfo/cmd/goversioninfo -platform-specific
    30  
    31  // version will be populated by the Makefile, read from
    32  // VERSION file of the source code.
    33  var version = ""
    34  
    35  // gitCommit will be the hash that the binary was built from
    36  // and will be populated by the Makefile
    37  var gitCommit = ""
    38  
    39  var (
    40  	namespaceFlag        string
    41  	addressFlag          string
    42  	containerdBinaryFlag string
    43  
    44  	idFlag string
    45  
    46  	// gracefulShutdownTimeout is how long to wait for clean-up before just exiting
    47  	gracefulShutdownTimeout = 3 * time.Second
    48  )
    49  
    50  func etwCallback(sourceID guid.GUID, state etw.ProviderState, level etw.Level, matchAnyKeyword uint64, matchAllKeyword uint64, filterData uintptr) {
    51  	if state == etw.ProviderStateCaptureState {
    52  		resp, err := svc.DiagStacks(context.Background(), &shimdiag.StacksRequest{})
    53  		if err != nil {
    54  			return
    55  		}
    56  		log := logrus.WithField("tid", svc.tid)
    57  		log.WithField("stack", resp.Stacks).Info("goroutine stack dump")
    58  		if resp.GuestStacks != "" {
    59  			log.WithField("stack", resp.GuestStacks).Info("guest stack dump")
    60  		}
    61  	}
    62  }
    63  
    64  func main() {
    65  	logrus.AddHook(log.NewHook())
    66  
    67  	// Provider ID: 0b52781f-b24d-5685-ddf6-69830ed40ec3
    68  	// Provider and hook aren't closed explicitly, as they will exist until process exit.
    69  	provider, err := etw.NewProvider("Microsoft.Virtualization.RunHCS", etwCallback)
    70  	if err != nil {
    71  		logrus.Error(err)
    72  	} else {
    73  		if hook, err := etwlogrus.NewHookFromProvider(provider); err == nil {
    74  			logrus.AddHook(hook)
    75  		} else {
    76  			logrus.Error(err)
    77  		}
    78  	}
    79  
    80  	_ = provider.WriteEvent(
    81  		"ShimLaunched",
    82  		nil,
    83  		etw.WithFields(
    84  			etw.StringArray("Args", os.Args),
    85  		),
    86  	)
    87  
    88  	// Register our OpenCensus logrus exporter
    89  	trace.ApplyConfig(trace.Config{DefaultSampler: oc.DefaultSampler})
    90  	trace.RegisterExporter(&oc.LogrusExporter{})
    91  
    92  	app := cli.NewApp()
    93  	app.Name = "containerd-shim-runhcs-v1"
    94  	app.Usage = usage
    95  
    96  	var v []string
    97  	if version != "" {
    98  		v = append(v, version)
    99  	}
   100  	if gitCommit != "" {
   101  		v = append(v, fmt.Sprintf("commit: %s", gitCommit))
   102  	}
   103  	v = append(v, fmt.Sprintf("spec: %s", specs.Version))
   104  	app.Version = strings.Join(v, "\n")
   105  
   106  	app.Flags = []cli.Flag{
   107  		cli.StringFlag{
   108  			Name:  "namespace",
   109  			Usage: "the namespace of the container",
   110  		},
   111  		cli.StringFlag{
   112  			Name:  "address",
   113  			Usage: "the address of the containerd's main socket",
   114  		},
   115  		cli.StringFlag{
   116  			Name:  "publish-binary",
   117  			Usage: "the binary path to publish events back to containerd",
   118  		},
   119  		cli.StringFlag{
   120  			Name:  "id",
   121  			Usage: "the id of the container",
   122  		},
   123  		cli.StringFlag{
   124  			Name:  "bundle",
   125  			Usage: "the bundle path to delete (delete command only).",
   126  		},
   127  		cli.BoolFlag{
   128  			Name:  "debug",
   129  			Usage: "run the shim in debug mode",
   130  		},
   131  	}
   132  	app.Commands = []cli.Command{
   133  		startCommand,
   134  		deleteCommand,
   135  		serveCommand,
   136  	}
   137  	app.Before = func(context *cli.Context) error {
   138  		if namespaceFlag = context.GlobalString("namespace"); namespaceFlag == "" {
   139  			return errors.New("namespace is required")
   140  		}
   141  		if addressFlag = context.GlobalString("address"); addressFlag == "" {
   142  			return errors.New("address is required")
   143  		}
   144  		if containerdBinaryFlag = context.GlobalString("publish-binary"); containerdBinaryFlag == "" {
   145  			return errors.New("publish-binary is required")
   146  		}
   147  		if idFlag = context.GlobalString("id"); idFlag == "" {
   148  			return errors.New("id is required")
   149  		}
   150  		return nil
   151  	}
   152  
   153  	if err := app.Run(os.Args); err != nil {
   154  		fmt.Fprintln(cli.ErrWriter, err)
   155  		os.Exit(1)
   156  	}
   157  }
   158  

View as plain text