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
=== modified file 'click-exec.c'
--- click-exec.c 2013-12-12 21:34:28 +0000
+++ click-exec.c 2013-12-20 17:42:31 +0000
@@ -17,7 +17,7 @@
17 * Ted Gould <ted.gould@canonical.com>17 * Ted Gould <ted.gould@canonical.com>
18 */18 */
1919
20#include <glib.h>20#include <gio/gio.h>
21#include "helpers.h"21#include "helpers.h"
22#include "click-exec-trace.h"22#include "click-exec-trace.h"
2323
@@ -55,6 +55,16 @@
5555
56 tracepoint(upstart_app_launch, click_start);56 tracepoint(upstart_app_launch, click_start);
5757
58 /* Ensure we keep one connection open to the bus for the entire
59 script even though different people need it throughout */
60 GError * error = NULL;
61 GDBusConnection * bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
62 if (error != NULL) {
63 g_error("Unable to get session bus: %s", error->message);
64 g_error_free(error);
65 return 1;
66 }
67
58 handshake_t * handshake = starting_handshake_start(app_id);68 handshake_t * handshake = starting_handshake_start(app_id);
59 if (handshake == NULL) {69 if (handshake == NULL) {
60 g_warning("Unable to setup starting handshake");70 g_warning("Unable to setup starting handshake");
@@ -62,7 +72,6 @@
6272
63 tracepoint(upstart_app_launch, click_starting_sent);73 tracepoint(upstart_app_launch, click_starting_sent);
6474
65 GError * error = NULL;
66 gchar * package = NULL;75 gchar * package = NULL;
67 /* 'Parse' the App ID */76 /* 'Parse' the App ID */
68 if (!app_id_to_triplet(app_id, &package, NULL, NULL)) {77 if (!app_id_to_triplet(app_id, &package, NULL, NULL)) {
@@ -157,5 +166,8 @@
157166
158 tracepoint(upstart_app_launch, click_handshake_complete);167 tracepoint(upstart_app_launch, click_handshake_complete);
159168
169 g_dbus_connection_flush_sync(bus, NULL, NULL);
170 g_object_unref(bus);
171
160 return 0;172 return 0;
161}173}
162174
=== modified file 'desktop-exec.c'
--- desktop-exec.c 2013-12-06 10:46:55 +0000
+++ desktop-exec.c 2013-12-20 17:42:31 +0000
@@ -44,6 +44,16 @@
44 g_setenv("LTTNG_UST_REGISTER_TIMEOUT", "0", FALSE); /* Set to zero if not set */44 g_setenv("LTTNG_UST_REGISTER_TIMEOUT", "0", FALSE); /* Set to zero if not set */
45 tracepoint(upstart_app_launch, desktop_start);45 tracepoint(upstart_app_launch, desktop_start);
4646
47 /* Ensure we keep one connection open to the bus for the entire
48 script even though different people need it throughout */
49 GError * error = NULL;
50 GDBusConnection * bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error);
51 if (error != NULL) {
52 g_error("Unable to get session bus: %s", error->message);
53 g_error_free(error);
54 return 1;
55 }
56
47 handshake_t * handshake = starting_handshake_start(app_id);57 handshake_t * handshake = starting_handshake_start(app_id);
48 if (handshake == NULL) {58 if (handshake == NULL) {
49 g_warning("Unable to setup starting handshake");59 g_warning("Unable to setup starting handshake");
@@ -97,5 +107,8 @@
97107
98 tracepoint(upstart_app_launch, desktop_handshake_complete);108 tracepoint(upstart_app_launch, desktop_handshake_complete);
99109
110 g_dbus_connection_flush_sync(bus, NULL, NULL);
111 g_object_unref(bus);
112
100 return 0;113 return 0;
101}114}
102115
=== modified file 'helpers.c'
--- helpers.c 2013-12-06 11:38:40 +0000
+++ helpers.c 2013-12-20 17:42:31 +0000
@@ -18,6 +18,7 @@
18 */18 */
1919
20#include <json-glib/json-glib.h>20#include <json-glib/json-glib.h>
21#include <upstart.h>
21#include "helpers.h"22#include "helpers.h"
2223
23/* Take an app ID and validate it and then break it up24/* Take an app ID and validate it and then break it up
@@ -222,35 +223,45 @@
222void223void
223set_upstart_variable (const gchar * variable, const gchar * value)224set_upstart_variable (const gchar * variable, const gchar * value)
224{225{
225 GError * error = NULL;226 /* Check to see if we can get the job environment */
226 gchar * command[4] = {227 const gchar * job_name = g_getenv("UPSTART_JOB");
227 "initctl",228 const gchar * instance_name = g_getenv("UPSTART_INSTANCE");
228 "set-env",229 g_return_if_fail(job_name != NULL);
229 NULL,230
230 NULL231 /* Get a bus, let's go! */
231 };232 GDBusConnection * bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
232233 g_return_if_fail(bus != NULL);
233 g_debug("Setting Upstart variable '%s' to '%s'", variable, value);234
234 gchar * variablestr = g_strdup_printf("%s=%s", variable, value);235 GVariantBuilder builder; /* Target: (assb) */
235 command[2] = variablestr;236 g_variant_builder_init(&builder, G_VARIANT_TYPE_TUPLE);
236237
237 g_spawn_sync(NULL, /* working directory */238 /* Setup the job properties */
238 command,239 g_variant_builder_open(&builder, G_VARIANT_TYPE_ARRAY);
239 NULL, /* environment */240 g_variant_builder_add_value(&builder, g_variant_new_string(job_name));
240 G_SPAWN_SEARCH_PATH,241 if (instance_name != NULL)
241 NULL, NULL, /* child setup */242 g_variant_builder_add_value(&builder, g_variant_new_string(instance_name));
242 NULL, /* stdout */243 g_variant_builder_close(&builder);
243 NULL, /* stderr */244
244 NULL, /* exit status */245 /* The value itself */
245 &error);246 gchar * envstr = g_strdup_printf("%s=%s", variable, value);
246247 g_variant_builder_add_value(&builder, g_variant_new_take_string(envstr));
247 if (error != NULL) {248
248 g_warning("Unable to set variable '%s' to '%s': %s", variable, value, error->message);249 /* Do we want to replace? Yes, we do! */
249 g_error_free(error);250 g_variant_builder_add_value(&builder, g_variant_new_boolean(TRUE));
250 }251
251252 g_dbus_connection_call(bus,
252 g_free(variablestr);253 DBUS_SERVICE_UPSTART,
253 return;254 DBUS_PATH_UPSTART,
255 DBUS_INTERFACE_UPSTART,
256 "SetEnv",
257 g_variant_builder_end(&builder),
258 NULL, /* reply */
259 G_DBUS_CALL_FLAGS_NONE,
260 -1, /* timeout */
261 NULL, /* cancelable */
262 NULL, NULL); /* callback */
263
264 g_object_unref(bus);
254}265}
255266
256/* Convert a URI into a file */267/* Convert a URI into a file */
257268
=== modified file 'tests/CMakeLists.txt'
--- tests/CMakeLists.txt 2013-12-06 11:47:53 +0000
+++ tests/CMakeLists.txt 2013-12-20 17:42:31 +0000
@@ -14,7 +14,7 @@
14add_executable (helper-test helper-test.cc)14add_executable (helper-test helper-test.cc)
15add_definitions ( -DCMAKE_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}" )15add_definitions ( -DCMAKE_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}" )
16add_definitions ( -DCMAKE_BINARY_DIR="${CMAKE_CURRENT_BINARY_DIR}" )16add_definitions ( -DCMAKE_BINARY_DIR="${CMAKE_CURRENT_BINARY_DIR}" )
17target_link_libraries (helper-test helpers gtest ${GTEST_LIBS})17target_link_libraries (helper-test helpers gtest ${GTEST_LIBS} ${DBUSTEST_LIBRARIES})
1818
19add_test (helper-test helper-test)19add_test (helper-test helper-test)
2020
2121
=== modified file 'tests/helper-test.cc'
--- tests/helper-test.cc 2013-11-22 16:39:38 +0000
+++ tests/helper-test.cc 2013-12-20 17:42:31 +0000
@@ -19,6 +19,8 @@
1919
20#include <gtest/gtest.h>20#include <gtest/gtest.h>
21#include <glib/gstdio.h>21#include <glib/gstdio.h>
22#include <libdbustest/dbus-test.h>
23#include <gio/gio.h>
2224
23extern "C" {25extern "C" {
24#include "../helpers.h"26#include "../helpers.h"
@@ -31,8 +33,12 @@
31 protected:33 protected:
32 virtual void SetUp() {34 virtual void SetUp() {
33 g_setenv("XDG_DATA_DIRS", CMAKE_SOURCE_DIR, TRUE);35 g_setenv("XDG_DATA_DIRS", CMAKE_SOURCE_DIR, TRUE);
34 g_setenv("PATH", CMAKE_SOURCE_DIR, TRUE);36 const gchar * oldpath = g_getenv("PATH");
37 gchar * newpath = g_strjoin(":", CMAKE_SOURCE_DIR, oldpath, NULL);
38 g_setenv("PATH", newpath, TRUE);
39 g_free(newpath);
35 g_setenv("DATA_WRITE_DIR", CMAKE_BINARY_DIR, TRUE);40 g_setenv("DATA_WRITE_DIR", CMAKE_BINARY_DIR, TRUE);
41 g_setenv("UPSTART_JOB", "made-up-job", TRUE);
36 return;42 return;
37 }43 }
38};44};
@@ -264,18 +270,34 @@
264270
265TEST_F(HelperTest, SetConfinedEnvvars)271TEST_F(HelperTest, SetConfinedEnvvars)
266{272{
267 g_unlink(CMAKE_BINARY_DIR "/initctl-output.txt");273 DbusTestService * service = dbus_test_service_new(NULL);
274 DbusTestDbusMock * mock = dbus_test_dbus_mock_new("com.ubuntu.Upstart");
275
276 DbusTestDbusMockObject * obj = dbus_test_dbus_mock_get_object(mock, "/com/ubuntu/Upstart", "com.ubuntu.Upstart0_6", NULL);
277
278 dbus_test_dbus_mock_object_add_method(mock, obj,
279 "SetEnv",
280 G_VARIANT_TYPE("(assb)"),
281 NULL,
282 "",
283 NULL);
284
285 dbus_test_service_add_task(service, DBUS_TEST_TASK(mock));
286 dbus_test_service_start_tasks(service);
287
288 GDBusConnection * bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
289 g_dbus_connection_set_exit_on_close(bus, FALSE);
290 g_object_add_weak_pointer(G_OBJECT(bus), (gpointer *)&bus);
268291
269 /* Not a test other than "don't crash" */292 /* Not a test other than "don't crash" */
270 set_confined_envvars("foo-app-pkg", "/foo/bar");293 set_confined_envvars("foo-app-pkg", "/foo/bar");
271294
272 ASSERT_TRUE(g_file_test(CMAKE_BINARY_DIR "/initctl-output.txt", G_FILE_TEST_EXISTS));295 guint len = 0;
273296 const DbusTestDbusMockCall * calls = dbus_test_dbus_mock_object_get_method_calls(mock, obj, "SetEnv", &len, NULL);
274 gchar * contents = NULL;297
275 ASSERT_TRUE(g_file_get_contents(CMAKE_BINARY_DIR "/initctl-output.txt", &contents, NULL, NULL));298 ASSERT_EQ(len, 8);
276299 ASSERT_NE(calls, nullptr);
277 gchar ** lines = g_strsplit(contents, "\n", 0);300
278 g_free(contents);
279 unsigned int i;301 unsigned int i;
280302
281 bool got_app_isolation = false;303 bool got_app_isolation = false;
@@ -287,13 +309,13 @@
287 bool got_temp_dir = false;309 bool got_temp_dir = false;
288 bool got_shader_dir = false;310 bool got_shader_dir = false;
289311
290 for (i = 0; lines[i] != NULL; i++) {312 for (i = 0; i < len; i++) {
291 g_debug("Checking: '%s'", lines[i]);313 EXPECT_STREQ("SetEnv", calls[i].name);
292 if (lines[i][0] == '\0') continue;314
293315 GVariant * envvar = g_variant_get_child_value(calls[i].params, 1);
294 ASSERT_TRUE(g_str_has_prefix(lines[i], "set-env "));316 gchar * var = g_variant_dup_string(envvar, NULL);
295317 g_variant_unref(envvar);
296 gchar * var = lines[i] + strlen("set-env ");318
297 gchar * equal = g_strstr_len(var, -1, "=");319 gchar * equal = g_strstr_len(var, -1, "=");
298 ASSERT_NE(equal, nullptr);320 ASSERT_NE(equal, nullptr);
299321
@@ -321,13 +343,13 @@
321 ASSERT_TRUE(g_str_has_suffix(value, "foo-app-pkg"));343 ASSERT_TRUE(g_str_has_suffix(value, "foo-app-pkg"));
322 got_shader_dir = true;344 got_shader_dir = true;
323 } else {345 } else {
324 g_warning("Unknown variable! %s", lines[i]);346 g_warning("Unknown variable! %s", var);
325 ASSERT_TRUE(false);347 ASSERT_TRUE(false);
326 }348 }
349
350 g_free(var);
327 }351 }
328352
329 g_strfreev(lines);
330
331 ASSERT_TRUE(got_app_isolation);353 ASSERT_TRUE(got_app_isolation);
332 ASSERT_TRUE(got_cache_home);354 ASSERT_TRUE(got_cache_home);
333 ASSERT_TRUE(got_config_home);355 ASSERT_TRUE(got_config_home);
@@ -337,6 +359,10 @@
337 ASSERT_TRUE(got_temp_dir);359 ASSERT_TRUE(got_temp_dir);
338 ASSERT_TRUE(got_shader_dir);360 ASSERT_TRUE(got_shader_dir);
339361
362 g_object_unref(bus);
363 g_object_unref(mock);
364 g_object_unref(service);
365
340 return;366 return;
341}367}
342368
343369
=== removed file 'tests/initctl'
--- tests/initctl 2013-11-12 21:56:12 +0000
+++ tests/initctl 1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
1#!/bin/bash
2
3echo $@ >> ${DATA_WRITE_DIR}/initctl-output.txt

Subscribers

People subscribed via source and target branches