Summary: Just run cgexec to start the process. Note that cgexec **exec()**s the desired program. It doesn't fork() and run it in the background.
TL;DR;
I'm speaking from relative ignorance here - I've got the same problem and am in the process of working out how to do it. However, I think that the solution is pretty clear. Here's my analysis:
From looking at cgexec's source in cgexec.c, you can see that main() does three things:
- The usual parameter parsing.
- Does <stuff> to find or create the appropriate cgroup environment. (No, I don't understand the particulars of this, but I don't think that it matters.)
- At the end, it just calls execvp(). It does not fork().
Remember that cgexec is a binary. It is not a library.
My take on this is that the binary puts itself in the requested cgroup environment and then execs the requested program.
To do this purely in golang, you'd have to start a new process and then exec the binary inside that - which is exactly the same thing that cgexec does. There's no easy/straightforward way to do that by writing golang code within your program. You do not want to fork inside a golang program!
Since you're going to have to fork/exec something, you may as well just use os.StartProcess or os/exec.Command(...).Run() to run cgexec. It's completely safe and you're guaranteed to get the same hopefully well-known semantics as cgexec.