@@ -168,35 +168,44 @@ PrepareChildProcess(AllocatorPtr alloc,
168168}
169169
170170static void
171- PrepareChildProcess (PreparedChildProcess &p, const char *plan_name,
171+ PrepareChildProcess (AllocatorPtr alloc, PreparedChildProcess &p,
172+ const char *plan_name,
172173 const Plan &plan,
173- FileDescriptor stderr_fd, SocketDescriptor control_fd)
174+ const TranslateResponse &translation,
175+ FileDescriptor stderr_fd, SocketDescriptor control_fd,
176+ FdHolder &close_fds)
174177{
175178 p.hook_info = plan_name;
176179 p.stderr_fd = p.stdout_fd = stderr_fd;
177180 p.control_fd = control_fd.ToFileDescriptor ();
178181
179- if (!debug_mode) {
180- p.uid_gid .effective_uid = plan.uid ;
181- p.uid_gid .effective_gid = plan.gid ;
182+ if (plan.translate ) {
183+ PrepareChildProcess (alloc, p, translation, close_fds);
184+ } else {
185+ if (!debug_mode) {
186+ p.uid_gid .effective_uid = plan.uid ;
187+ p.uid_gid .effective_gid = plan.gid ;
182188
183- std::copy (plan.groups .begin (), plan.groups .end (),
184- p.uid_gid .supplementary_groups .begin ());
185- }
189+ std::copy (plan.groups .begin (), plan.groups .end (),
190+ p.uid_gid .supplementary_groups .begin ());
191+ }
186192
187- if (!plan.chroot .empty ())
188- p.chroot = plan.chroot .c_str ();
193+ if (!plan.chroot .empty ())
194+ p.chroot = plan.chroot .c_str ();
189195
190- p.umask = plan.umask ;
191- p.rlimits = plan.rlimits ;
192- p.priority = plan.priority ;
193- p.ioprio_idle = plan.ioprio_idle ;
194- p.ns .enable_network = plan.private_network ;
196+ p.umask = plan.umask ;
197+ p.rlimits = plan.rlimits ;
198+ p.priority = plan.priority ;
199+ p.sched_idle = plan.sched_idle ;
200+ p.ioprio_idle = plan.ioprio_idle ;
201+ p.ns .enable_network = plan.private_network ;
195202
196- if (plan.private_tmp )
197- p.ns .mount .mount_tmp_tmpfs = " " ;
203+ if (plan.private_tmp )
204+ p.ns .mount .mount_tmp_tmpfs = " " ;
205+
206+ p.no_new_privs = true ;
207+ }
198208
199- p.no_new_privs = true ;
200209}
201210
202211void
@@ -215,6 +224,22 @@ WorkshopOperator::Start2(std::size_t max_log_buffer,
215224{
216225 assert (!pid);
217226
227+ Allocator alloc;
228+ TranslateResponse translation;
229+ if (plan->translate ) {
230+ const auto translation_socket = workplace.GetTranslationSocket ();
231+ if (translation_socket == nullptr )
232+ throw std::runtime_error{" No 'translation_server' configured" };
233+
234+ translation = co_await
235+ TranslateSpawn (event_loop, alloc,
236+ CreateConnectSocket (translation_socket, SOCK_STREAM),
237+ workplace.GetListenerTag (),
238+ job.plan_name .c_str (),
239+ " " , nullptr ,
240+ job.args );
241+ }
242+
218243 auto &spawn_service = workplace.GetSpawnService ();
219244
220245 co_await CoEnqueueSpawner{spawn_service};
@@ -227,9 +252,12 @@ WorkshopOperator::Start2(std::size_t max_log_buffer,
227252
228253 const auto control_child = InitControl ();
229254
255+ FdHolder close_fds;
230256 PreparedChildProcess p;
231- PrepareChildProcess (p, job.plan_name .c_str (), *plan,
232- stderr_w, control_child);
257+ PrepareChildProcess (alloc, p, job.plan_name .c_str (), *plan,
258+ translation,
259+ stderr_w, control_child,
260+ close_fds);
233261
234262 /* use a per-plan cgroup */
235263
@@ -253,7 +281,7 @@ WorkshopOperator::Start2(std::size_t max_log_buffer,
253281
254282 UniqueFileDescriptor stdout_w;
255283
256- if (!plan->control_channel ) {
284+ if (plan-> translate || !plan->control_channel ) {
257285 /* if there is no control channel, read progress from the
258286 stdout pipe */
259287 UniqueFileDescriptor stdout_r;
@@ -266,27 +294,31 @@ WorkshopOperator::Start2(std::size_t max_log_buffer,
266294 /* build command line */
267295
268296 std::list<std::string> args;
269- args.insert (args.end (), plan->args .begin (), plan->args .end ());
270- args.insert (args.end (), job.args .begin (), job.args .end ());
271297
272- Expand (args);
298+ if (!plan->translate ) {
299+ args.insert (args.end (), plan->args .begin (), plan->args .end ());
300+ args.insert (args.end (), job.args .begin (), job.args .end ());
273301
274- for (const auto &i : args) {
275- if (p.args .size () >= 4096 )
276- throw std::runtime_error (" Too many command-line arguments" );
302+ Expand (args);
277303
278- p.args .push_back (i.c_str ());
279- }
304+ for (const auto &i : args) {
305+ if (p.args .size () >= 4096 )
306+ throw std::runtime_error (" Too many command-line arguments" );
307+
308+ p.args .push_back (i.c_str ());
309+ }
280310
281- for (const auto &i : job.env ) {
282- if (p.env .size () >= 64 )
283- throw std::runtime_error (" Too many environment variables" );
311+ // TODO do we want to allow job.env for "translate" plans?
312+ for (const auto &i : job.env ) {
313+ if (p.env .size () >= 64 )
314+ throw std::runtime_error (" Too many environment variables" );
284315
285- if (StringStartsWith (i.c_str (), " LD_" ))
286- /* reject - too dangerous */
287- continue ;
316+ if (StringStartsWith (i.c_str (), " LD_" ))
317+ /* reject - too dangerous */
318+ continue ;
288319
289- p.env .push_back (i.c_str ());
320+ p.env .push_back (i.c_str ());
321+ }
290322 }
291323
292324 /* fork */
@@ -558,7 +590,8 @@ WorkshopOperator::OnControlSpawn(const char *token, const char *param)
558590 CreateConnectSocket (translation_socket, SOCK_STREAM),
559591 workplace.GetListenerTag (),
560592 job.plan_name .c_str (),
561- token, param);
593+ token, param,
594+ {});
562595
563596 auto &spawn_service = workplace.GetSpawnService ();
564597
0 commit comments