@@ -141,6 +141,111 @@ func TestRuntime(t *testing.T) {
141141 require .FileExists (t , pidFile )
142142 assertFileContent (t , pidFile , fmt .Sprintf ("%d" , pid ))
143143 })
144+
145+ t .Run ("proxy process creates new process" , func (t * testing.T ) {
146+ t .Run ("in requested namespace when root" , func (t * testing.T ) {
147+ remoteprocName := "lovely-blue-device"
148+ sim := remoteproc .NewSimulator (rootpathPrefix ).WithName (remoteprocName )
149+ if err := sim .Start (); err != nil {
150+ t .Fatalf ("failed to run simulator: %s" , err )
151+ }
152+ defer func () { _ = sim .Stop () }()
153+
154+ uniqueID := testID (t )
155+ containerName := uniqueID
156+ bundlePath := filepath .Join (dirMountedInVM , uniqueID )
157+ require .NoError (t , generateBundle (
158+ bundlePath ,
159+ remoteprocName ,
160+ specs.LinuxNamespace {Type : specs .MountNamespace },
161+ ))
162+ _ , stderr , err := vm .RunCommand ("sudo" , installedRuntime .String (),
163+ "create" , "--bundle" , bundlePath ,
164+ containerName )
165+ require .NoError (t , err , "stderr: %s" , stderr )
166+ t .Cleanup (func () {
167+ _ , _ , _ = vm .RunCommand ("sudo" , "remoteproc-runtime" , "delete" , containerName )
168+ })
169+
170+ pid , err := checkContainerRunning (func () (specs.State , error ) {
171+ stdout , stderr , err := vm .RunCommand ("sudo" , "remoteproc-runtime" , "state" , containerName )
172+ if err != nil {
173+ return specs.State {}, fmt .Errorf ("stderr: %s: %w" , stderr , err )
174+ }
175+ var state specs.State
176+ if err := json .Unmarshal ([]byte (stdout ), & state ); err != nil {
177+ return specs.State {}, err
178+ }
179+ return state , nil
180+ })
181+ require .NoError (t , err )
182+
183+ hostMountNS , stderr , err := vm .RunCommand ("readlink" , "/proc/self/ns/mnt" )
184+ require .NoError (t , err , "stderr: %s" , stderr )
185+
186+ proxyMountNS , stderr , err := vm .RunCommand ("sudo" , "readlink" , fmt .Sprintf ("/proc/%d/ns/mnt" , pid ))
187+ require .NoError (t , err , "stderr: %s" , stderr )
188+ assert .NotEqual (t , strings .TrimSpace (hostMountNS ), strings .TrimSpace (proxyMountNS ))
189+
190+ remoteproc .AssertState (t , sim .DeviceDir (), "offline" )
191+
192+ _ , stderr , err = vm .RunCommand ("sudo" , "remoteproc-runtime" , "start" , containerName )
193+ require .NoError (t , err , "stderr: %s" , stderr )
194+ remoteproc .AssertState (t , sim .DeviceDir (), "running" )
195+ })
196+
197+ t .Run ("in user's namespace when not root" , func (t * testing.T ) {
198+ remoteprocName := "lovely-blue-device"
199+ sim := remoteproc .NewSimulator (rootpathPrefix ).WithName (remoteprocName )
200+ if err := sim .Start (); err != nil {
201+ t .Fatalf ("failed to run simulator: %s" , err )
202+ }
203+ defer func () { _ = sim .Stop () }()
204+
205+ uniqueID := testID (t )
206+ containerName := uniqueID
207+ bundlePath := filepath .Join (dirMountedInVM , uniqueID )
208+ require .NoError (t , generateBundle (
209+ bundlePath ,
210+ remoteprocName ,
211+ specs.LinuxNamespace {Type : specs .MountNamespace },
212+ ))
213+ _ , stderr , err := vm .RunCommand (installedRuntime .String (),
214+ "create" , "--bundle" , bundlePath ,
215+ containerName )
216+ require .NoError (t , err , "stderr: %s" , stderr )
217+ t .Cleanup (func () {
218+ _ , _ , _ = vm .RunCommand ("sudo" , "remoteproc-runtime" , "delete" , containerName )
219+ })
220+
221+ pid , err := checkContainerRunning (func () (specs.State , error ) {
222+ stdout , stderr , err := vm .RunCommand ("sudo" , "remoteproc-runtime" , "state" , containerName )
223+ if err != nil {
224+ return specs.State {}, fmt .Errorf ("stderr: %s: %w" , stderr , err )
225+ }
226+ var state specs.State
227+ if err := json .Unmarshal ([]byte (stdout ), & state ); err != nil {
228+ return specs.State {}, err
229+ }
230+ return state , nil
231+ })
232+ require .NoError (t , err )
233+
234+ hostMountNS , stderr , err := vm .RunCommand ("readlink" , "/proc/self/ns/mnt" )
235+ require .NoError (t , err , "stderr: %s" , stderr )
236+
237+ proxyMountNS , stderr , err := vm .RunCommand ("sudo" , "readlink" , fmt .Sprintf ("/proc/%d/ns/mnt" , pid ))
238+ require .NoError (t , err , "stderr: %s" , stderr )
239+ assert .Equal (t , strings .TrimSpace (hostMountNS ), strings .TrimSpace (proxyMountNS ))
240+
241+ remoteproc .AssertState (t , sim .DeviceDir (), "offline" )
242+
243+ _ , stderr , err = vm .RunCommand ("sudo" , "remoteproc-runtime" , "start" , containerName )
244+ require .NoError (t , err , "stderr: %s" , stderr )
245+ remoteproc .AssertState (t , sim .DeviceDir (), "running" )
246+ })
247+
248+ })
144249}
145250
146251func testID (t testing.TB ) string {
@@ -150,130 +255,6 @@ func testID(t testing.TB) string {
150255 return name
151256}
152257
153- func TestRuntimeProxyKeepsHostNamespaceWhenNotRoot (t * testing.T ) {
154- rootDir := t .TempDir ()
155- remoteprocName := "a-lovely-blue-device"
156-
157- runtimeBin , err := repo .BuildRuntimeBin (t .TempDir (), rootDir , limavm .BinBuildEnv )
158- require .NoError (t , err )
159-
160- vm , err := limavm .NewDebian (rootDir )
161- require .NoError (t , err )
162- t .Cleanup (vm .Cleanup )
163-
164- installedRuntime , err := vm .InstallBin (runtimeBin )
165- require .NoError (t , err )
166-
167- sim := remoteproc .NewSimulator (rootDir ).WithName (remoteprocName )
168- if err := sim .Start (); err != nil {
169- t .Fatalf ("failed to run simulator: %s" , err )
170- }
171- t .Cleanup (func () { _ = sim .Stop () })
172-
173- const containerName = "not-root-namespace-container"
174- bundlePath := filepath .Join (rootDir , "not-root-namespace-bundle" )
175- require .NoError (t , generateBundle (
176- bundlePath ,
177- remoteprocName ,
178- specs.LinuxNamespace {Type : specs .MountNamespace },
179- ))
180-
181- _ , stderr , err := installedRuntime .Run (
182- "create" , "--bundle" , bundlePath ,
183- containerName ,
184- )
185- require .NoError (t , err , "stderr: %s" , stderr )
186- t .Cleanup (func () {
187- _ , _ , _ = installedRuntime .Run ("delete" , containerName )
188- })
189-
190- pid , err := checkContainerRunning (func () (specs.State , error ) {
191- stdout , stderr , err := installedRuntime .Run ("state" , containerName )
192- if err != nil {
193- return specs.State {}, fmt .Errorf ("stderr: %s: %w" , stderr , err )
194- }
195- var state specs.State
196- if err := json .Unmarshal ([]byte (stdout ), & state ); err != nil {
197- return specs.State {}, err
198- }
199- return state , nil
200- })
201- require .NoError (t , err )
202-
203- hostMountNS , stderr , err := vm .RunCommand ("readlink" , "/proc/self/ns/mnt" )
204- require .NoError (t , err , "stderr: %s" , stderr )
205-
206- proxyMountNS , stderr , err := vm .RunCommand ("readlink" , fmt .Sprintf ("/proc/%d/ns/mnt" , pid ))
207- require .NoError (t , err , "stderr: %s" , stderr )
208-
209- assert .Equal (t , strings .TrimSpace (hostMountNS ), strings .TrimSpace (proxyMountNS ))
210- }
211-
212- func TestRuntimeProxyKeepsHostNamespaceWhenRootInLimaVM (t * testing.T ) {
213- rootDir := t .TempDir ()
214- remoteprocName := "a-lovely-blue-device"
215-
216- runtimeBin , err := repo .BuildRuntimeBin (t .TempDir (), rootDir , limavm .BinBuildEnv )
217- require .NoError (t , err )
218-
219- vm , err := limavm .NewDebian (rootDir )
220- require .NoError (t , err )
221- t .Cleanup (vm .Cleanup )
222-
223- _ , err = vm .InstallBin (runtimeBin )
224- require .NoError (t , err )
225-
226- sim := remoteproc .NewSimulator (rootDir ).WithName (remoteprocName )
227- if err := sim .Start (); err != nil {
228- t .Fatalf ("failed to run simulator: %s" , err )
229- }
230- t .Cleanup (func () { _ = sim .Stop () })
231-
232- const containerName = "root-namespace-container"
233- bundlePath := filepath .Join (rootDir , "root-namespace-bundle" )
234- require .NoError (t , generateBundle (
235- bundlePath ,
236- remoteprocName ,
237- specs.LinuxNamespace {Type : specs .MountNamespace },
238- ))
239-
240- _ , stderr , err := vm .RunCommand (
241- "sudo" , "remoteproc-runtime" ,
242- "create" , "--bundle" , bundlePath ,
243- containerName ,
244- )
245- require .NoError (t , err , "stderr: %s" , stderr )
246- t .Cleanup (func () {
247- _ , _ , _ = vm .RunCommand ("sudo" , "remoteproc-runtime" , "delete" , containerName )
248- })
249-
250- pid , err := checkContainerRunning (func () (specs.State , error ) {
251- stdout , stderr , err := vm .RunCommand ("sudo" , "remoteproc-runtime" , "state" , containerName )
252- if err != nil {
253- return specs.State {}, fmt .Errorf ("stderr: %s: %w" , stderr , err )
254- }
255- var state specs.State
256- if err := json .Unmarshal ([]byte (stdout ), & state ); err != nil {
257- return specs.State {}, err
258- }
259- return state , nil
260- })
261- require .NoError (t , err )
262-
263- hostMountNS , stderr , err := vm .RunCommand ("readlink" , "/proc/self/ns/mnt" )
264- require .NoError (t , err , "stderr: %s" , stderr )
265-
266- proxyMountNS , stderr , err := vm .RunCommand ("sudo" , "readlink" , fmt .Sprintf ("/proc/%d/ns/mnt" , pid ))
267- require .NoError (t , err , "stderr: %s" , stderr )
268- assert .NotEqual (t , strings .TrimSpace (hostMountNS ), strings .TrimSpace (proxyMountNS ))
269-
270- remoteproc .AssertState (t , sim .DeviceDir (), "offline" )
271-
272- _ , stderr , err = vm .RunCommand ("sudo" , "remoteproc-runtime" , "start" , containerName )
273- require .NoError (t , err , "stderr: %s" , stderr )
274- remoteproc .AssertState (t , sim .DeviceDir (), "running" )
275- }
276-
277258func assertContainerStatus (t testing.TB , runtime limavm.InstalledBin , containerName string , wantStatus specs.ContainerState ) {
278259 t .Helper ()
279260 state , err := getContainerState (runtime , containerName )
0 commit comments