Merge lp:~ted/ubuntu-app-launch/install-root into lp:ubuntu-app-launch

Proposed by Ted Gould
Status: Merged
Approved by: Ted Gould
Approved revision: 328
Merged at revision: 282
Proposed branch: lp:~ted/ubuntu-app-launch/install-root
Merge into: lp:ubuntu-app-launch
Prerequisite: lp:~ted/ubuntu-app-launch/jobs-systemd
Diff against target: 869 lines (+598/-20)
21 files modified
CMakeLists.txt (+25/-0)
debian/ubuntu-app-launch.install (+1/-0)
docs/index.rst (+50/-0)
libubuntu-app-launch/application-impl-legacy.cpp (+23/-8)
libubuntu-app-launch/application-impl-snap.cpp (+3/-1)
libubuntu-app-launch/jobs-systemd.cpp (+48/-3)
libubuntu-app-launch/registry-impl.cpp (+11/-0)
libubuntu-app-launch/registry-impl.h (+8/-0)
libubuntu-app-launch/ubuntu-app-launch.cpp (+5/-1)
snappy-xmir-envvars.c (+112/-0)
snappy-xmir.c (+212/-0)
tests/CMakeLists.txt (+5/-0)
tests/snappy-xmir-test-check.sh (+32/-0)
tests/snappy-xmir-test-helper-long.sh (+12/-0)
tests/snappy-xmir-test-helper.sh (+12/-0)
tests/snappy-xmir-test-libertine-launch.sh (+5/-0)
tests/snappy-xmir-test.sh.in (+30/-0)
upstart-jobs/application-click.conf.in (+0/-1)
upstart-jobs/application-snap.conf.in (+0/-1)
upstart-jobs/untrusted-helper.conf.in (+0/-1)
xmir-helper.c (+4/-4)
To merge this branch: bzr merge lp:~ted/ubuntu-app-launch/install-root
Reviewer Review Type Date Requested Status
Charles Kerr (community) Approve
unity-api-1-bot continuous-integration Needs Fixing
dobey Pending
Ted Gould Pending
Marcus Tomlinson Pending
Review via email: mp+316036@code.launchpad.net

Commit message

Adjust UAL for working inside a snap

Description of the change

This branch is various changes that make it so that UAL works well inside the Unity8 Session Snap.

The majority of the changes are basically adjustments to the environment variables and other tweaks to the various calls to look for the SNAP environment variable and change how UAL behaves in those cases. There are also some cases where variables have been removed as they were determined to not be needed when testing in the unity8-session snap.

A bigger change that exists in this branch is the addition of the snappy helpers for setting up xmir. This works a little bit different in that it gives a small utility to the XMir setup functions that then sends the environment over a socket to the helper. This allows us to go in and out of the snap confinement for X11. These utilities are written in conservative low-level C to ensure they'll work on ubuntu-core with a minimal set of libraries.

To post a comment you must log in.
Revision history for this message
Ted Gould (ted) wrote :

Resubmitted this with a better description of what the branch actually does today.

Revision history for this message
Ted Gould (ted) wrote :

Resubmitted this with a better description of what the branch actually does today.

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:316
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/192/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/1575
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1582
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1360
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1360/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1360
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1360/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1360
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1360/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1360
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1360/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1360
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1360/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1360
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1360/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/192/rebuild

review: Approve (continuous-integration)
Revision history for this message
Charles Kerr (charlesk) wrote :

Mostly looks good. A handful of little tweaks + one more serious issue w/easy fix. Comments inline.

review: Needs Fixing
Revision history for this message
Ted Gould (ted) :
317. By Ted Gould

Fix docs to include default path for LEGACY_EXEC

318. By Ted Gould

Cache snap env var

319. By Ted Gould

Make sure we only use references in loops

320. By Ted Gould

Don't store if we have the variable

321. By Ted Gould

Return const pointer

322. By Ted Gould

Handle larger possible pids

323. By Ted Gould

Make sure we're gettin' data

324. By Ted Gould

Move debug outside of the print loop

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

FAILED: Continuous integration, rev:324
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/193/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/1576/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1583
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1361
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1361/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1361
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1361/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1361/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1361
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1361/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1361
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1361/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1361
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1361/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/193/rebuild

review: Needs Fixing (continuous-integration)
325. By Ted Gould

A read failure is a helper failure

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

FAILED: Continuous integration, rev:325
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/196/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/1583/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/1590
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1368
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/1368/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=zesty/1368/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1368
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/1368/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1368
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=zesty/1368/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1368
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/1368/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1368
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=zesty/1368/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-ubuntu-app-launch-ci/196/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Charles Kerr (charlesk) wrote :

Approving these changes, feel free to top-approve when Jenkins is happy or if the Jenkins failure is a red herring

review: Approve
326. By Ted Gould

If we don't have a MIR_SOCKET use the default one

327. By Ted Gould

Special case legacy apps on Unity8 from debs

328. By Ted Gould

