1
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,
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
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 {
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