{"id":672,"date":"2014-03-29T13:14:08","date_gmt":"2014-03-29T12:14:08","guid":{"rendered":"http:\/\/katastrophos.net\/andre\/blog\/?p=672"},"modified":"2015-09-26T12:50:43","modified_gmt":"2015-09-26T10:50:43","slug":"running-sailfishos-build-engine-outside-virtualbox-vm","status":"publish","type":"post","link":"https:\/\/katastrophos.net\/andre\/blog\/2014\/03\/29\/running-sailfishos-build-engine-outside-virtualbox-vm\/","title":{"rendered":"Running the SailfishOS Build engine outside of a VirtualBox VM"},"content":{"rendered":"<p>I have been struggling with the SailfishOS Build Engine VM for quite some time. 4 out of 5 SailfishOS builds of QuasarMX would fail because the Shared Folder (vboxsf) mechanism in VirtualBox at some point starts to corrupt files on my system, even though the system&#8217;s RAM and storage are perfectly fine. Since QuasarMX heavily relies on qmlpp (see <a href=\"http:\/\/katastrophos.net\/andre\/blog\/2013\/09\/20\/qml-preprocessor-the-qnd-and-kiss-way\/\" target=\"_blank\">previous post<\/a>) to work with QtQuick 2, a lot of files will be touched during compilation. For this, vboxsf is both unreliable and slow (!).<\/p>\n<p>So, here is a short tutorial that will show how to run the SailfishOS Build engine outside of the VirtualBox VM in your host&#8217;s Linux installation. This guide is geared towards Ubuntu 12.04, but might work on other systems too.<\/p>\n<p>UPDATE 1: New version with root check, private namespace and permission fixes in SB2 targets.<br \/>\nUPDATE 2: The tutorial has been updated to work with SDK Alpha-1404 (Alpha 4). This new version does not work with Alpha-1312 (Alpha 3).<br \/>\n<strong>UPDATE 3: This method is working with SDK Beta-1509.<\/strong><\/p>\n<p>Start the Build engine VM and make sure you can connect to it via SSH (see <a href=\"https:\/\/sailfishos.org\/develop-faq.html\" target=\"_blank\">Developer FAQ<\/a> for details):<br \/>\n$SUDO_USER is the username you used to sudo into root privileges, change it if you have not used sudo to become root.<\/p>\n<pre name=\"code\" class=\"bash:nocontrols\">\r\nssh -p 2222 -i \/home\/$SUDO_USER\/SailfishOS\/vmshare\/ssh\/private_keys\/engine\/root root@localhost\r\n<\/pre>\n<p>If it works:<\/p>\n<pre name=\"code\" class=\"bash:nocontrols\">\r\nexit\r\n<\/pre>\n<p>Now, become root:<\/p>\n<pre name=\"code\" class=\"bash:nocontrols\">\r\nsudo -i\r\n<\/pre>\n<p>Create a directory to host the rootfs of the SailfishOS Build engine:<\/p>\n<pre name=\"code\" class=\"bash:nocontrols\">\r\nmkdir \/opt\/sailfishos-buildengine\r\n<\/pre>\n<p>Use rsync to copy the rootfs to our newly created directory:<\/p>\n<pre name=\"code\" class=\"bash:nocontrols\">\r\nrsync --numeric-ids -xazuv -e \"ssh -p 2222 -i \/home\/$SUDO_USER\/SailfishOS\/vmshare\/ssh\/private_keys\/engine\/root\" root@localhost:\/ \/opt\/sailfishos-buildengine\r\n<\/pre>\n<p>This will take a while. Go, have dinner or get a cup of tea.<\/p>\n<p>Save the following script as file &#8220;run-sailfishos-buildengine.sh&#8221; somewhere you like. We&#8217;ll use \/opt\/run-sailfishos-buildengine.sh<br \/>\nMake sure to edit the first few lines to match your environment, SDK=\/opt\/SailfishOS is the directory you used to install the Sailfish SDK on your host. This probably is \/home\/YOURUSERNAME\/SailfishOS if you haven&#8217;t installed as root.<\/p>\n<pre name=\"code\" class=\"bash\">\r\n#!\/bin\/bash\r\nUSER=$SUDO_USER\r\nUSERDIR=\/home\/$USER\r\nSDK=\/opt\/SailfishOS\r\nBUILDENGINE=\/opt\/sailfishos-buildengine\r\n\r\nif [ $EUID -ne 0 ]; then\r\n\techo &#x22;This script must be run as root.&#x22; 1&#x3E;&#x26;2\r\n\texit 1\r\nfi\r\n\r\nif cmp -s \/proc\/$PPID\/mountinfo \/proc\/self\/mountinfo; then\r\n\texec unshare -m -- &#x22;$0&#x22; &#x22;$@&#x22;\r\n\techo &#x22;$0 must be run in private namespace.&#x22;\r\n\texit 1\r\nfi\r\n\t\t\r\ncleanup()\r\n{\r\n\tumount -l $BUILDENGINE\/dev\/pts\r\n\tumount -l $BUILDENGINE\/dev\r\n\tumount -l $BUILDENGINE\/proc\r\n\tumount -l $BUILDENGINE\/sys\r\n\tumount -l $BUILDENGINE\/run\r\n\r\n\tumount -l $BUILDENGINE\/home\/mersdk\/share\t\r\n\tumount -l $BUILDENGINE\/home\/src1\r\n\tumount -l $BUILDENGINE\/etc\/ssh\/authorized_keys\r\n\tumount -l $BUILDENGINE\/host_targets\r\n\tumount -l $BUILDENGINE\/etc\/mersdk\/share\r\n}\r\n\r\ntrap &#x22;cleanup &#x3E; \/dev\/null 2&#x3E;&#x26;1; exit&#x22; INT QUIT TERM EXIT\r\n\r\nmount --make-slave &#x22;$(df -P &#x22;$BUILDENGINE&#x22; | tail -1 | awk &#x27;{print $NF}&#x27;)&#x22;\r\n\r\nmount --bind \/dev &#x22;$BUILDENGINE\/dev&#x22;\r\nmount --bind \/dev\/pts &#x22;$BUILDENGINE\/dev\/pts&#x22;\r\nmount --bind \/proc &#x22;$BUILDENGINE\/proc&#x22;\r\nmount --bind \/sys &#x22;$BUILDENGINE\/sys&#x22;\r\nmount --bind \/run &#x22;$BUILDENGINE\/run&#x22;\r\n\r\nmount --bind &#x22;$USERDIR&#x22; &#x22;$BUILDENGINE\/home\/mersdk\/share&#x22;\r\nmount --bind &#x22;$USERDIR&#x22; &#x22;$BUILDENGINE\/home\/src1&#x22;\r\nmount --bind &#x22;$SDK\/mersdk\/ssh&#x22; &#x22;$BUILDENGINE\/etc\/ssh\/authorized_keys&#x22;\r\nmount --bind &#x22;$SDK\/mersdk\/targets&#x22; &#x22;$BUILDENGINE\/host_targets&#x22;\r\nmount --bind &#x22;$SDK\/vmshare&#x22; &#x22;$BUILDENGINE\/etc\/mersdk\/share&#x22;\r\n\r\n# Rewrite user id and group id entries to match host system&#x27;s users\r\nupdateConfigs()\r\n{\r\n\tsed -i -e &#x22;s\/$1:x:$2:100000:\/$1:x:$(id -u $USER):$(id -g $USER):\/&#x22; &#x22;$3\/passwd&#x22;\r\n\tsed -i -e &#x22;s\/$1:x:100000:\/$1:x:$(id -g $USER):\/&#x22; &#x22;$3\/group&#x22;\r\n\tcp \/etc\/resolv.conf &#x22;$3\/&#x22;\r\n}\r\n\r\nupdateConfigs mersdk 1001 &#x22;$BUILDENGINE\/etc&#x22;\r\nupdateConfigs nemo 100000 &#x22;$BUILDENGINE\/srv\/mer\/targets\/SailfishOS-armv7hl\/etc&#x22;\r\nupdateConfigs nemo 100000 &#x22;$BUILDENGINE\/srv\/mer\/targets\/SailfishOS-i486\/etc&#x22;\r\n\r\ncat &#x3E; &#x22;$BUILDENGINE\/runmersdkengine.sh&#x22; &#x3C;&#x3C; CONTENT\r\n#!\/bin\/bash\r\n\r\ncleanup()\r\n{\r\n\tpkill -KILL -f &#x22;\/usr\/bin\/ruby \/usr\/bin\/puma -p 8080 -t 1:1 -e production&#x22;\r\n}\r\ntrap &#x22;cleanup; exit&#x22; INT QUIT TERM EXIT\r\n\r\n# Fix up permissions to point to new uid\/gid of mersdk\r\nmkdir -p \/home\/deploy\/installroot\r\nchown -R mersdk.mersdk \/home\/deploy\/installroot\r\nchown -R mersdk.mersdk \/srv\/mer\/targets\/*\r\nfind \/home\/mersdk | grep -v &#x22;\/home\/mersdk\/share&#x22; | xargs chown mersdk.mersdk\r\n\r\n# Run web server of build engine as mersdk in background:\r\nsu mersdk -c &#x22;cd \/usr\/lib\/sdk-webapp-bundle; \/usr\/bin\/ruby \/usr\/bin\/puma -p 8080 -t 1:1 -e production&#x22; &#x26;\r\n\r\n# Run SSH Server of build engine as root:\r\n\/usr\/sbin\/sshd -p 2222 -D -e -f \/etc\/ssh\/sshd_config_engine\r\nCONTENT\r\n\r\nchroot &#x22;$BUILDENGINE&#x22; sh \/runmersdkengine.sh \r\n<\/pre>\n<p>Don&#8217;t forget to <\/p>\n<pre name=\"code\" class=\"bash:nocontrols\">\r\nchmod 755 \/opt\/run-sailfishos-buildengine.sh\r\n<\/pre>\n<p>Now exit the root shell and run:<\/p>\n<pre name=\"code\" class=\"bash:nocontrols\">\r\nsudo \/opt\/run-sailfishos-buildengine.sh\r\n<\/pre>\n<p>This will start the Open SSH server and the build engine&#8217;s web server which is used in the modified Qt Creator of the SailfishOS SDK.<br \/>\nPress CTRL+C to terminate the engine at any time.<\/p>\n<p>Qt Creator will complain that the VM is not started and offers to start the VM for you. Just click No and ignore it. The build is already running in the background.<\/p>\n<p>Enjoy your fast builds!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have been struggling with the SailfishOS Build Engine VM for quite some time. 4 out of 5 SailfishOS builds of QuasarMX would fail because the Shared Folder (vboxsf) mechanism in VirtualBox at some point starts to corrupt files on my system, even though the system&#8217;s RAM and storage are perfectly fine. Since QuasarMX heavily [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-672","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/katastrophos.net\/andre\/blog\/wp-json\/wp\/v2\/posts\/672"}],"collection":[{"href":"https:\/\/katastrophos.net\/andre\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/katastrophos.net\/andre\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/katastrophos.net\/andre\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/katastrophos.net\/andre\/blog\/wp-json\/wp\/v2\/comments?post=672"}],"version-history":[{"count":32,"href":"https:\/\/katastrophos.net\/andre\/blog\/wp-json\/wp\/v2\/posts\/672\/revisions"}],"predecessor-version":[{"id":686,"href":"https:\/\/katastrophos.net\/andre\/blog\/wp-json\/wp\/v2\/posts\/672\/revisions\/686"}],"wp:attachment":[{"href":"https:\/\/katastrophos.net\/andre\/blog\/wp-json\/wp\/v2\/media?parent=672"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/katastrophos.net\/andre\/blog\/wp-json\/wp\/v2\/categories?post=672"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/katastrophos.net\/andre\/blog\/wp-json\/wp\/v2\/tags?post=672"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}