Skip to content

Commit 86786da

Browse files
MouriNarutoVigilans
andcommitted
Add Virtual SMB shares configuration support. (#50) (Contributed by Vigilans.)
Co-authored-by: Vigilans <vigilans@foxmail.com>
1 parent 684a75f commit 86786da

6 files changed

Lines changed: 216 additions & 13 deletions

Documents/ConfigurationReference.md

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@
132132
- Port (Number)
133133
- Path (String)
134134
- Name (String)
135+
- VirtualSmbShares (Object Array)
136+
- ReadOnly (Boolean)
137+
- Path (String)
138+
- Name (String)
135139

136140
### NanaBox
137141

@@ -228,36 +232,39 @@ Available values: "Disabled", "Default", "List" and "Mirror"
228232

229233
#### EnableHostDriverStore
230234

231-
(Optional) Set it true if you want to enable readonly Plan 9 shares for several
232-
GPU-PV (paravirtualization) related folders from the Host OS.
235+
(Optional) Set it true if you want to enable readonly Plan 9 and Virtual SMB
236+
shares for several GPU-PV (paravirtualization) related folders from the Host OS.
233237

234238
Note: You cannot suspend the virtual machine properly if this option is enabled.
235239

236240
Note: All these shares are transported with Hyper-V Socket.
237241

238242
Note: Available starting with NanaBox 1.2.
239243

240-
Here are the exposed readonly Plan 9 shares:
244+
Here are the exposed readonly Plan 9 and Virtual SMB shares:
241245

242246
- Access Name: HostDriverStore
243247
- Available starting with NanaBox 1.2.
244248
- Deprecated, reserved for compatibility with virtual machines hosted with
245249
previous NanaBox versions.
246250
- Host Path: %SystemRoot%\System32\DriverStore
247-
- Hyper-V Socket Port: 50001
251+
- Hyper-V Socket Port for Plan 9 share: 50001
252+
- Virtual SMB share support: N/A
248253
- Suggested Guest Paths:
249254
- Windows: %SystemRoot%\System32\HostDriverStore
250255
- Access Name: NanaBox.HostDrivers
251256
- Available starting with NanaBox 1.5 Update 3.
252257
- Host Path: %SystemRoot%\System32\DriverStore\FileRepository
253-
- Hyper-V Socket Port: 50001
258+
- Hyper-V Socket Port for Plan 9 share: 50001
259+
- Virtual SMB share support: Available starting with NanaBox 1.6 Update 1.
254260
- Suggested Guest Paths:
255261
- Windows: %SystemRoot%\System32\HostDriverStore\FileRepository
256262
- Linux: /usr/lib/wsl/drivers
257263
- Access Name: NanaBox.HostLxssLib
258264
- Available starting with NanaBox 1.5 Update 3.
259265
- Host Path: %SystemRoot%\System32\lxss\lib
260-
- Hyper-V Socket Port: 50001
266+
- Hyper-V Socket Port for Plan 9 share: 50001
267+
- Virtual SMB share support: Available starting with NanaBox 1.6 Update 1.
261268
- Suggested Guest Paths:
262269
- Linux: /usr/lib/wsl/lib
263270

@@ -877,6 +884,42 @@ names mentioned in "EnableHostDriverStore" related document for the current Plan
877884

878885
Note: Available starting with NanaBox 1.5 Update 2.
879886

887+
### VirtualSmbShares
888+
889+
The Virtual SMB shares setting object array of virtual machine.
890+
891+
Note: You cannot suspend the virtual machine properly if this option is enabled.
892+
893+
Note: Available starting with NanaBox 1.6 Update 1.
894+
895+
#### ReadOnly
896+
897+
(Optional) Set it true if you want to make the current Virtual SMB share read-only.
898+
899+
Note: Available starting with NanaBox 1.6 Update 1.
900+
901+
#### Path
902+
903+
The host path of the current Virtual SMB share.
904+
905+
Note: The relative path is supported.
906+
907+
Example value: "D:\\Projects"
908+
909+
Note: Available starting with NanaBox 1.6 Update 1.
910+
911+
#### Name
912+
913+
The guest access name of the current Virtual SMB share.
914+
915+
Example value: "HostProjects"
916+
917+
Note: If you have set the "EnableHostDriverStore" true, you should not use the
918+
names mentioned in "EnableHostDriverStore" related document for the current
919+
Virtual SMB share.
920+
921+
Note: Available starting with NanaBox 1.6 Update 1.
922+
880923
## Samples
881924

882925
### Typical Windows Virtual Machine

Documents/ConfigurationSchema.json

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@
136136
},
137137
"EnableHostDriverStore": {
138138
"type": "boolean",
139-
"description": "Set it true if you want to enable readonly Plan 9 shares for several GPU-PV (paravirtualization) related folders from the Host OS. You cannot suspend the virtual machine properly if this option is enabled. All these shares are transported with Hyper-V Socket. Available starting with NanaBox 1.2. Read NanaBox Configuration File Reference for more information."
139+
"description": "Set it true if you want to enable readonly Plan 9 and Virtual SMB shares for several GPU-PV (paravirtualization) related folders from the Host OS. You cannot suspend the virtual machine properly if this option is enabled. All these shares are transported with Hyper-V Socket. Available starting with NanaBox 1.2. Read NanaBox Configuration File Reference for more information."
140140
},
141141
"SelectedDevices": {
142142
"type": "array",
@@ -401,6 +401,30 @@
401401
}
402402
}
403403
}
404+
},
405+
"VirtualSmbShares": {
406+
"type": "array",
407+
"description": "The Virtual SMB shares setting object array of virtual machine. You cannot suspend the virtual machine properly if this option is enabled. Available starting with NanaBox 1.6 Update 1.",
408+
"items": {
409+
"type": "object",
410+
"required": [ "Path", "Name" ],
411+
"properties": {
412+
"ReadOnly": {
413+
"type": "boolean",
414+
"description": "Set it true if you want to make the current Virtual SMB share read-only. Available starting with NanaBox 1.6 Update 1."
415+
},
416+
"Path": {
417+
"type": "string",
418+
"description": "The host path of the current Virtual SMB share. The relative path is supported. Available starting with NanaBox 1.6 Update 1.",
419+
"examples": [ "D:\\Projects" ]
420+
},
421+
"Name": {
422+
"type": "string",
423+
"description": "The guest access name of the current Virtual SMB share. If you have set the \"EnableHostDriverStore\" true, you should not use the names mentioned in \"EnableHostDriverStore\" related document for the current Virtual SMB share. Available starting with NanaBox 1.6 Update 1.",
424+
"examples": [ "HostProjects" ]
425+
}
426+
}
427+
}
404428
}
405429
}
406430
}

