4 Replies
      Latest reply on Feb 2, 2020 7:20 PM by hbanko
      hbanko Level 1 Level 1 (0 points)

        Hi,

         

        I am working on a little menu bar app to lauch VMs headless in VirtualBox. For that I am using VBoxManage to generate a list of available VMs. This works flawlessly in a "command line project" but not in an "App project" with the sandbox in place.

         

        I have learned about entitlements (thanks Quinn!) and I am now able to execute VBoxManage with active Sandbox but I am not getting the output of it? Any an idea how to solve this? Below the code I am using that works perfectly without Sandbox:

        func list_vms() -> String {
          
            let task = Process()
            task.executableURL = URL(fileURLWithPath: "/usr/local/bin/VBoxManage")
            let option = "list"
            let command = "vms"
            task.arguments = [option, command]
            let outputPipe = Pipe()
            let errorPipe = Pipe()
        
            task.standardOutput = outputPipe
            task.standardError = errorPipe
            do {
                try task.run()
                } catch {
                    print("Error launching VBoxManage")
            }
            let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile()
            let output = String(decoding: outputData, as: UTF8.self)
           
            // let errorData = errorPipe.fileHandleForReading.readDataToEndOfFile()
            // let error = String(decoding: errorData, as: UTF8.self)
        
            return output
        }
        
        

        I have also added an entitlement:

         

        com.apple.security.temporary-exception.files.absolute-path.read-only for /usr/local/bin/

         

        As soon as I remove the Sandbox entirely things start to work like in the command line project. I am kind of clueless why the output of VBoxManage is not getting passed on?

        • Re: Shell Script output missing after called by process()
          eskimo Apple Staff Apple Staff (13,125 points)

          I am not getting the output of it?

          Are you sure that the tool is generating output in this case?  The code you posted is ignoring stderr.  If the tool is failing, and thus printing an error message to stderr rather than its normal output to stdout, you’d see exactly this behaviour.

          And failure is definitely a possibility here.  Remember that when a sandboxed process starts a child process, which is what Process is doing here, the child process inherits the parent’s sandbox.  I very much doubt that VBoxManage is expecting to be run inside a sandbox.

          One way to debug this is to skip all the code that sets up standardOutput and standardError.  The tool will then inherit stdot and stderr from the app.  If you run the app from Xcode, those are connected to Xcode’s Console pane.  You’ll then be able to see exactly what the tool is printing.

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

            • Re: Shell Script output missing after called by process()
              hbanko Level 1 Level 1 (0 points)

              Hi Quinn,


              Yes you are right. Doing that I am getting error below:

               

              VBoxManage: error: Failed to create the VirtualBox object!
              VBoxManage: error: Code NS_ERROR_SOCKET_FAIL (0xC1F30200) - IPC daemon socket error (extended info not available)
              VBoxManage: error: Most likely, the VirtualBox COM server is not running or failed to start.

               

              I probably go without Sandbox. I sense it will be way too much effort to get around this looking at the (tiny) scope of the whole project. Just sad that it won't be able to go in the app store.

               

              .. and greeting from Down Under (Sydney)!

                • Re: Shell Script output missing after called by process()
                  john daniel Level 4 Level 4 (600 points)

                  Where is the VirtualBox server listening? It isn't that hard to get out of the sandbox. If the server is listening on TCP over localhost, all you need is network client entitlement. For locating the VBoxManage tool, you can just provide an interface for the user to select it. You can do the same if the server is listening on a UNIX socket.

                   

                  It looks like VBoxManage can run over a network to remote Virtual Box servers over TCP port 3389. You should be able to make that work. For App Review, you will probably have to setup a private, remove Virtual Box server that they can test with, but that shouldn't be too difficult.

                   

                  On second though, do some research on the Virtual Box protocol. You should be able to do what you need without VBoxManage. Here is a (Python) project that connects to Virtual Box remotely (github.com/ilyaglow/remote-virtualbox). Supposedly it is SOAP. SOAP won't win you any friends or developer street cred, but it is relatively straightforward. It's all XML. Now you can get your app into the iOS App Store.