Skip to content

Commit 5825524

Browse files
committed
feat: add instance-specific config
Add support for defining custom mounts in runtime configuration files. Run with --instance will apply instance-specific runtime configurations and run in an isolate container environment. Signed-off-by: reddevillg <reddevillg@gmail.com>
1 parent 235d593 commit 5825524

16 files changed

Lines changed: 529 additions & 16 deletions

File tree

api/schema/v1.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,18 @@
14571457
},
14581458
"disable_xdp": {
14591459
"type": "boolean"
1460+
},
1461+
"mounts": {
1462+
"type": "array",
1463+
"items": {
1464+
"$ref": "#/$defs/Mount"
1465+
}
1466+
},
1467+
"instances": {
1468+
"type": "object",
1469+
"additionalProperties": {
1470+
"$ref": "#/$defs/RuntimeConfigure"
1471+
}
14601472
}
14611473
}
14621474
},
@@ -1499,6 +1511,15 @@
14991511
"items": {
15001512
"$ref": "#/$defs/CDIDeviceEntry"
15011513
}
1514+
},
1515+
"instance": {
1516+
"type": "string"
1517+
},
1518+
"mounts": {
1519+
"type": "array",
1520+
"items": {
1521+
"$ref": "#/$defs/Mount"
1522+
}
15021523
}
15031524
}
15041525
},
@@ -1545,6 +1566,31 @@
15451566
"enum": [
15461567
"passthru"
15471568
]
1569+
},
1570+
"Mount": {
1571+
"type": "object",
1572+
"required": [
1573+
"destination",
1574+
"source",
1575+
"type"
1576+
],
1577+
"properties": {
1578+
"destination": {
1579+
"type": "string"
1580+
},
1581+
"source": {
1582+
"type": "string"
1583+
},
1584+
"type": {
1585+
"type": "string"
1586+
},
1587+
"options": {
1588+
"type": "array",
1589+
"items": {
1590+
"type": "string"
1591+
}
1592+
}
1593+
}
15481594
}
15491595
},
15501596
"type": "object",
@@ -1698,6 +1744,9 @@
16981744
},
16991745
"DeviceOption": {
17001746
"$ref": "#/$defs/DeviceOption"
1747+
},
1748+
"Mount": {
1749+
"$ref": "#/$defs/Mount"
17011750
}
17021751
}
17031752
}

api/schema/v1.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,14 @@ $defs:
11031103
$ref: '#/$defs/DeviceOption'
11041104
disable_xdp:
11051105
type: boolean
1106+
mounts:
1107+
type: array
1108+
items:
1109+
$ref: '#/$defs/Mount'
1110+
instances:
1111+
type: object
1112+
additionalProperties:
1113+
$ref: '#/$defs/RuntimeConfigure'
11061114
RunContextConfig:
11071115
title: RunContextConfig
11081116
type: object
@@ -1131,6 +1139,12 @@ $defs:
11311139
type: array
11321140
items:
11331141
$ref: '#/$defs/CDIDeviceEntry'
1142+
instance:
1143+
type: string
1144+
mounts:
1145+
type: array
1146+
items:
1147+
$ref: '#/$defs/Mount'
11341148
CDIDeviceEntry:
11351149
title: CDIDeviceEntry
11361150
type: object
@@ -1162,6 +1176,23 @@ $defs:
11621176
DeviceOption:
11631177
description: device option
11641178
enum: ["passthru"]
1179+
Mount:
1180+
type: object
1181+
required:
1182+
- destination
1183+
- source
1184+
- type
1185+
properties:
1186+
destination:
1187+
type: string
1188+
source:
1189+
type: string
1190+
type:
1191+
type: string
1192+
options:
1193+
type: array
1194+
items:
1195+
type: string
11651196
type: object
11661197
properties:
11671198
# NOTE: "properties" is auto generated by referring all types is $defs

