@synopackageland/templates 0.35.5 → 0.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -17
- package/package.json +1 -1
- package/templates/compose/dsm-package.yaml +1 -1
- package/templates/native-go/README.md +2 -2
- package/templates/native-go/backend/THIRD_PARTY_NOTICES.txt +1 -1
- package/templates/native-go/backend/go.mod +1 -1
- package/templates/native-go/backend/go.sum +2 -2
- package/templates/native-go/backend/internal/app/background.go +10 -12
- package/templates/native-go/backend/internal/app/background_inbox_test.go +37 -0
- package/templates/native-go/backend/internal/app/background_owner.go +14 -0
- package/templates/native-go/backend/internal/app/background_owner_test.go +2 -2
- package/templates/native-go/backend/internal/app/background_test.go +27 -8
- package/templates/native-go-delegate/frontend/src/CapabilityPanels.vue +1 -1
- package/templates/native-go-delegate/frontend/test/capability-panels.test.ts +1 -0
- package/templates/native-go-vue/frontend/package-lock.json +658 -9
- package/templates/native-go-vue/frontend/package.json +2 -2
- package/templates/native-node/README.md +2 -2
- package/templates/native-node/backend/package-lock.json +2 -2
- package/templates/native-node/dsm-package.yaml +1 -1
- package/templates/native-node-delegate/backend/src/delegate.ts +20 -8
- package/templates/native-node-delegate/backend/test/delegate.test.ts +18 -9
- package/templates/native-python/README.md +2 -2
- package/templates/native-python/dsm-package.yaml +1 -1
- package/templates/native-python-delegate/backend/app/delegate.py +19 -7
- package/templates/native-python-delegate/backend/tests/test_delegate.py +18 -8
- package/templates/native-rust/README.md +2 -2
- package/templates/native-rust/backend/Cargo.lock +2 -2
- package/templates/native-rust/backend/Cargo.toml +1 -1
- package/templates/native-rust-delegate/backend/Cargo.lock +203 -0
- package/templates/native-rust-delegate/backend/Cargo.toml +17 -0
- package/templates/native-rust-delegate/backend/src/delegate.rs +78 -23
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
use crate::routes::{Config, internal, utc_now};
|
|
7
7
|
use serde::Deserialize;
|
|
8
8
|
use serde_json::{Value, json};
|
|
9
|
+
use sha2::{Digest, Sha256};
|
|
9
10
|
use std::fs::OpenOptions;
|
|
10
11
|
use std::io::{ErrorKind, Write};
|
|
11
12
|
use std::os::unix::fs::{DirBuilderExt, OpenOptionsExt};
|
|
@@ -31,12 +32,25 @@ fn valid_job_id(id: &str) -> bool {
|
|
|
31
32
|
|
|
32
33
|
fn save(cfg: &Config, ctx: &Context, params: &Params) -> Result<Value, Error> {
|
|
33
34
|
let p: SaveReport = params.decode()?;
|
|
34
|
-
if !valid_job_id(&p.job_id) {
|
|
35
|
+
if !valid_job_id(&p.job_id) || !valid_job_id(&p.delegation_id) {
|
|
35
36
|
return Err(Error::bad_request(
|
|
36
37
|
"job_id must be 1 to 128 letters, digits, '.', '_' or '-'",
|
|
37
38
|
));
|
|
38
39
|
}
|
|
39
|
-
let
|
|
40
|
+
let owner = format!(
|
|
41
|
+
"{:x}",
|
|
42
|
+
Sha256::digest(format!("{}\0{}", ctx.user, p.delegation_id).as_bytes())
|
|
43
|
+
);
|
|
44
|
+
let job_id = format!(
|
|
45
|
+
"{:x}-{}",
|
|
46
|
+
Sha256::digest(format!("{}\0{}\0{}", ctx.user, p.delegation_id, p.job_id).as_bytes()),
|
|
47
|
+
&owner[..32]
|
|
48
|
+
);
|
|
49
|
+
let staging = cfg
|
|
50
|
+
.data_dir
|
|
51
|
+
.join("executor-staging")
|
|
52
|
+
.join("owners")
|
|
53
|
+
.join(&owner);
|
|
40
54
|
std::fs::DirBuilder::new()
|
|
41
55
|
.recursive(true)
|
|
42
56
|
.mode(0o700)
|
|
@@ -44,7 +58,8 @@ fn save(cfg: &Config, ctx: &Context, params: &Params) -> Result<Value, Error> {
|
|
|
44
58
|
.map_err(internal)?;
|
|
45
59
|
let name = format!("report-{}.txt", p.job_id);
|
|
46
60
|
let path = staging.join(&name);
|
|
47
|
-
//
|
|
61
|
+
// An admitted or uncertain save retries the original source.
|
|
62
|
+
let mut created = false;
|
|
48
63
|
match OpenOptions::new()
|
|
49
64
|
.write(true)
|
|
50
65
|
.create_new(true)
|
|
@@ -52,6 +67,7 @@ fn save(cfg: &Config, ctx: &Context, params: &Params) -> Result<Value, Error> {
|
|
|
52
67
|
.open(&path)
|
|
53
68
|
{
|
|
54
69
|
Ok(mut file) => {
|
|
70
|
+
created = true;
|
|
55
71
|
let report = format!("Report for {}, {}\n", ctx.user, utc_now());
|
|
56
72
|
file.write_all(report.as_bytes()).map_err(internal)?;
|
|
57
73
|
}
|
|
@@ -59,10 +75,20 @@ fn save(cfg: &Config, ctx: &Context, params: &Params) -> Result<Value, Error> {
|
|
|
59
75
|
Err(e) => return Err(internal(e)),
|
|
60
76
|
}
|
|
61
77
|
let size = std::fs::metadata(&path).map_err(internal)?.len();
|
|
62
|
-
ctx.runtime(
|
|
78
|
+
let result: Result<Value, Error> = ctx.runtime(
|
|
63
79
|
"delegate.move_from_staging",
|
|
64
|
-
&json!({"delegation_id": p.delegation_id, "job_id":
|
|
65
|
-
)
|
|
80
|
+
&json!({"delegation_id": p.delegation_id, "job_id": job_id, "staging": format!("owners/{owner}/{name}"), "name": name, "size": size}),
|
|
81
|
+
);
|
|
82
|
+
// A transport failure may already have been admitted; keep its source.
|
|
83
|
+
if created
|
|
84
|
+
&& result
|
|
85
|
+
.as_ref()
|
|
86
|
+
.err()
|
|
87
|
+
.is_some_and(|e| e.code == "DELEGATION_DENIED")
|
|
88
|
+
{
|
|
89
|
+
std::fs::remove_file(&path).map_err(internal)?;
|
|
90
|
+
}
|
|
91
|
+
result
|
|
66
92
|
}
|
|
67
93
|
|
|
68
94
|
#[cfg(test)]
|
|
@@ -106,11 +132,26 @@ mod tests {
|
|
|
106
132
|
let (_dir, cfg) = setup();
|
|
107
133
|
let reply = save(&cfg, "alice", &moved());
|
|
108
134
|
assert_eq!(reply.data, json!({"state": "queued"}));
|
|
109
|
-
let path = cfg
|
|
135
|
+
let path = cfg
|
|
136
|
+
.data_dir
|
|
137
|
+
.join("executor-staging")
|
|
138
|
+
.join(reply.services[0].1["staging"].as_str().unwrap());
|
|
110
139
|
assert!(std::fs::read_to_string(&path).unwrap().contains("alice"));
|
|
111
140
|
let meta = std::fs::metadata(&path).unwrap();
|
|
112
141
|
assert_eq!(meta.permissions().mode() & 0o777, 0o600);
|
|
113
|
-
let
|
|
142
|
+
let owner = reply.services[0].1["staging"]
|
|
143
|
+
.as_str()
|
|
144
|
+
.unwrap()
|
|
145
|
+
.split('/')
|
|
146
|
+
.nth(1)
|
|
147
|
+
.unwrap();
|
|
148
|
+
assert!(
|
|
149
|
+
reply.services[0].1["job_id"]
|
|
150
|
+
.as_str()
|
|
151
|
+
.unwrap()
|
|
152
|
+
.ends_with(&format!("-{}", &owner[..32]))
|
|
153
|
+
);
|
|
154
|
+
let params = json!({"delegation_id": "d1", "job_id": reply.services[0].1["job_id"], "staging": reply.services[0].1["staging"], "name": "report-job-1.txt", "size": meta.len()});
|
|
114
155
|
assert_eq!(
|
|
115
156
|
reply.services,
|
|
116
157
|
vec![("delegate.move_from_staging".to_string(), params)]
|
|
@@ -118,29 +159,43 @@ mod tests {
|
|
|
118
159
|
}
|
|
119
160
|
|
|
120
161
|
#[test]
|
|
121
|
-
fn
|
|
162
|
+
fn retries_reuse_only_the_same_owner_and_grant_source() {
|
|
122
163
|
let (_dir, cfg) = setup();
|
|
123
164
|
let first = save(&cfg, "alice", &moved()).services;
|
|
124
|
-
let path = cfg
|
|
165
|
+
let path = cfg
|
|
166
|
+
.data_dir
|
|
167
|
+
.join("executor-staging")
|
|
168
|
+
.join(first[0].1["staging"].as_str().unwrap());
|
|
125
169
|
let report = std::fs::read_to_string(&path).unwrap();
|
|
126
|
-
assert_eq!(save(&cfg, "
|
|
170
|
+
assert_eq!(save(&cfg, "alice", &moved()).services, first);
|
|
171
|
+
let other = save(&cfg, "bob", &moved()).services;
|
|
172
|
+
assert_ne!(other[0].1["staging"], first[0].1["staging"]);
|
|
173
|
+
assert_ne!(other[0].1["job_id"], first[0].1["job_id"]);
|
|
174
|
+
let other_path = cfg
|
|
175
|
+
.data_dir
|
|
176
|
+
.join("executor-staging")
|
|
177
|
+
.join(other[0].1["staging"].as_str().unwrap());
|
|
178
|
+
assert!(std::fs::read_to_string(other_path).unwrap().contains("bob"));
|
|
127
179
|
assert_eq!(std::fs::read_to_string(&path).unwrap(), report);
|
|
128
180
|
}
|
|
129
181
|
|
|
130
182
|
#[test]
|
|
131
|
-
fn
|
|
183
|
+
fn rejection_removes_new_source_but_timeout_keeps_retry() {
|
|
132
184
|
let (_dir, cfg) = setup();
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
Err(Error::new(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
185
|
+
for (code, retained) in [("DELEGATION_DENIED", false), ("EXECUTOR_TIMEOUT", true)] {
|
|
186
|
+
let services: Services = [(
|
|
187
|
+
"delegate.move_from_staging",
|
|
188
|
+
Box::new(move |_: &Value| Err(Error::new(code, "Save failed"))) as _,
|
|
189
|
+
)]
|
|
190
|
+
.into();
|
|
191
|
+
let reply = save(&cfg, "alice", &services);
|
|
192
|
+
assert_eq!(reply.code(), code);
|
|
193
|
+
let path = cfg
|
|
194
|
+
.data_dir
|
|
195
|
+
.join("executor-staging")
|
|
196
|
+
.join(reply.services[0].1["staging"].as_str().unwrap());
|
|
197
|
+
assert_eq!(path.exists(), retained);
|
|
198
|
+
}
|
|
144
199
|
}
|
|
145
200
|
|
|
146
201
|
#[test]
|