...

Source file src/github.com/Microsoft/hcsshim/internal/tools/uvmboot/mounts.go

Documentation: github.com/Microsoft/hcsshim/internal/tools/uvmboot

     1  //go:build windows
     2  
     3  package main
     4  
     5  import (
     6  	"context"
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/Microsoft/hcsshim/internal/uvm"
    11  	"github.com/sirupsen/logrus"
    12  	"github.com/urfave/cli"
    13  )
    14  
    15  func mountSCSI(ctx context.Context, c *cli.Context, vm *uvm.UtilityVM) error {
    16  	for _, m := range parseMounts(c, scsiMountsArgName) {
    17  		if _, err := vm.AddSCSI(
    18  			ctx,
    19  			m.host,
    20  			m.guest,
    21  			!m.writable,
    22  			false, // encrypted
    23  			[]string{},
    24  			uvm.VMAccessTypeIndividual,
    25  		); err != nil {
    26  			return fmt.Errorf("could not mount disk %s: %w", m.host, err)
    27  		} else {
    28  			logrus.WithFields(logrus.Fields{
    29  				"host":     m.host,
    30  				"guest":    m.guest,
    31  				"writable": m.writable,
    32  			}).Debug("Mounted SCSI disk")
    33  		}
    34  	}
    35  
    36  	return nil
    37  }
    38  
    39  func shareFiles(ctx context.Context, c *cli.Context, vm *uvm.UtilityVM) error {
    40  	switch os := vm.OS(); os {
    41  	case "linux":
    42  		return shareFilesLCOW(ctx, c, vm)
    43  	default:
    44  		return fmt.Errorf("file shares are not supported for %s UVMs", os)
    45  	}
    46  }
    47  
    48  func shareFilesLCOW(ctx context.Context, c *cli.Context, vm *uvm.UtilityVM) error {
    49  	for _, s := range parseMounts(c, shareFilesArgName) {
    50  		if s.guest == "" {
    51  			return fmt.Errorf("file shares %q has invalid quest destination: %q", s.host, s.guest)
    52  		}
    53  
    54  		if err := vm.Share(ctx, s.host, s.guest, !s.writable); err != nil {
    55  			return fmt.Errorf("could not share file or directory %s: %w", s.host, err)
    56  		} else {
    57  			logrus.WithFields(logrus.Fields{
    58  				"host":     s.host,
    59  				"guest":    s.guest,
    60  				"writable": s.writable,
    61  			}).Debug("Shared path")
    62  		}
    63  	}
    64  
    65  	return nil
    66  }
    67  
    68  func mountVPMem(ctx context.Context, c *cli.Context, vm *uvm.UtilityVM) error {
    69  	if !c.IsSet(vpmemMountsArgName) {
    70  		return nil
    71  	}
    72  	for _, p := range c.StringSlice(vpmemMountsArgName) {
    73  		if _, err := vm.AddVPMem(ctx, p); err != nil {
    74  			return fmt.Errorf("could not mount VPMem device: %w", err)
    75  		}
    76  	}
    77  	return nil
    78  }
    79  
    80  type mount struct {
    81  	host     string
    82  	guest    string
    83  	writable bool
    84  }
    85  
    86  // parseMounts parses the mounts stored under the cli StringSlice argument, `n`
    87  func parseMounts(c *cli.Context, n string) []mount {
    88  	if c.IsSet(n) {
    89  		ss := c.StringSlice(n)
    90  		ms := make([]mount, 0, len(ss))
    91  		for _, s := range ss {
    92  			logrus.Debugf("parsing %q", s)
    93  
    94  			if m, err := mountFromString(s); err == nil {
    95  				ms = append(ms, m)
    96  			}
    97  		}
    98  
    99  		return ms
   100  	}
   101  
   102  	return nil
   103  }
   104  
   105  func mountFromString(s string) (m mount, _ error) {
   106  	ps := strings.Split(s, ",")
   107  
   108  	l := len(ps)
   109  	if l == 0 { // shouldn't happen, but just in case
   110  		return m, fmt.Errorf("could not parse string %q", s)
   111  	}
   112  
   113  	if l > 3 {
   114  		return m, fmt.Errorf("too many parts in %q", s)
   115  	}
   116  
   117  	m.host = ps[0]
   118  
   119  	if l >= 2 {
   120  		m.guest = ps[1]
   121  	}
   122  
   123  	if l == 3 && strings.ToLower(ps[2]) == "w" {
   124  		m.writable = true
   125  	}
   126  
   127  	return m, nil
   128  }
   129  

View as plain text