NanaBox/ConfigurationManager.cpp

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -361,12 +361,20 @@ std::string NanaBox::MakeHcsConfiguration(
361361

362362
{
363363
nlohmann::json Plan9Shares;
364+
nlohmann::json VirtualSmbShares;
364365

365366
if (Configuration.Gpu.EnableHostDriverStore)
366367
{
368+
std::wstring SystemDirectoryPath(MAX_PATH, L'\0');
369+
SystemDirectoryPath.resize(::GetSystemDirectoryW(
370+
SystemDirectoryPath.data(),
371+
static_cast<UINT>(SystemDirectoryPath.size())));
372+
367373
const std::uint32_t Plan9SharePort = 50001;
368374

369-
const struct { LPCSTR Name; LPCWSTR Path; } Plan9ShareItems[] =
375+
typedef struct { LPCSTR Name; LPCWSTR Path; } ShareItem;
376+
377+
const ShareItem Plan9ShareItems[] =
370378
{
371379
{ "HostDriverStore", L"\\DriverStore" },
372380
{ "NanaBox.HostDrivers", L"\\DriverStore\\FileRepository" },
@@ -375,10 +383,13 @@ std::string NanaBox::MakeHcsConfiguration(
375383
const size_t Plan9ShareItemsCount =
376384
sizeof(Plan9ShareItems) / sizeof(*Plan9ShareItems);
377385

378-
std::wstring SystemDirectoryPath(MAX_PATH, L'\0');
379-
SystemDirectoryPath.resize(::GetSystemDirectoryW(
380-
SystemDirectoryPath.data(),
381-
static_cast<UINT>(SystemDirectoryPath.size())));
386+
const ShareItem VirtualSmbShareItems[] =
387+
{
388+
{ "NanaBox.HostDrivers", L"\\DriverStore\\FileRepository" },
389+
{ "NanaBox.HostLxssLib", L"\\lxss\\lib" }
390+
};
391+
const size_t VirtualSmbShareItemsCount =
392+
sizeof(VirtualSmbShareItems) / sizeof(*VirtualSmbShareItems);
382393

383394
for (size_t i = 0; i < Plan9ShareItemsCount; ++i)
384395
{
@@ -398,6 +409,27 @@ std::string NanaBox::MakeHcsConfiguration(
398409
Current["Flags"] = NanaBox::Plan9ShareFlags::ReadOnly;
399410
Plan9Shares.push_back(Current);
400411
}
412+
413+
for (size_t i = 0; i < VirtualSmbShareItemsCount; ++i)
414+
{
415+
std::wstring SharePath(
416+
SystemDirectoryPath + VirtualSmbShareItems[i].Path);
417+
418+
if (!::PathFileExistsW(SharePath.c_str()))
419+
{
420+
continue;
421+
}
422+
423+
nlohmann::json Current;
424+
Current["Name"] = VirtualSmbShareItems[i].Name;
425+
Current["Path"] = Mile::ToString(CP_UTF8, SharePath);
426+
Current["Options"]["ReadOnly"] = true;
427+
Current["Options"]["ShareRead"] = true;
428+
Current["Options"]["CacheIo"] = true;
429+
Current["Options"]["PseudoOplocks"] = true;
430+
Current["Options"]["SupportCloudFiles"] = true;
431+
VirtualSmbShares.push_back(Current);
432+
}
401433
}
402434

403435
for (NanaBox::Plan9ShareConfiguration const& Plan9Share
@@ -413,11 +445,27 @@ std::string NanaBox::MakeHcsConfiguration(
413445
: NanaBox::Plan9ShareFlags::None;
414446
Plan9Shares.push_back(Current);
415447
}
416-
417448
if (!Plan9Shares.empty())
418449
{
419450
Devices["Plan9"]["Shares"] = Plan9Shares;
420451
}
452+
453+
for (NanaBox::VirtualSmbShareConfiguration const& VirtualSmbShare
454+
: Configuration.VirtualSmbShares)
455+
{
456+
nlohmann::json Current;
457+
Current["Name"] = VirtualSmbShare.Name;
458+
Current["Path"] = ::GetAbsoluteUtf8Path(VirtualSmbShare.Path);
459+
if (VirtualSmbShare.ReadOnly)
460+
{
461+
Current["Options"]["ReadOnly"] = true;
462+
Current["Options"]["ShareRead"] = true;
463+
Current["Options"]["CacheIo"] = true;
464+
Current["Options"]["PseudoOplocks"] = true;
465+
}
466+
Current["Options"]["SupportCloudFiles"] = true;
467+
VirtualSmbShares.push_back(Current);
468+
}
421469
}
422470
}
423471
VirtualMachine["Devices"] = Devices;

NanaBox/NanaBox.Configuration.Parser.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,49 @@ NanaBox::Plan9ShareConfiguration NanaBox::ToPlan9ShareConfiguration(
840840
return Result;
841841
}
842842

843+
nlohmann::json NanaBox::FromVirtualSmbShareConfiguration(
844+
VirtualSmbShareConfiguration const& Value)
845+
{
846+
nlohmann::json Result;
847+
848+
if (Value.ReadOnly)
849+
{
850+
Result["ReadOnly"] = true;
851+
}
852+
853+
if (!Value.Path.empty())
854+
{
855+
Result["Path"] = Value.Path;
856+
}
857+
858+
if (!Value.Name.empty())
859+
{
860+
Result["Name"] = Value.Name;
861+
}
862+
863+
return Result;
864+
}
865+
866+
NanaBox::VirtualSmbShareConfiguration NanaBox::ToVirtualSmbShareConfiguration(
867+
nlohmann::json const& Value)
868+
{
869+
NanaBox::VirtualSmbShareConfiguration Result;
870+
871+
Result.ReadOnly = Mile::Json::ToBoolean(
872+
Mile::Json::GetSubKey(Value, "ReadOnly"),
873+
Result.ReadOnly);
874+
875+
Result.Path = Mile::Json::ToString(
876+
Mile::Json::GetSubKey(Value, "Path"),
877+
Result.Path);
878+
879+
Result.Name = Mile::Json::ToString(
880+
Mile::Json::GetSubKey(Value, "Name"),
881+
Result.Name);
882+
883+
return Result;
884+
}
885+
843886
nlohmann::json NanaBox::FromVirtualMachineConfiguration(
844887
NanaBox::VirtualMachineConfiguration const& Value)
845888
{
@@ -983,6 +1026,23 @@ nlohmann::json NanaBox::FromVirtualMachineConfiguration(
9831026
Result["Plan9Shares"] = Plan9Shares;
9841027
}
9851028

1029+
if (!Value.VirtualSmbShares.empty())
1030+
{
1031+
nlohmann::json VirtualSmbShares;
1032+
for (NanaBox::VirtualSmbShareConfiguration const& VirtualSmbShare
1033+
: Value.VirtualSmbShares)
1034+
{
1035+
if (VirtualSmbShare.Path.empty() || VirtualSmbShare.Name.empty())
1036+
{
1037+
continue;
1038+
}
1039+
1040+
VirtualSmbShares.push_back(
1041+
NanaBox::FromVirtualSmbShareConfiguration(VirtualSmbShare));
1042+
}
1043+
Result["VirtualSmbShares"] = VirtualSmbShares;
1044+
}
1045+
9861046
return Result;
9871047
}
9881048

@@ -1100,5 +1160,19 @@ NanaBox::VirtualMachineConfiguration NanaBox::ToVirtualMachineConfiguration(
11001160
Result.Plan9Shares.push_back(Current);
11011161
}
11021162

1163+
for (nlohmann::json const& VirtualSmbShare : Mile::Json::ToArray(
1164+
Mile::Json::GetSubKey(Value, "VirtualSmbShares")))
1165+
{
1166+
NanaBox::VirtualSmbShareConfiguration Current =
1167+
NanaBox::ToVirtualSmbShareConfiguration(VirtualSmbShare);
1168+
1169+
if (Current.Path.empty() || Current.Name.empty())
1170+
{
1171+
continue;
1172+
}
1173+
1174+
Result.VirtualSmbShares.push_back(Current);
1175+
}
1176+
11031177
return Result;
11041178
}

NanaBox/NanaBox.Configuration.Parser.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ namespace NanaBox
9595
Plan9ShareConfiguration ToPlan9ShareConfiguration(
9696
nlohmann::json const& Value);
9797

98+
nlohmann::json FromVirtualSmbShareConfiguration(
99+
VirtualSmbShareConfiguration const& Value);
100+
101+
VirtualSmbShareConfiguration ToVirtualSmbShareConfiguration(
102+
nlohmann::json const& Value);
103+
98104
nlohmann::json FromVirtualMachineConfiguration(
99105
VirtualMachineConfiguration const& Value);
100106

NanaBox/NanaBox.Configuration.Specification.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,13 @@ namespace NanaBox
148148
std::string Name;
149149
};
150150

151+
struct VirtualSmbShareConfiguration
152+
{
153+
bool ReadOnly = false;
154+
std::string Path;
155+
std::string Name;
156+
};
157+
151158
struct VirtualMachineConfiguration
152159
{
153160
std::uint32_t Version = 1;
@@ -171,6 +178,7 @@ namespace NanaBox
171178
VideoMonitorConfiguration VideoMonitor;
172179
std::vector<std::string> Policies;
173180
std::vector<Plan9ShareConfiguration> Plan9Shares;
181+
std::vector<VirtualSmbShareConfiguration> VirtualSmbShares;
174182
};
175183
}
176184

0 commit comments

Comments
 (0)