apps/ll-cli/src/main.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,12 @@ ll-cli run org.deepin.demo -- bash -x /path/to/bash/script)"));
201201
->delimiter(',')
202202
->transform(CLI::CheckedTransformer(deviceOptionMap, CLI::ignore_case))
203203
->allow_extra_args(false);
204+
cliRun
205+
->add_option("--instance",
206+
runOptions.instance,
207+
_("Specify the container instance name for reuse or identification"))
208+
->type_name("NAME")
209+
->check(validatorString);
204210
cliRun->add_option("COMMAND", runOptions.commands, _("Run commands in a running sandbox"));
205211
}
206212

libs/api/src/linglong/api/types/v1/Generators.hpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#include "linglong/api/types/v1/PackageInfoDisplay.hpp"
5151
#include "linglong/api/types/v1/PackageInfo.hpp"
5252
#include "linglong/api/types/v1/OciConfigurationPatch.hpp"
53+
#include "linglong/api/types/v1/Mount.hpp"
5354
#include "linglong/api/types/v1/LayerInfo.hpp"
5455
#include "linglong/api/types/v1/InteractionRequest.hpp"
5556
#include "linglong/api/types/v1/InteractionReply.hpp"
@@ -173,6 +174,9 @@ void to_json(json & j, const InteractionRequest & x);
173174
void from_json(const json & j, LayerInfo & x);
174175
void to_json(json & j, const LayerInfo & x);
175176

177+
void from_json(const json & j, Mount & x);
178+
void to_json(json & j, const Mount & x);
179+
176180
void from_json(const json & j, OciConfigurationPatch & x);
177181
void to_json(json & j, const OciConfigurationPatch & x);
178182

@@ -753,6 +757,23 @@ j["info"] = x.info;
753757
j["version"] = x.version;
754758
}
755759

760+
inline void from_json(const json & j, Mount& x) {
761+
x.destination = j.at("destination").get<std::string>();
762+
x.options = get_stack_optional<std::vector<std::string>>(j, "options");
763+
x.source = j.at("source").get<std::string>();
764+
x.type = j.at("type").get<std::string>();
765+
}
766+
767+
inline void to_json(json & j, const Mount & x) {
768+
j = json::object();
769+
j["destination"] = x.destination;
770+
if (x.options) {
771+
j["options"] = x.options;
772+
}
773+
j["source"] = x.source;
774+
j["type"] = x.type;
775+
}
776+
756777
inline void from_json(const json & j, OciConfigurationPatch& x) {
757778
x.ociVersion = j.at("ociVersion").get<std::string>();
758779
x.patch = j.at("patch").get<std::vector<nlohmann::json>>();
@@ -1244,6 +1265,8 @@ x.app = get_stack_optional<std::string>(j, "app");
12441265
x.base = get_stack_optional<std::string>(j, "base");
12451266
x.cdiDevices = get_stack_optional<std::vector<CdiDeviceEntry>>(j, "cdiDevices");
12461267
x.extensions = get_stack_optional<std::map<std::string, std::vector<std::string>>>(j, "extensions");
1268+
x.instance = get_stack_optional<std::string>(j, "instance");
1269+
x.mounts = get_stack_optional<std::vector<Mount>>(j, "mounts");
12471270
x.overlayfs = get_stack_optional<std::string>(j, "overlayfs");
12481271
x.runtime = get_stack_optional<std::string>(j, "runtime");
12491272
x.timezone = get_stack_optional<std::string>(j, "timezone");
@@ -1264,6 +1287,12 @@ j["cdiDevices"] = x.cdiDevices;
12641287
if (x.extensions) {
12651288
j["extensions"] = x.extensions;
12661289
}
1290+
if (x.instance) {
1291+
j["instance"] = x.instance;
1292+
}
1293+
if (x.mounts) {
1294+
j["mounts"] = x.mounts;
1295+
}
12671296
if (x.overlayfs) {
12681297
j["overlayfs"] = x.overlayfs;
12691298
}
@@ -1281,6 +1310,8 @@ x.deviceMode = get_stack_optional<std::vector<DeviceOption>>(j, "device_mode");
12811310
x.disableXdp = get_stack_optional<bool>(j, "disable_xdp");
12821311
x.env = get_stack_optional<std::map<std::string, std::string>>(j, "env");
12831312
x.extDefs = get_stack_optional<std::map<std::string, std::vector<ExtensionDefine>>>(j, "ext_defs");
1313+
x.instances = get_stack_optional<std::map<std::string, RuntimeConfigure>>(j, "instances");
1314+
x.mounts = get_stack_optional<std::vector<Mount>>(j, "mounts");
12841315
}
12851316

