Merge lp:~ted/ubuntu-app-launch/environment-dbus into lp:ubuntu-app-launch/14.04

Proposed by Ted Gould
Status: Merged
Approved by: Ted Gould
Approved revision: 101
Merged at revision: 102
Proposed branch: lp:~ted/ubuntu-app-launch/environment-dbus
Merge into: lp:ubuntu-app-launch/14.04
Diff against target: 303 lines (+113/-54)
6 files modified
click-exec.c (+14/-2)
desktop-exec.c (+13/-0)
helpers.c (+40/-29)
tests/CMakeLists.txt (+1/-1)
tests/helper-test.cc (+45/-19)
tests/initctl (+0/-3)
To merge this branch: bzr merge lp:~ted/ubuntu-app-launch/environment-dbus
Reviewer Review Type Date Requested Status
Charles Kerr (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+198839@code.launchpad.net

Commit message

Set the Upstart job environment using DBus

Description of the change

Switching from shelling out to using a DBus message to set environment variables. This should hopefully make things a little bit faster as we can reuse the same DBus connection over and over.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Charles Kerr (charlesk) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'click-exec.c'
2--- click-exec.c 2013-12-12 21:34:28 +0000
3+++ click-exec.c 2013-12-20 17:42:31 +0000
4@@ -17,7 +17,7 @@
5 * Ted Gould <ted.gould@canonical.com>
6 */
7
8-#include <glib.h>
9+#include <gio/gio.h>
10 #include "helpers.h"
11 #include "click-exec-trace.h"
12
13@@ -55,6 +55,16 @@
14
15 tracepoint(upstart_app_launch, click_start);
16
17+ /* Ensure we keep one connection open to the bus for the entire
18+ script even though different people need it throughout */
19+ GError * error = NULL;
20+ GDBusConnection * bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
21+ if (error != NULL) {
22+ g_error("Unable to get session bus: %s", error->message);
23+ g_error_free(error);
24+ return 1;
25+ }
26+
27 handshake_t * handshake = starting_handshake_start(app_id);
28 if (handshake == NULL) {
29 g_warning("Unable to setup starting handshake");
30@@ -62,7 +72,6 @@
31
32 tracepoint(upstart_app_launch, click_starting_sent);
33
34- GError * error = NULL;
35 gchar * package = NULL;
36 /* 'Parse' the App ID */
37 if (!app_id_to_triplet(app_id, &package, NULL, NULL)) {
38@@ -157,5 +166,8 @@
39
40 tracepoint(upstart_app_launch, click_handshake_complete);
41
42+ g_dbus_connection_flush_sync(bus, NULL, NULL);
43+ g_object_unref(bus);
44+
45 return 0;
46 }
47
48=== modified file 'desktop-exec.c'
49--- desktop-exec.c 2013-12-06 10:46:55 +0000
50+++ desktop-exec.c 2013-12-20 17:42:31 +0000
51@@ -44,6 +44,16 @@
52 g_setenv("LTTNG_UST_REGISTER_TIMEOUT", "0", FALSE); /* Set to zero if not set */
53 tracepoint(upstart_app_launch, desktop_start);
54
55+ /* Ensure we keep one connection open to the bus for the entire
56+ script even though different people need it throughout */
57+ GError * error = NULL;
58+ GDBusConnection * bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
59+ if (error != NULL) {
60+ g_error("Unable to get session bus: %s", error->message);
61+ g_error_free(error);
62+ return 1;
63+ }
64+
65 handshake_t * handshake = starting_handshake_start(app_id);
66 if (handshake == NULL) {
67 g_warning("Unable to setup starting handshake");
68@@ -97,5 +107,8 @@
69
70 tracepoint(upstart_app_launch, desktop_handshake_complete);
71
72+ g_dbus_connection_flush_sync(bus, NULL, NULL);
73+ g_object_unref(bus);
74+
75 return 0;
76 }
77
78=== modified file 'helpers.c'
79--- helpers.c 2013-12-06 11:38:40 +0000
80+++ helpers.c 2013-12-20 17:42:31 +0000
81@@ -18,6 +18,7 @@
82 */
83
84 #include <json-glib/json-glib.h>
85+#include <upstart.h>
86 #include "helpers.h"
87
88 /* Take an app ID and validate it and then break it up
89@@ -222,35 +223,45 @@
90 void
91 set_upstart_variable (const gchar * variable, const gchar * value)
92 {
93- GError * error = NULL;
94- gchar * command[4] = {
95- "initctl",
96- "set-env",
97- NULL,
98- NULL
99- };
100-
101- g_debug("Setting Upstart variable '%s' to '%s'", variable, value);
102- gchar * variablestr = g_strdup_printf("%s=%s", variable, value);
103- command[2] = variablestr;
104-
105- g_spawn_sync(NULL, /* working directory */
106- command,
107- NULL, /* environment */
108- G_SPAWN_SEARCH_PATH,
109- NULL, NULL, /* child setup */
110- NULL, /* stdout */
111- NULL, /* stderr */
112- NULL, /* exit status */
113- &error);
114-
115- if (error != NULL) {
116- g_warning("Unable to set variable '%s' to '%s': %s", variable, value, error->message);
117- g_error_free(error);
118- }
119-
120- g_free(variablestr);
121- return;
122+ /* Check to see if we can get the job environment */
123+ const gchar * job_name = g_getenv("UPSTART_JOB");
124+ const gchar * instance_name = g_getenv("UPSTART_INSTANCE");
125+ g_return_if_fail(job_name != NULL);
126+
127+ /* Get a bus, let's go! */
128+ GDBusConnection * bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
129+ g_return_if_fail(bus != NULL);
130+
131+ GVariantBuilder builder; /* Target: (assb) */
132+ g_variant_builder_init(&builder, G_VARIANT_TYPE_TUPLE);
133+
134+ /* Setup the job properties */
135+ g_variant_builder_open(&builder, G_VARIANT_TYPE_ARRAY);
136+ g_variant_builder_add_value(&builder, g_variant_new_string(job_name));
137+ if (instance_name != NULL)
138+ g_variant_builder_add_value(&builder, g_variant_new_string(instance_name));
139+ g_variant_builder_close(&builder);
140+
141+ /* The value itself */
142+ gchar * envstr = g_strdup_printf("%s=%s", variable, value);
143+ g_variant_builder_add_value(&builder, g_variant_new_take_string(envstr));
144+
145+ /* Do we want to replace? Yes, we do! */
146+ g_variant_builder_add_value(&builder, g_variant_new_boolean(TRUE));
147+
148+ g_dbus_connection_call(bus,
149+ DBUS_SERVICE_UPSTART,
150+ DBUS_PATH_UPSTART,
151+ DBUS_INTERFACE_UPSTART,
152+ "SetEnv",
153+ g_variant_builder_end(&builder),
154+ NULL, /* reply */
155+ G_DBUS_CALL_FLAGS_NONE,
156+ -1, /* timeout */
157+ NULL, /* cancelable */
158+ NULL, NULL); /* callback */
159+
160+ g_object_unref(bus);
161 }
162
163 /* Convert a URI into a file */
164
165=== modified file 'tests/CMakeLists.txt'
166--- tests/CMakeLists.txt 2013-12-06 11:47:53 +0000
167+++ tests/CMakeLists.txt 2013-12-20 17:42:31 +0000
168@@ -14,7 +14,7 @@
169 add_executable (helper-test helper-test.cc)
170 add_definitions ( -DCMAKE_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}" )
171 add_definitions ( -DCMAKE_BINARY_DIR="${CMAKE_CURRENT_BINARY_DIR}" )
172-target_link_libraries (helper-test helpers gtest ${GTEST_LIBS})
173+target_link_libraries (helper-test helpers gtest ${GTEST_LIBS} ${DBUSTEST_LIBRARIES})
174
175 add_test (helper-test helper-test)
176
177
178=== modified file 'tests/helper-test.cc'
179--- tests/helper-test.cc 2013-11-22 16:39:38 +0000
180+++ tests/helper-test.cc 2013-12-20 17:42:31 +0000
181@@ -19,6 +19,8 @@
182
183 #include <gtest/gtest.h>
184 #include <glib/gstdio.h>
185+#include <libdbustest/dbus-test.h>
186+#include <gio/gio.h>
187
188 extern "C" {
189 #include "../helpers.h"
190@@ -31,8 +33,12 @@
191 protected:
192 virtual void SetUp() {
193 g_setenv("XDG_DATA_DIRS", CMAKE_SOURCE_DIR, TRUE);
194- g_setenv("PATH", CMAKE_SOURCE_DIR, TRUE);
195+ const gchar * oldpath = g_getenv("PATH");
196+ gchar * newpath = g_strjoin(":", CMAKE_SOURCE_DIR, oldpath, NULL);
197+ g_setenv("PATH", newpath, TRUE);
198+ g_free(newpath);
199 g_setenv("DATA_WRITE_DIR", CMAKE_BINARY_DIR, TRUE);
200+ g_setenv("UPSTART_JOB", "made-up-job", TRUE);
201 return;
202 }
203 };
204@@ -264,18 +270,34 @@
205
206 TEST_F(HelperTest, SetConfinedEnvvars)
207 {
208- g_unlink(CMAKE_BINARY_DIR "/initctl-output.txt");
209+ DbusTestService * service = dbus_test_service_new(NULL);
210+ DbusTestDbusMock * mock = dbus_test_dbus_mock_new("com.ubuntu.Upstart");
211+
212+ DbusTestDbusMockObject * obj = dbus_test_dbus_mock_get_object(mock, "/com/ubuntu/Upstart", "com.ubuntu.Upstart0_6", NULL);
213+
214+ dbus_test_dbus_mock_object_add_method(mock, obj,
215+ "SetEnv",
216+ G_VARIANT_TYPE("(assb)"),
217+ NULL,
218+ "",
219+ NULL);
220+
221+ dbus_test_service_add_task(service, DBUS_TEST_TASK(mock));
222+ dbus_test_service_start_tasks(service);
223+
224+ GDBusConnection * bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
225+ g_dbus_connection_set_exit_on_close(bus, FALSE);
226+ g_object_add_weak_pointer(G_OBJECT(bus), (gpointer *)&bus);
227
228 /* Not a test other than "don't crash" */
229 set_confined_envvars("foo-app-pkg", "/foo/bar");
230
231- ASSERT_TRUE(g_file_test(CMAKE_BINARY_DIR "/initctl-output.txt", G_FILE_TEST_EXISTS));
232-
233- gchar * contents = NULL;
234- ASSERT_TRUE(g_file_get_contents(CMAKE_BINARY_DIR "/initctl-output.txt", &contents, NULL, NULL));
235-
236- gchar ** lines = g_strsplit(contents, "\n", 0);
237- g_free(contents);
238+ guint len = 0;
239+ const DbusTestDbusMockCall * calls = dbus_test_dbus_mock_object_get_method_calls(mock, obj, "SetEnv", &len, NULL);
240+
241+ ASSERT_EQ(len, 8);
242+ ASSERT_NE(calls, nullptr);
243+
244 unsigned int i;
245
246 bool got_app_isolation = false;
247@@ -287,13 +309,13 @@
248 bool got_temp_dir = false;
249 bool got_shader_dir = false;
250
251- for (i = 0; lines[i] != NULL; i++) {
252- g_debug("Checking: '%s'", lines[i]);
253- if (lines[i][0] == '\0') continue;
254-
255- ASSERT_TRUE(g_str_has_prefix(lines[i], "set-env "));
256-
257- gchar * var = lines[i] + strlen("set-env ");
258+ for (i = 0; i < len; i++) {
259+ EXPECT_STREQ("SetEnv", calls[i].name);
260+
261+ GVariant * envvar = g_variant_get_child_value(calls[i].params, 1);
262+ gchar * var = g_variant_dup_string(envvar, NULL);
263+ g_variant_unref(envvar);
264+
265 gchar * equal = g_strstr_len(var, -1, "=");
266 ASSERT_NE(equal, nullptr);
267
268@@ -321,13 +343,13 @@
269 ASSERT_TRUE(g_str_has_suffix(value, "foo-app-pkg"));
270 got_shader_dir = true;
271 } else {
272- g_warning("Unknown variable! %s", lines[i]);
273+ g_warning("Unknown variable! %s", var);
274 ASSERT_TRUE(false);
275 }
276+
277+ g_free(var);
278 }
279
280- g_strfreev(lines);
281-
282 ASSERT_TRUE(got_app_isolation);
283 ASSERT_TRUE(got_cache_home);
284 ASSERT_TRUE(got_config_home);
285@@ -337,6 +359,10 @@
286 ASSERT_TRUE(got_temp_dir);
287 ASSERT_TRUE(got_shader_dir);
288
289+ g_object_unref(bus);
290+ g_object_unref(mock);
291+ g_object_unref(service);
292+
293 return;
294 }
295
296
297=== removed file 'tests/initctl'
298--- tests/initctl 2013-11-12 21:56:12 +0000
299+++ tests/initctl 1970-01-01 00:00:00 +0000
300@@ -1,3 +0,0 @@
301-#!/bin/bash
302-
303-echo $@ >> ${DATA_WRITE_DIR}/initctl-output.txt

Subscribers

People subscribed via source and target branches