1package uvm
2
3import (
4	"context"
5	"fmt"
6	"os"
7	"path/filepath"
8
9	"github.com/Microsoft/hcsshim/internal/guestrequest"
10	"github.com/Microsoft/hcsshim/internal/requesttype"
11	hcsschema "github.com/Microsoft/hcsshim/internal/schema2"
12)
13
14// Share shares in file(s) from `reqHostPath` on the host machine to `reqUVMPath` inside the UVM.
15// This function handles both LCOW and WCOW scenarios.
16func (uvm *UtilityVM) Share(ctx context.Context, reqHostPath, reqUVMPath string, readOnly bool) (err error) {
17	if uvm.OS() == "windows" {
18		options := uvm.DefaultVSMBOptions(readOnly)
19		vsmbShare, err := uvm.AddVSMB(ctx, reqHostPath, options)
20		if err != nil {
21			return err
22		}
23		defer func() {
24			if err != nil {
25				vsmbShare.Release(ctx)
26			}
27		}()
28
29		sharePath, err := uvm.GetVSMBUvmPath(ctx, reqHostPath, readOnly)
30		if err != nil {
31			return err
32		}
33		guestReq := guestrequest.GuestRequest{
34			ResourceType: guestrequest.ResourceTypeMappedDirectory,
35			RequestType:  requesttype.Add,
36			Settings: &hcsschema.MappedDirectory{
37				HostPath:      sharePath,
38				ContainerPath: reqUVMPath,
39				ReadOnly:      readOnly,
40			},
41		}
42		if err := uvm.GuestRequest(ctx, guestReq); err != nil {
43			return err
44		}
45	} else {
46		st, err := os.Stat(reqHostPath)
47		if err != nil {
48			return fmt.Errorf("could not open '%s' path on host: %s", reqHostPath, err)
49		}
50		var (
51			hostPath       string = reqHostPath
52			restrictAccess bool
53			fileName       string
54			allowedNames   []string
55		)
56		if !st.IsDir() {
57			hostPath, fileName = filepath.Split(hostPath)
58			allowedNames = append(allowedNames, fileName)
59			restrictAccess = true
60		}
61		plan9Share, err := uvm.AddPlan9(ctx, hostPath, reqUVMPath, readOnly, restrictAccess, allowedNames)
62		if err != nil {
63			return err
64		}
65		defer func() {
66			if err != nil {
67				plan9Share.Release(ctx)
68			}
69		}()
70	}
71	return nil
72}
73