12861317
inline void to_json(json & j, const RuntimeConfigure & x) {
@@ -1297,6 +1328,12 @@ j["env"] = x.env;
12971328
if (x.extDefs) {
12981329
j["ext_defs"] = x.extDefs;
12991330
}
1331+
if (x.instances) {
1332+
j["instances"] = x.instances;
1333+
}
1334+
if (x.mounts) {
1335+
j["mounts"] = x.mounts;
1336+
}
13001337
}
13011338

13021339
inline void from_json(const json & j, UabLayer& x) {
@@ -1380,6 +1417,7 @@ x.interactionMessageType = get_stack_optional<InteractionMessageType>(j, "Intera
13801417
x.interactionReply = get_stack_optional<InteractionReply>(j, "InteractionReply");
13811418
x.interactionRequest = get_stack_optional<InteractionRequest>(j, "InteractionRequest");
13821419
x.layerInfo = get_stack_optional<LayerInfo>(j, "LayerInfo");
1420+
x.mount = get_stack_optional<Mount>(j, "Mount");
13831421
x.ociConfigurationPatch = get_stack_optional<OciConfigurationPatch>(j, "OCIConfigurationPatch");
13841422
x.packageInfo = get_stack_optional<PackageInfo>(j, "PackageInfo");
13851423
x.packageInfoDisplay = get_stack_optional<PackageInfoDisplay>(j, "PackageInfoDisplay");
@@ -1478,6 +1516,9 @@ j["InteractionRequest"] = x.interactionRequest;
14781516
if (x.layerInfo) {
14791517
j["LayerInfo"] = x.layerInfo;
14801518
}
1519+
if (x.mount) {
1520+
j["Mount"] = x.mount;
1521+
}
14811522
if (x.ociConfigurationPatch) {
14821523
j["OCIConfigurationPatch"] = x.ociConfigurationPatch;
14831524
}

libs/api/src/linglong/api/types/v1/LinglongAPIV1.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "linglong/api/types/v1/InteractionReply.hpp"
3838
#include "linglong/api/types/v1/InteractionRequest.hpp"
3939
#include "linglong/api/types/v1/LayerInfo.hpp"
40+
#include "linglong/api/types/v1/Mount.hpp"
4041
#include "linglong/api/types/v1/OciConfigurationPatch.hpp"
4142
#include "linglong/api/types/v1/PackageInfo.hpp"
4243
#include "linglong/api/types/v1/PackageInfoDisplay.hpp"
@@ -113,6 +114,7 @@ std::optional<InteractionMessageType> interactionMessageType;
113114
std::optional<InteractionReply> interactionReply;
114115
std::optional<InteractionRequest> interactionRequest;
115116
std::optional<LayerInfo> layerInfo;
117+
std::optional<Mount> mount;
116118
std::optional<OciConfigurationPatch> ociConfigurationPatch;
117119
std::optional<PackageInfo> packageInfo;
118120
std::optional<PackageInfoDisplay> packageInfoDisplay;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// This file is generated by tools/codegen.sh
2+
// DO NOT EDIT IT.
3+
4+
// clang-format off
5+
6+
// To parse this JSON data, first install
7+
//
8+
// json.hpp https://github.com/nlohmann/json
9+
//
10+
// Then include this file, and then do
11+
//
12+
// Mount.hpp data = nlohmann::json::parse(jsonString);
13+
14+
#pragma once
15+
16+
#include <optional>
17+
#include <nlohmann/json.hpp>
18+
#include "linglong/api/types/v1/helper.hpp"
19+
20+
namespace linglong {
21+
namespace api {
22+
namespace types {
23+
namespace v1 {
24+
using nlohmann::json;
25+
26+
struct Mount {
27+
std::string destination;
28+
std::optional<std::vector<std::string>> options;
29+
std::string source;
30+
std::string type;
31+
};
32+
}
33+
}
34+
}
35+
}
36+
37+
// clang-format on

libs/api/src/linglong/api/types/v1/RunContextConfig.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "linglong/api/types/v1/helper.hpp"
1919

2020
#include "linglong/api/types/v1/CdiDeviceEntry.hpp"
21+
#include "linglong/api/types/v1/Mount.hpp"
2122

2223
namespace linglong {
2324
namespace api {
@@ -30,6 +31,8 @@ std::optional<std::string> app;
3031
std::optional<std::string> base;
3132
std::optional<std::vector<CdiDeviceEntry>> cdiDevices;
3233
std::optional<std::map<std::string, std::vector<std::string>>> extensions;
34+
std::optional<std::string> instance;
35+
std::optional<std::vector<Mount>> mounts;
3336
std::optional<std::string> overlayfs;
3437
std::optional<std::string> runtime;
3538
std::optional<std::string> timezone;

libs/api/src/linglong/api/types/v1/RuntimeConfigure.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "linglong/api/types/v1/helper.hpp"
1919

2020
#include "linglong/api/types/v1/ExtensionDefine.hpp"
21+
#include "linglong/api/types/v1/Mount.hpp"
2122

2223
namespace linglong {
2324
namespace api {
@@ -43,6 +44,8 @@ std::optional<std::map<std::string, std::string>> env;
4344
* external extension definitions to extend the component
4445
*/
4546
std::optional<std::map<std::string, std::vector<ExtensionDefine>>> extDefs;
47+
std::optional<std::map<std::string, RuntimeConfigure>> instances;
48+
std::optional<std::vector<Mount>> mounts;
4649
};
4750
}
4851
}

libs/linglong/src/linglong/cli/cli.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ int Cli::run(const RunOptions &options)
627627
return -1;
628628
}
629629

630-
auto loaded = linglong::utils::loadRuntimeConfig(options.appid);
630+
auto loaded = linglong::utils::loadRuntimeConfig(options.appid, options.instance.value_or(""));
631631
if (!loaded) {
632632
this->printer.printErr(loaded.error());
633633
return -1;
@@ -636,14 +636,17 @@ int Cli::run(const RunOptions &options)
636636

637637
runtime::RunContext runContext(this->repository);
638638
linglong::runtime::ResolveOptions opts;
639-
opts.baseRef = options.base;
640-
opts.runtimeRef = options.runtime;
641-
// 处理多个扩展
642-
if (!options.extensions.empty()) {
643-
opts.extensionRefs = options.extensions;
639+
if (runtimeConfig) {
640+
auto cfgRes = opts.applyRuntimeConfig(*runtimeConfig);
641+
if (!cfgRes) {
642+
this->printer.printErr(cfgRes.error());
643+
return -1;
644+
}
644645
}
645-
if (runtimeConfig && runtimeConfig->extDefs) {
646-
opts.externalExtensionDefs = std::move(runtimeConfig->extDefs).value();
646+
auto cliRes = opts.applyCliRunOptions(options);
647+
if (!cliRes) {
648+
this->printer.printErr(cliRes.error());
649+
return -1;
647650
}
648651
if (!options.cdiDevices.empty()) {
649652
auto cdiDevices = cdi::getCDIDevices(options.cdiSpecDir, options.cdiDevices);
@@ -805,7 +808,7 @@ int Cli::runWithContext(const RunOptions &options)
805808
return -1;
806809
}
807810

808-
auto loaded = linglong::utils::loadRuntimeConfig(options.appid);
811+
auto loaded = linglong::utils::loadRuntimeConfig(options.appid, options.instance.value_or(""));
809812
if (!loaded) {
810813
this->printer.printErr(loaded.error());
811814
return -1;

libs/linglong/src/linglong/cli/cli.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ struct RunOptions
6363
std::vector<std::string> cdiSpecDir = { "/etc/cdi", "/var/run/cdi" };
6464
std::vector<std::string> cdiDevices;
6565
std::vector<api::types::v1::DeviceOption> deviceOptions;
66+
std::optional<std::string> instance;
6667
};
6768

6869
struct EnterOptions

0 commit comments

Comments
 (0)