Put on the dunce cap and sit in the corner

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2017-01-23 21:32:16 +0000
3+++ CMakeLists.txt 2017-02-02 15:08:16 +0000
4@@ -111,6 +111,7 @@
5 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
6
7 add_definitions( -DXMIR_HELPER="${pkglibexecdir}/xmir-helper" )
8+add_definitions( -DSNAPPY_XMIR="${CMAKE_INSTALL_FULL_BINDIR}/snappy-xmir" )
9
10 ####################
11 # Helpers
12@@ -210,6 +211,30 @@
13 install(TARGETS socket-demangler-helper RUNTIME DESTINATION "${pkglibexecdir}")
14
15 ####################
16+# snappy-xmir
17+####################
18+
19+####################
20+# NOTE: This only can link to libraries that are in
21+# the base UBUNTU CORE image. Which is basically libc
22+# and not much else. Don't add libs.
23+####################
24+
25+add_executable(snappy-xmir snappy-xmir.c)
26+set_target_properties(snappy-xmir PROPERTIES OUTPUT_NAME "snappy-xmir")
27+install(TARGETS snappy-xmir RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
28+
29+####################
30+# snappy-xmir-envvars
31+####################
32+
33+add_executable(snappy-xmir-envvars snappy-xmir-envvars.c)
34+set_target_properties(snappy-xmir-envvars PROPERTIES OUTPUT_NAME "snappy-xmir-envvars")
35+# No libs, otherwise we have to worry about how to handle finding them
36+install(TARGETS snappy-xmir-envvars RUNTIME DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}")
37+
38+
39+####################
40 # ubuntu-app-launch-desktop.click-hook
41 ####################
42
43
44=== modified file 'debian/ubuntu-app-launch.install'
45--- debian/ubuntu-app-launch.install 2014-04-30 15:14:26 +0000
46+++ debian/ubuntu-app-launch.install 2017-02-02 15:08:16 +0000
47@@ -1,2 +1,3 @@
48 usr/share/upstart/sessions/*
49 usr/lib/*/ubuntu-app-launch/*
50+usr/bin/snappy-xmir*
51
52=== modified file 'docs/index.rst'
53--- docs/index.rst 2016-09-30 20:46:07 +0000
54+++ docs/index.rst 2017-02-02 15:08:16 +0000
55@@ -18,6 +18,56 @@
56
57 .. _Upstart: http://upstart.ubuntu.com/
58
59+
60+Environment Variables
61+=====================
62+
63+There are a few environment variables that can effect the behavior of UAL while
64+it is running.
65+
66+UBUNTU_APP_LAUNCH_CG_MANAGER_NAME
67+ The DBus name that CG Manager registers under if it is on the session bus.
68+
69+UBUNTU_APP_LAUNCH_CG_MANAGER_SESSION_BUS
70+ Tell UAL to look on the session bus for CG Manager.
71+
72+UBUNTU_APP_LAUNCH_DEMANGLER
73+ Path to the UAL demangler tool that will get the Mir FD for trusted prompt session.
74+
75+UBUNTU_APP_LAUNCH_DISABLE_SNAPD_TIMEOUT
76+ Wait as long as Snapd wants to return data instead of erroring after 100ms.
77+
78+UBUNTU_APP_LAUNCH_LEGACY_ROOT
79+ Set the path that represents the root for legacy applications.
80+
81+UBUNTU_APP_LAUNCH_LIBERTINE_LAUNCH
82+ Path to the libertine launch utility for setting up libertine containers and XMir based legacy apps.
83+
84+UBUNTU_APP_LAUNCH_LINK_FARM
85+ Path to the link farm that is created by Click of all the installed Click applications.
86+
87+UBUNTU_APP_LAUNCH_OOM_HELPER
88+ Path to the setuid helper that configures OOM values on application processes that we otherwise couldn't, mostly this is for Oxide.
89+
90+UBUNTU_APP_LAUNCH_OOM_PROC_PATH
91+ Path to look for the files to set OOM values, defaults to `/proc`.
92+
93+UBUNTU_APP_LAUNCH_SNAP_BASEDIR
94+ The place where snaps are installed in the system, `/snap` is the default.
95+
96+UBUNTU_APP_LAUNCH_SNAP_LEGACY_EXEC
97+ A snappy command that is used to launch legacy applications in the current snap, to ensure the environment gets configured correctly, defaults to `/snap/bin/unity8-session.legacy-exec`
98+
99+UBUNTU_APP_LAUNCH_SNAPD_SOCKET
100+ Path to the snapd socket.
101+
102+UBUNTU_APP_LAUNCH_XMIR_HELPER
103+ Tool that helps to start XMir and sets the DISPLAY variable for applications
104+
105+UBUNTU_APP_LAUNCH_XMIR_PATH
106+ Specifies the location of the XMir binary to use
107+
108+
109 API Documentation
110 =================
111
112
113=== modified file 'libubuntu-app-launch/application-impl-legacy.cpp'
114--- libubuntu-app-launch/application-impl-legacy.cpp 2017-02-02 15:08:16 +0000
115+++ libubuntu-app-launch/application-impl-legacy.cpp 2017-02-02 15:08:16 +0000
116@@ -299,7 +299,25 @@
117 info();
118
119 retval.emplace_back(std::make_pair("APP_XMIR_ENABLE", appinfo_->xMirEnable().value() ? "1" : "0"));
120- if (appinfo_->xMirEnable())
121+ auto execline = appinfo_->execLine().value();
122+
123+ auto snappath = getenv("SNAP");
124+ if (snappath != nullptr)
125+ {
126+ /* This means we're inside a snap, and if we're in a snap then
127+ the legacy application is in a snap. We need to try and set
128+ up the proper environment for that app */
129+ retval.emplace_back(std::make_pair("SNAP", snappath));
130+
131+ const char* legacyexec = getenv("UBUNTU_APP_LAUNCH_SNAP_LEGACY_EXEC");
132+ if (legacyexec == nullptr)
133+ {
134+ legacyexec = "/snap/bin/unity8-session.legacy-exec";
135+ }
136+
137+ execline = std::string{legacyexec} + " " + execline;
138+ }
139+ else if (appinfo_->xMirEnable().value())
140 {
141 /* If we're setting up XMir we also need the other helpers
142 that libertine is helping with */
143@@ -309,13 +327,10 @@
144 libertine_launch = LIBERTINE_LAUNCH;
145 }
146
147- retval.emplace_back(
148- std::make_pair("APP_EXEC", std::string(libertine_launch) + " " + appinfo_->execLine().value()));
149- }
150- else
151- {
152- retval.emplace_back(std::make_pair("APP_EXEC", appinfo_->execLine().value()));
153- }
154+ execline = std::string{libertine_launch} + " " + execline;
155+ }
156+
157+ retval.emplace_back(std::make_pair("APP_EXEC", execline));
158
159 /* Honor the 'Path' key if it is in the desktop file */
160 if (g_key_file_has_key(_keyfile.get(), "Desktop Entry", "Path", nullptr))
161
162=== modified file 'libubuntu-app-launch/application-impl-snap.cpp'
163--- libubuntu-app-launch/application-impl-snap.cpp 2017-02-02 15:08:16 +0000
164+++ libubuntu-app-launch/application-impl-snap.cpp 2017-02-02 15:08:16 +0000
165@@ -441,7 +441,7 @@
166 std::list<std::pair<std::string, std::string>> retval;
167
168 retval.emplace_back(std::make_pair("APP_XMIR_ENABLE", info_->xMirEnable().value() ? "1" : "0"));
169- if (info_->xMirEnable())
170+ if (info_->xMirEnable() && getenv("SNAP") == nullptr)
171 {
172 /* If we're setting up XMir we also need the other helpers
173 that libertine is helping with */
174@@ -456,6 +456,8 @@
175 }
176 else
177 {
178+ /* If we're in a snap the libertine helpers are setup by
179+ the snap stuff */
180 retval.emplace_back(std::make_pair("APP_EXEC", info_->execLine().value()));
181 }
182
183
184=== modified file 'libubuntu-app-launch/jobs-systemd.cpp'
185--- libubuntu-app-launch/jobs-systemd.cpp 2017-02-02 15:08:16 +0000
186+++ libubuntu-app-launch/jobs-systemd.cpp 2017-02-02 15:08:16 +0000
187@@ -441,7 +441,28 @@
188 if (findEnv("APP_XMIR_ENABLE", env) == "1" && getenv("DISPLAY") == nullptr)
189 {
190 retval.emplace(retval.begin(), findEnv("APP_ID", env));
191- retval.emplace(retval.begin(), XMIR_HELPER);
192+
193+ auto snapenv = getenv("SNAP");
194+ if (snapenv == nullptr)
195+ {
196+ auto xmirenv = getenv("UBUNTU_APP_LAUNCH_XMIR_HELPER");
197+ if (xmirenv == nullptr)
198+ {
199+ retval.emplace(retval.begin(), XMIR_HELPER);
200+ }
201+ else
202+ {
203+ retval.emplace(retval.begin(), xmirenv);
204+ }
205+ }
206+ else
207+ {
208+ /* If we're in a snap we need to use the utility which
209+ gets us back into the snap */
210+ std::string snappath{snapenv};
211+
212+ retval.emplace(retval.begin(), snappath + SNAPPY_XMIR);
213+ }
214 }
215
216 /* See if we're doing apparmor by hand */
217@@ -588,11 +609,35 @@
218 env.emplace_back(std::make_pair("APP_LAUNCHER_PID", std::to_string(getpid()))); /* Who we are, for bugs */
219
220 copyEnv("DISPLAY", env);
221- for (const auto prefix : {"DBUS_", "MIR_", "QT_", "UBUNTU_", "UNITY_", "XDG_"})
222+
223+ for (const auto& prefix : {"DBUS_", "MIR_", "UBUNTU_APP_LAUNCH_"})
224 {
225 copyEnvByPrefix(prefix, env);
226 }
227
228+ /* If we're in deb mode and launching legacy apps, they're gonna need
229+ * more context, they really have no other way to get it. */
230+ if (g_getenv("SNAP") == nullptr && appId.package.value().empty())
231+ {
232+ copyEnvByPrefix("QT_", env);
233+ copyEnvByPrefix("XDG_", env);
234+ copyEnv("UBUNTU_APP_LAUNCH_XMIR_PATH", env);
235+
236+ /* If we're in Unity8 we don't want to pass it's platform, we want
237+ * an application platform. */
238+ if (findEnv("QT_QPA_PLATFORM", env) == "mirserver")
239+ {
240+ removeEnv("QT_QPA_PLATFORM", env);
241+ env.emplace_back(std::make_pair("QT_QPA_PLATFORM", "ubuntumirclient"));
242+ }
243+ }
244+
245+ /* Mir socket if we don't have one in our env */
246+ if (findEnv("MIR_SOCKET", env).empty())
247+ {
248+ env.emplace_back(std::make_pair("MIR_SOCKET", g_get_user_runtime_dir() + std::string{"/mir_socket"}));
249+ }
250+
251 if (!urls.empty())
252 {
253 auto accumfunc = [](const std::string& prev, Application::URL thisurl) -> std::string {
254@@ -702,7 +747,7 @@
255 }
256
257 /* Clean up env before shipping it */
258- for (const auto rmenv :
259+ for (const auto& rmenv :
260 {"APP_XMIR_ENABLE", "APP_DIR", "APP_URIS", "APP_EXEC", "APP_EXEC_POLICY", "APP_LAUNCHER_PID",
261 "INSTANCE_ID", "MIR_SERVER_PLATFORM_PATH", "MIR_SERVER_PROMPT_FILE", "MIR_SERVER_HOST_SOCKET",
262 "UBUNTU_APP_LAUNCH_DEMANGLER", "UBUNTU_APP_LAUNCH_OOM_HELPER", "UBUNTU_APP_LAUNCH_LEGACY_ROOT",
263
264=== modified file 'libubuntu-app-launch/registry-impl.cpp'
265--- libubuntu-app-launch/registry-impl.cpp 2017-02-02 15:08:16 +0000
266+++ libubuntu-app-launch/registry-impl.cpp 2017-02-02 15:08:16 +0000
267@@ -48,6 +48,17 @@
268 return std::shared_ptr<GDBusConnection>(g_bus_get_sync(G_BUS_TYPE_SESSION, cancel.get(), nullptr),
269 [](GDBusConnection* bus) { g_clear_object(&bus); });
270 });
271+
272+ /* Determine where we're getting the helper from */
273+ auto goomHelper = g_getenv("UBUNTU_APP_LAUNCH_OOM_HELPER");
274+ if (goomHelper != nullptr)
275+ {
276+ oomHelper_ = goomHelper;
277+ }
278+ else
279+ {
280+ oomHelper_ = OOM_HELPER;
281+ }
282 }
283
284 void Registry::Impl::initClick()
285
286=== modified file 'libubuntu-app-launch/registry-impl.h'
287--- libubuntu-app-launch/registry-impl.h 2017-01-11 22:38:42 +0000
288+++ libubuntu-app-launch/registry-impl.h 2017-02-02 15:08:16 +0000
289@@ -84,6 +84,11 @@
290 static void watchingAppStarting(bool rWatching);
291 static bool isWatchingAppStarting();
292
293+ const std::string& oomHelper() const
294+ {
295+ return oomHelper_;
296+ }
297+
298 private:
299 Registry* _registry; /**< The Registry that we're spawned from */
300
301@@ -98,6 +103,9 @@
302 /** All of our icon finders based on the path that they're looking
303 into */
304 std::unordered_map<std::string, std::shared_ptr<IconFinder>> _iconFinders;
305+
306+ /** Path to the OOM Helper */
307+ std::string oomHelper_;
308 };
309
310 } // namespace app_launch
311
312=== modified file 'libubuntu-app-launch/ubuntu-app-launch.cpp'
313--- libubuntu-app-launch/ubuntu-app-launch.cpp 2017-01-23 22:43:47 +0000
314+++ libubuntu-app-launch/ubuntu-app-launch.cpp 2017-02-02 15:08:16 +0000
315@@ -1608,7 +1608,11 @@
316 /* The exec value */
317 gchar * envstr = NULL;
318 if (demangler) {
319- envstr = g_strdup_printf("APP_EXEC=%s %s", DEMANGLER_PATH, execline);
320+ const gchar * demangler_path = g_getenv("UBUNTU_APP_LAUNCH_DEMANGLER");
321+ if (demangler_path == nullptr) {
322+ demangler_path = DEMANGLER_PATH;
323+ }
324+ envstr = g_strdup_printf("APP_EXEC=%s %s", demangler_path, execline);
325 } else {
326 envstr = g_strdup_printf("APP_EXEC=%s", execline);
327 }
328
329=== added file 'snappy-xmir-envvars.c'
330--- snappy-xmir-envvars.c 1970-01-01 00:00:00 +0000
331+++ snappy-xmir-envvars.c 2017-02-02 15:08:16 +0000
332@@ -0,0 +1,112 @@
333+/*
334+ * Copyright © 2016 Canonical Ltd.
335+ *
336+ * This program is free software: you can redistribute it and/or modify it
337+ * under the terms of the GNU General Public License version 3, as published
338+ * by the Free Software Foundation.
339+ *
340+ * This program is distributed in the hope that it will be useful, but
341+ * WITHOUT ANY WARRANTY; without even the implied warranties of
342+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
343+ * PURPOSE. See the GNU General Public License for more details.
344+ *
345+ * You should have received a copy of the GNU General Public License along
346+ * with this program. If not, see <http://www.gnu.org/licenses/>.
347+ *
348+ * Authors:
349+ * Ted Gould <ted.gould@canonical.com>
350+ */
351+
352+#define _POSIX_C_SOURCE 200212L
353+
354+#include <unistd.h>
355+#include <stdio.h>
356+#include <stdlib.h>
357+#include <sys/types.h>
358+#include <sys/socket.h>
359+#include <sys/un.h>
360+#include <sys/wait.h>
361+#include <signal.h>
362+#include <string.h>
363+
364+void
365+copyenv (int fd, const char * envname, const char * envval)
366+{
367+ if (envval == NULL) {
368+ fprintf(stderr, "Unable to get environment variable '%s'\n", envname);
369+ exit(EXIT_FAILURE);
370+ }
371+
372+ int writesize;
373+
374+ writesize = write(fd, envname, strlen(envname) + 1);
375+
376+ if (writesize <= 0) {
377+ fprintf(stderr, "Unable to write to socket '%s'\n", envname);
378+ exit(EXIT_FAILURE);
379+ }
380+
381+ writesize = write(fd, envval, strlen(envval) + 1);
382+
383+ if (writesize <= 0) {
384+ fprintf(stderr, "Unable to write to socket '%s'\n", envval);
385+ exit(EXIT_FAILURE);
386+ }
387+
388+ if (getenv("G_MESSAGES_DEBUG") != NULL)
389+ printf("Wrote envvar '%s=%s'\n", envname, envval);
390+}
391+
392+void
393+termhandler (int sig)
394+{
395+ exit(EXIT_SUCCESS);
396+}
397+
398+int
399+main (int argc, char * argv[])
400+{
401+ /* Grab socket */
402+ if (argc != 2) {
403+ fprintf(stderr, "Usage: %s <socket name>\n", argv[0]);
404+ return(EXIT_FAILURE);
405+ }
406+
407+ char * socketname = argv[1];
408+
409+ int socketfd = socket(AF_UNIX, SOCK_STREAM, 0);
410+ if (socketfd <= 0) {
411+ fprintf(stderr, "%s: Unable to create socket\n", argv[0]);
412+ return EXIT_FAILURE;
413+ }
414+
415+ struct sockaddr_un socketaddr = {0};
416+ socketaddr.sun_family = AF_UNIX;
417+ strncpy(socketaddr.sun_path, socketname, sizeof(socketaddr.sun_path) - 1);
418+ socketaddr.sun_path[0] = 0;
419+
420+ if (connect(socketfd, (const struct sockaddr *)&socketaddr, sizeof(struct sockaddr_un)) < 0) {
421+ fprintf(stderr, "Unable to connect socket\n");
422+ return EXIT_FAILURE;
423+ }
424+
425+ /* Dump envvars to socket */
426+ copyenv(socketfd, "DISPLAY", getenv("DISPLAY"));
427+ copyenv(socketfd, "DBUS_SESSION_BUS_ADDRESS", getenv("DBUS_SESSION_BUS_ADDRESS"));
428+
429+ char mypid[16];
430+ snprintf(mypid, 16, "%ld", (long)getpid());
431+ copyenv(socketfd, "UBUNTU_APP_LAUNCH_SNAPPY_XMIR_ENVVARS_PID", mypid);
432+
433+ /* Close the socket */
434+ close(socketfd);
435+
436+ /* Wait for sigterm */
437+ signal(SIGTERM, termhandler);
438+
439+ for (;;) {
440+ sleep(24 * 60 * 60); // taking things one day at a time
441+ }
442+
443+ return EXIT_FAILURE;
444+}
445
446=== added file 'snappy-xmir.c'
447--- snappy-xmir.c 1970-01-01 00:00:00 +0000
448+++ snappy-xmir.c 2017-02-02 15:08:16 +0000
449@@ -0,0 +1,212 @@
450+/*
451+ * Copyright © 2016 Canonical Ltd.
452+ *
453+ * This program is free software: you can redistribute it and/or modify it
454+ * under the terms of the GNU General Public License version 3, as published
455+ * by the Free Software Foundation.
456+ *
457+ * This program is distributed in the hope that it will be useful, but
458+ * WITHOUT ANY WARRANTY; without even the implied warranties of
459+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
460+ * PURPOSE. See the GNU General Public License for more details.
461+ *
462+ * You should have received a copy of the GNU General Public License along
463+ * with this program. If not, see <http://www.gnu.org/licenses/>.
464+ *
465+ * Authors:
466+ * Ted Gould <ted.gould@canonical.com>
467+ */
468+
469+#define _POSIX_C_SOURCE 200212L
470+
471+#include <errno.h>
472+#include <unistd.h>
473+#include <stdio.h>
474+#include <stdlib.h>
475+#include <sys/types.h>
476+#include <sys/socket.h>
477+#include <sys/un.h>
478+#include <signal.h>
479+#include <string.h>
480+#include <fcntl.h>
481+#include <time.h>
482+
483+#define ENVVAR_SIZE 4096
484+#define SOCKETNAME_SIZE 256
485+#define ENVNAME_SIZE 64
486+
487+void
488+sigchild_handler (int signal)
489+{
490+ fprintf(stderr, "XMir has closed unexpectedly\n");
491+ exit(EXIT_FAILURE);
492+}
493+
494+struct sigaction sigchild_action = {
495+ .sa_handler = sigchild_handler,
496+ .sa_flags = SA_NOCLDWAIT
497+};
498+
499+int
500+main (int argc, char * argv[])
501+{
502+ if (argc < 3) {
503+ fprintf(stderr, "%s: Usage: [appid] [command to execute...]\n", argv[0]);
504+ return EXIT_FAILURE;
505+ }
506+
507+ char * appid = argv[1];
508+
509+ /* Build Socket Name */
510+ srand(time(NULL));
511+ char socketname[SOCKETNAME_SIZE] = {0};
512+ snprintf(socketname, sizeof(socketname), "/ual-socket-%08X-%s", rand(), appid);
513+
514+ /* Setup abstract socket */
515+ int socketfd = socket(AF_UNIX, SOCK_STREAM, 0);
516+ if (socketfd <= 0) {
517+ fprintf(stderr, "%s: Unable to create socket\n", argv[0]);
518+ return EXIT_FAILURE;
519+ }
520+
521+ struct sockaddr_un socketaddr = {0};
522+ socketaddr.sun_family = AF_UNIX;
523+ strncpy(socketaddr.sun_path, socketname, sizeof(socketaddr.sun_path) - 1);
524+ socketaddr.sun_path[0] = 0;
525+
526+ if (bind(socketfd, (const struct sockaddr *)&socketaddr, sizeof(struct sockaddr_un)) < 0) {
527+ fprintf(stderr, "%s: Unable to bind socket '%s'\n", argv[0], socketname);
528+ return EXIT_FAILURE;
529+ }
530+
531+ /* Fork and exec the x11 setup under it's confiment */
532+ if (sigaction(SIGCHLD, &sigchild_action, NULL) != 0) {
533+ fprintf(stderr, "Unable to setup child signal handler\n");
534+ return EXIT_FAILURE;
535+ }
536+
537+ if (fork() == 0) {
538+ /* XMir start here */
539+ /* GOAL: /snap/bin/unity8-session.xmir-helper $appid libertine-launch /snap/unity8-session/current/usr/bin/snappy-xmir-envvars socketname */
540+
541+ char * snappyhelper = getenv("UBUNTU_APP_LAUNCH_SNAPPY_XMIR_HELPER");
542+ if (snappyhelper == NULL) {
543+ snappyhelper = "xmir-helper";
544+ }
545+
546+ char * libertinelaunch = getenv("UBUNTU_APP_LAUNCH_LIBERTINE_LAUNCH");
547+ if (libertinelaunch == NULL) {
548+ libertinelaunch = "libertine-launch";
549+ }
550+
551+ /* envvar is like us, but a little more */
552+ char envvars[256] = {0};
553+ snprintf(envvars, sizeof(envvars), "%s-envvars", argv[0]);
554+
555+ char * xmirexec[6] = {
556+ snappyhelper,
557+ appid,
558+ libertinelaunch,
559+ envvars,
560+ socketname,
561+ NULL
562+ };
563+
564+ printf("Executing xmir-helper on PID: %d\n", getpid());
565+
566+ fflush(stdout);
567+
568+ return execv(xmirexec[0], xmirexec);
569+ }
570+
571+ listen(socketfd, 1); /* 1 is the number of people who can connect */
572+ int readsocket = accept(socketfd, NULL, NULL);
573+
574+ if (getenv("G_MESSAGES_DEBUG") != NULL) {
575+ printf("Got a socket connection on: %s\n", socketname);
576+ }
577+
578+ /* Read our socket until we get all of the environment */
579+ char readbuf[ENVVAR_SIZE] = {0};
580+ int amountread = 0;
581+ int thisread = 0;
582+ while ((thisread = read(readsocket, readbuf + amountread, ENVVAR_SIZE - amountread)) > 0) {
583+ amountread += thisread;
584+
585+ if (amountread == ENVVAR_SIZE) {
586+ fprintf(stderr, "Environment is too large, abort!\n");
587+ exit(EXIT_FAILURE);
588+ }
589+ }
590+
591+ if (thisread < 0) {
592+ fprintf(stderr, "Error reading environment variables from Xmir utilities: %s", strerror(errno));
593+ exit(EXIT_FAILURE);
594+ }
595+
596+ close(readsocket);
597+ close(socketfd);
598+
599+ /* Parse the environment into variables we can insert */
600+ if (amountread > 0) {
601+ char * startvar = readbuf;
602+ int debug = (getenv("G_MESSAGES_DEBUG") != NULL);
603+
604+ do {
605+ char * startval = startvar + strlen(startvar) + 1;
606+ setenv(startvar, startval, 1);
607+
608+ if (debug) {
609+ printf("Got env: %s=%s\n", startvar, startval);
610+ }
611+
612+ startvar = startval + strlen(startval) + 1;
613+ }
614+ while (startvar < readbuf + amountread);
615+ }
616+
617+ /* Clear MIR_* variables from the environment */
618+ /* Unfortunately calling unsetenv resets the environ array so
619+ it can become invalid. So we need to start over, though this
620+ is fast */
621+ int unset = 1;
622+ while (unset) {
623+ unset = 0;
624+
625+ unsigned int i;
626+ for (i = 0; __environ[i] != NULL; i++) {
627+ const char * env = __environ[i];
628+ /* Not checking the length becasue imagining that block
629+ size will always be larger than 4 bytes on 32-bit systems.
630+ Compiler should fold this into one comparison. */
631+ if (env[0] == 'M' && env[1] == 'I' && env[2] == 'R' && env[3] == '_') {
632+ char envname[ENVNAME_SIZE] = {0};
633+ unset = 1;
634+
635+ strncpy(envname, env, ENVNAME_SIZE - 1);
636+ unsigned int j;
637+ for (j = 0; j < ENVNAME_SIZE && envname[j] != '\0'; j++) {
638+ if (envname[j] == '=') {
639+ envname[j] = '\0';
640+
641+ if (unsetenv(envname) != 0) {
642+ /* Shouldn't happen unless we're out of memory,
643+ might as well bail now if that's the case. */
644+ fprintf(stderr, "Unable to unset '%s' environment variable\n", envname);
645+ exit(EXIT_FAILURE);
646+ }
647+
648+ break;
649+ }
650+ }
651+
652+ break;
653+ }
654+ }
655+ }
656+
657+ fflush(stdout);
658+
659+ /* Exec the application with the new environment under its confinement */
660+ return execv(argv[2], &(argv[2]));
661+}
662
663=== modified file 'tests/CMakeLists.txt'
664--- tests/CMakeLists.txt 2017-02-02 15:08:16 +0000
665+++ tests/CMakeLists.txt 2017-02-02 15:08:16 +0000
666@@ -165,6 +165,11 @@
667 configure_file ("xmir-helper-test.in" "${CMAKE_CURRENT_BINARY_DIR}/xmir-helper-test" @ONLY)
668 add_test (xmir-helper-test xmir-helper-test)
669
670+# Snappy XMir Wrapper Test
671+
672+configure_file("snappy-xmir-test.sh.in" "${CMAKE_CURRENT_BINARY_DIR}/snappy-xmir-test.sh" @ONLY)
673+add_test (NAME snappy-xmir-test COMMAND ${CMAKE_CURRENT_BINARY_DIR}/snappy-xmir-test.sh)
674+
675 # Formatted code
676
677 add_custom_target(format-tests
678
679=== added file 'tests/snappy-xmir-test-check.sh'
680--- tests/snappy-xmir-test-check.sh 1970-01-01 00:00:00 +0000
681+++ tests/snappy-xmir-test-check.sh 2017-02-02 15:08:16 +0000
682@@ -0,0 +1,32 @@
683+#!/bin/bash
684+
685+set -ex
686+
687+if [ -z ${DISPLAY} ] ; then
688+ echo DISPLAY is not set
689+ exit 1
690+fi
691+
692+if [ ${DISPLAY} != "foo" ] ; then
693+ echo DISPLAY is not set to 'foo'
694+ exit 1
695+fi
696+
697+if [ -z ${DBUS_SESSION_BUS_ADDRESS} ] ; then
698+ echo DBUS_SESSION_BUS_ADDRESS is not set
699+ exit 1
700+fi
701+
702+if [ ${DBUS_SESSION_BUS_ADDRESS} != "bar" ] ; then
703+ echo DBUS_SESSION_BUS_ADDRESS is not set to 'bar'
704+ exit 1
705+fi
706+
707+if [ ! -z ${MIR_SOCKET} ] ; then
708+ echo Mir variables are leaking in
709+ exit 1
710+fi
711+
712+if [ ! -z ${UBUNTU_APP_LAUNCH_SNAPPY_XMIR_ENVVARS_PID} ] ; then
713+ kill -TERM ${UBUNTU_APP_LAUNCH_SNAPPY_XMIR_ENVVARS_PID}
714+fi
715
716=== added file 'tests/snappy-xmir-test-helper-long.sh'
717--- tests/snappy-xmir-test-helper-long.sh 1970-01-01 00:00:00 +0000
718+++ tests/snappy-xmir-test-helper-long.sh 2017-02-02 15:08:16 +0000
719@@ -0,0 +1,12 @@
720+#!/bin/bash
721+
722+set -ex
723+
724+if [ $1 != "this-is-a-really-really-really_long_appid-that-we-shouldnt-reallyhave_13523432324235.234.234.234234+foo" ] ; then
725+ exit 1
726+fi
727+
728+export DISPLAY=foo
729+export DBUS_SESSION_BUS_ADDRESS=bar
730+
731+exec $2 $3 $4 $5
732
733=== added file 'tests/snappy-xmir-test-helper.sh'
734--- tests/snappy-xmir-test-helper.sh 1970-01-01 00:00:00 +0000
735+++ tests/snappy-xmir-test-helper.sh 2017-02-02 15:08:16 +0000
736@@ -0,0 +1,12 @@
737+#!/bin/bash
738+
739+set -ex
740+
741+if [ $1 != "appid" ] ; then
742+ exit 1
743+fi
744+
745+export DISPLAY=foo
746+export DBUS_SESSION_BUS_ADDRESS=bar
747+
748+exec $2 $3 $4 $5
749
750=== added file 'tests/snappy-xmir-test-libertine-launch.sh'
751--- tests/snappy-xmir-test-libertine-launch.sh 1970-01-01 00:00:00 +0000
752+++ tests/snappy-xmir-test-libertine-launch.sh 2017-02-02 15:08:16 +0000
753@@ -0,0 +1,5 @@
754+#!/bin/bash
755+
756+set -ex
757+
758+exec $@
759
760=== added file 'tests/snappy-xmir-test.sh.in'
761--- tests/snappy-xmir-test.sh.in 1970-01-01 00:00:00 +0000
762+++ tests/snappy-xmir-test.sh.in 2017-02-02 15:08:16 +0000
763@@ -0,0 +1,30 @@
764+#!/bin/bash
765+
766+set -ex
767+
768+# Unset MIR_SOCKET as we might be in an environment it exists in
769+
770+export MIR_SOCKET=
771+
772+# Test the test harness
773+
774+@CMAKE_CURRENT_SOURCE_DIR@/snappy-xmir-test-helper.sh appid @CMAKE_CURRENT_SOURCE_DIR@/snappy-xmir-test-check.sh
775+
776+# Test our pass through
777+
778+export UBUNTU_APP_LAUNCH_SNAPPY_XMIR_HELPER="@CMAKE_CURRENT_SOURCE_DIR@/snappy-xmir-test-helper.sh"
779+export UBUNTU_APP_LAUNCH_LIBERTINE_LAUNCH="@CMAKE_CURRENT_SOURCE_DIR@/snappy-xmir-test-libertine-launch.sh"
780+
781+@CMAKE_BINARY_DIR@/snappy-xmir appid @CMAKE_CURRENT_SOURCE_DIR@/snappy-xmir-test-check.sh
782+
783+# Add a Mir variable to make sure it gets cleared
784+
785+export MIR_SOCKET="/this/is/a/socket"
786+
787+@CMAKE_BINARY_DIR@/snappy-xmir appid @CMAKE_CURRENT_SOURCE_DIR@/snappy-xmir-test-check.sh
788+
789+# This is a long appid test
790+
791+export UBUNTU_APP_LAUNCH_SNAPPY_XMIR_HELPER="@CMAKE_CURRENT_SOURCE_DIR@/snappy-xmir-test-helper-long.sh"
792+
793+@CMAKE_BINARY_DIR@/snappy-xmir "this-is-a-really-really-really_long_appid-that-we-shouldnt-reallyhave_13523432324235.234.234.234234+foo" @CMAKE_CURRENT_SOURCE_DIR@/snappy-xmir-test-check.sh
794
795=== modified file 'upstart-jobs/application-click.conf.in'
796--- upstart-jobs/application-click.conf.in 2015-08-17 21:34:39 +0000
797+++ upstart-jobs/application-click.conf.in 2017-02-02 15:08:16 +0000
798@@ -14,7 +14,6 @@
799 env APP_XMIR_ENABLE
800
801 env UBUNTU_APP_LAUNCH_ARCH="@ubuntu_app_launch_arch@"
802-export UBUNTU_APP_LAUNCH_ARCH
803
804 apparmor switch ${APP_ID}
805 cgroup freezer
806
807=== modified file 'upstart-jobs/application-snap.conf.in'
808--- upstart-jobs/application-snap.conf.in 2016-09-08 15:05:06 +0000
809+++ upstart-jobs/application-snap.conf.in 2017-02-02 15:08:16 +0000
810@@ -15,7 +15,6 @@
811 env INSTANCE_ID=""
812
813 env UBUNTU_APP_LAUNCH_ARCH="@ubuntu_app_launch_arch@"
814-export UBUNTU_APP_LAUNCH_ARCH
815
816 # apparmor is taken care of by confine
817 cgroup freezer
818
819=== modified file 'upstart-jobs/untrusted-helper.conf.in'
820--- upstart-jobs/untrusted-helper.conf.in 2014-08-07 16:16:05 +0000
821+++ upstart-jobs/untrusted-helper.conf.in 2017-02-02 15:08:16 +0000
822@@ -12,7 +12,6 @@
823 env APP_URIS
824
825 env UBUNTU_APP_LAUNCH_ARCH="@ubuntu_app_launch_arch@"
826-export UBUNTU_APP_LAUNCH_ARCH
827
828 apparmor switch ${APP_ID}
829 cgroup freezer
830
831=== modified file 'xmir-helper.c'
832--- xmir-helper.c 2017-02-02 15:08:16 +0000
833+++ xmir-helper.c 2017-02-02 15:08:16 +0000
834@@ -30,7 +30,7 @@
835 sigchild_handler (int signal)
836 {
837 fprintf(stderr, "XMir has closed unexpectedly\n");
838- exit(1);
839+ exit(EXIT_FAILURE);
840 }
841
842 struct sigaction sigchild_action = {
843@@ -43,7 +43,7 @@
844 {
845 if (argc < 3) {
846 fprintf(stderr, "xmir-helper needs more arguments: xmir-helper $(appid) $(thing to exec) ... \n");
847- return 1;
848+ return EXIT_FAILURE;
849 }
850
851 /* Make nice variables for the things we need */
852@@ -57,7 +57,7 @@
853 int sockets[2];
854 if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sockets) != 0) {
855 fprintf(stderr, "Unable to create socketpair for communicating with XMir\n");
856- return 1;
857+ return EXIT_FAILURE;
858 }
859
860 /* Give them nice names, the compiler will optimize out */
861@@ -67,7 +67,7 @@
862 /* Watch for the child dying */
863 if (sigaction(SIGCHLD, &sigchild_action, NULL) != 0) {
864 fprintf(stderr, "Unable to setup child signal handler\n");
865- return 1;
866+ return EXIT_FAILURE;
867 }
868
869 /* Start XMir */

Subscribers

People subscribed via source and target branches