...

Source file src/github.com/Microsoft/hcsshim/internal/guest/runtime/hcsv2/sandbox_container.go

Documentation: github.com/Microsoft/hcsshim/internal/guest/runtime/hcsv2

     1  //go:build linux
     2  // +build linux
     3  
     4  package hcsv2
     5  
     6  import (
     7  	"context"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  
    12  	oci "github.com/opencontainers/runtime-spec/specs-go"
    13  	"github.com/pkg/errors"
    14  	"go.opencensus.io/trace"
    15  
    16  	"github.com/Microsoft/hcsshim/internal/guest/network"
    17  	specInternal "github.com/Microsoft/hcsshim/internal/guest/spec"
    18  	"github.com/Microsoft/hcsshim/internal/oc"
    19  	"github.com/Microsoft/hcsshim/pkg/annotations"
    20  )
    21  
    22  func getSandboxHostnamePath(id string) string {
    23  	return filepath.Join(specInternal.SandboxRootDir(id), "hostname")
    24  }
    25  
    26  func getSandboxHostsPath(id string) string {
    27  	return filepath.Join(specInternal.SandboxRootDir(id), "hosts")
    28  }
    29  
    30  func getSandboxResolvPath(id string) string {
    31  	return filepath.Join(specInternal.SandboxRootDir(id), "resolv.conf")
    32  }
    33  
    34  func setupSandboxContainerSpec(ctx context.Context, id string, spec *oci.Spec) (err error) {
    35  	ctx, span := oc.StartSpan(ctx, "hcsv2::setupSandboxContainerSpec")
    36  	defer span.End()
    37  	defer func() { oc.SetSpanStatus(span, err) }()
    38  	span.AddAttributes(trace.StringAttribute("cid", id))
    39  
    40  	// Generate the sandbox root dir
    41  	rootDir := specInternal.SandboxRootDir(id)
    42  	if err := os.MkdirAll(rootDir, 0755); err != nil {
    43  		return errors.Wrapf(err, "failed to create sandbox root directory %q", rootDir)
    44  	}
    45  	defer func() {
    46  		if err != nil {
    47  			_ = os.RemoveAll(rootDir)
    48  		}
    49  	}()
    50  
    51  	// Write the hostname
    52  	hostname := spec.Hostname
    53  	if hostname == "" {
    54  		var err error
    55  		hostname, err = os.Hostname()
    56  		if err != nil {
    57  			return errors.Wrap(err, "failed to get hostname")
    58  		}
    59  	}
    60  
    61  	sandboxHostnamePath := getSandboxHostnamePath(id)
    62  	if err := os.WriteFile(sandboxHostnamePath, []byte(hostname+"\n"), 0644); err != nil {
    63  		return errors.Wrapf(err, "failed to write hostname to %q", sandboxHostnamePath)
    64  	}
    65  
    66  	// Write the hosts
    67  	sandboxHostsContent := network.GenerateEtcHostsContent(ctx, hostname)
    68  	sandboxHostsPath := getSandboxHostsPath(id)
    69  	if err := os.WriteFile(sandboxHostsPath, []byte(sandboxHostsContent), 0644); err != nil {
    70  		return errors.Wrapf(err, "failed to write sandbox hosts to %q", sandboxHostsPath)
    71  	}
    72  
    73  	// Write resolv.conf
    74  	ns, err := getNetworkNamespace(getNetworkNamespaceID(spec))
    75  	if err != nil {
    76  		return err
    77  	}
    78  	var searches, servers []string
    79  	for _, n := range ns.Adapters() {
    80  		if len(n.DNSSuffix) > 0 {
    81  			searches = network.MergeValues(searches, strings.Split(n.DNSSuffix, ","))
    82  		}
    83  		if len(n.DNSServerList) > 0 {
    84  			servers = network.MergeValues(servers, strings.Split(n.DNSServerList, ","))
    85  		}
    86  	}
    87  	resolvContent, err := network.GenerateResolvConfContent(ctx, searches, servers, nil)
    88  	if err != nil {
    89  		return errors.Wrap(err, "failed to generate sandbox resolv.conf content")
    90  	}
    91  	sandboxResolvPath := getSandboxResolvPath(id)
    92  	if err := os.WriteFile(sandboxResolvPath, []byte(resolvContent), 0644); err != nil {
    93  		return errors.Wrap(err, "failed to write sandbox resolv.conf")
    94  	}
    95  
    96  	// User.Username is generally only used on Windows, but as there's no (easy/fast at least) way to grab
    97  	// a uid:gid pairing for a username string on the host, we need to defer this work until we're here in the
    98  	// guest. The username field is used as a temporary holding place until we can perform this work here when
    99  	// we actually have the rootfs to inspect.
   100  	if spec.Process.User.Username != "" {
   101  		if err := setUserStr(spec, spec.Process.User.Username); err != nil {
   102  			return err
   103  		}
   104  	}
   105  
   106  	if rlimCore := spec.Annotations[annotations.RLimitCore]; rlimCore != "" {
   107  		if err := setCoreRLimit(spec, rlimCore); err != nil {
   108  			return err
   109  		}
   110  	}
   111  
   112  	// TODO: JTERRY75 /dev/shm is not properly setup for LCOW I believe. CRI
   113  	// also has a concept of a sandbox/shm file when the IPC NamespaceMode !=
   114  	// NODE.
   115  
   116  	// Force the parent cgroup into our /containers root
   117  	spec.Linux.CgroupsPath = "/containers/" + id
   118  
   119  	// Clear the windows section as we dont want to forward to runc
   120  	spec.Windows = nil
   121  
   122  	return nil
   123  }
   124  

View as plain text