Merge lp:~ted/ubuntu-app-launch/reset-units into lp:ubuntu-app-launch

Proposed by Ted Gould
Status: Superseded
Proposed branch: lp:~ted/ubuntu-app-launch/reset-units
Merge into: lp:ubuntu-app-launch
Prerequisite: lp:~ted/ubuntu-app-launch/install-root
Diff against target: 226 lines (+109/-11)
4 files modified
libubuntu-app-launch/jobs-systemd.cpp (+61/-6)
libubuntu-app-launch/jobs-systemd.h (+2/-0)
tests/jobs-systemd.cpp (+4/-1)
tests/systemd-mock.h (+42/-4)
To merge this branch: bzr merge lp:~ted/ubuntu-app-launch/reset-units
Reviewer Review Type Date Requested Status
Indicator Applet Developers Pending
Review via email: mp+316291@code.launchpad.net

This proposal has been superseded by a proposal from 2017-02-03.

Commit message

Reset failed units so they can be tried again

To post a comment you must log in.
406. By Ted Gould

Merging future trunk

407. By Ted Gould

Add a test that catches the error

408. By Ted Gould

Check to ensure we get the reset on a failure

409. By Ted Gould

Add comment to describe the function

410. By Ted Gould

Attaching bug

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'libubuntu-app-launch/jobs-systemd.cpp'
--- libubuntu-app-launch/jobs-systemd.cpp 2017-02-02 22:54:33 +0000
+++ libubuntu-app-launch/jobs-systemd.cpp 2017-02-02 22:54:34 +0000
@@ -306,7 +306,7 @@
306 auto unsub = [&](guint& handle) {306 auto unsub = [&](guint& handle) {
307 if (handle != 0)307 if (handle != 0)
308 {308 {
309 g_dbus_connection_signal_unsubscribe(dbus_.get(), handle);309 g_dbus_connection_signal_unsubscribe(userbus_.get(), handle);
310 handle = 0;310 handle = 0;
311 }311 }
312 };312 };
@@ -425,12 +425,24 @@
425 }425 }
426 auto uris = findEnv("APP_URIS", env);426 auto uris = findEnv("APP_URIS", env);
427427
428 g_debug("Exec line: %s", exec.c_str());
429 g_debug("App URLS: %s", uris.c_str());
430
428 auto execarray = desktop_exec_parse(exec.c_str(), uris.c_str());431 auto execarray = desktop_exec_parse(exec.c_str(), uris.c_str());
429432
430 std::vector<std::string> retval = {execarray->data, execarray->data + execarray->len};433 std::vector<std::string> retval;
434 for (unsigned int i = 0; i < execarray->len; i++)
435 {
436 auto cstr = g_array_index(execarray, gchar*, i);
437 if (cstr != nullptr)
438 {
439 retval.emplace_back(cstr);
440 }
441 }
431442
432 g_array_set_clear_func(execarray, g_free);443 /* This seems to work better than array_free(), I can't figure out why */
433 g_array_free(execarray, TRUE);444 auto strv = (gchar**)g_array_free(execarray, FALSE);
445 g_strfreev(strv);
434446
435 if (retval.empty())447 if (retval.empty())
436 {448 {
@@ -786,7 +798,7 @@
786 auto retval = std::make_shared<instance::SystemD>(appId, job, instance, urls, registry);798 auto retval = std::make_shared<instance::SystemD>(appId, job, instance, urls, registry);
787 auto chelper = new StartCHelper{};799 auto chelper = new StartCHelper{};
788 chelper->ptr = retval;800 chelper->ptr = retval;
789 chelper->bus = manager->userbus_;801 chelper->bus = registry->impl->_dbus;
790802
791 tracepoint(ubuntu_app_launch, handshake_wait, appIdStr.c_str());803 tracepoint(ubuntu_app_launch, handshake_wait, appIdStr.c_str());
792 starting_handshake_wait(handshake);804 starting_handshake_wait(handshake);
@@ -1269,7 +1281,7 @@
1269 auto data = new FailedData{reg};1281 auto data = new FailedData{reg};
12701282
1271 handle_appFailed = g_dbus_connection_signal_subscribe(1283 handle_appFailed = g_dbus_connection_signal_subscribe(
1272 reg->impl->_dbus.get(), /* bus */1284 userbus_.get(), /* bus */
1273 SYSTEMD_DBUS_ADDRESS, /* sender */1285 SYSTEMD_DBUS_ADDRESS, /* sender */
1274 "org.freedesktop.DBus.Properties", /* interface */1286 "org.freedesktop.DBus.Properties", /* interface */
1275 "PropertiesChanged", /* signal */1287 "PropertiesChanged", /* signal */
@@ -1330,6 +1342,9 @@
1330 }1342 }
1331 g_variant_dict_clear(&dict);1343 g_variant_dict_clear(&dict);
13321344
1345 /* Reset the failure bit on the unit */
1346 manager->resetUnit(unitinfo);
1347
1333 /* Oh, we might want to do something now */1348 /* Oh, we might want to do something now */
1334 auto reason{Registry::FailureType::CRASH};1349 auto reason{Registry::FailureType::CRASH};
1335 if (g_strcmp0(value, "exit-code") == 0)1350 if (g_strcmp0(value, "exit-code") == 0)
@@ -1356,6 +1371,46 @@
1356 return sig_appFailed;1371 return sig_appFailed;
1357}1372}
13581373
1374void SystemD::resetUnit(const UnitInfo& info) const
1375{
1376 auto registry = registry_.lock();
1377 auto unitname = unitName(info);
1378 auto bus = userbus_;
1379 auto cancel = registry->impl->thread.getCancellable();
1380
1381 registry->impl->thread.executeOnThread([bus, unitname, cancel] {
1382 g_dbus_connection_call(bus.get(), /* user bus */
1383 SYSTEMD_DBUS_ADDRESS, /* bus name */
1384 SYSTEMD_DBUS_PATH_MANAGER, /* path */
1385 SYSTEMD_DBUS_IFACE_MANAGER, /* interface */
1386 "ResetFailedUnit", /* method */
1387 g_variant_new("(s)", /* params */
1388 unitname.c_str()), /* param: specify unit */
1389 nullptr, /* ret type */
1390 G_DBUS_CALL_FLAGS_NONE, /* flags */
1391 -1, /* timeout */
1392 cancel.get(), /* cancellable */
1393 [](GObject* obj, GAsyncResult* res, gpointer user_data) {
1394 GError* error{nullptr};
1395 GVariant* callt = g_dbus_connection_call_finish(G_DBUS_CONNECTION(obj), res, &error);
1396
1397 if (error != nullptr)
1398 {
1399 if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
1400 {
1401 g_warning("Unable to reset failed unit: %s", error->message);
1402 }
1403 g_error_free(error);
1404 return;
1405 }
1406
1407 g_clear_pointer(&callt, g_variant_unref);
1408 g_debug("Reset Failed Unit");
1409 },
1410 nullptr);
1411 });
1412}
1413
1359} // namespace manager1414} // namespace manager
1360} // namespace jobs1415} // namespace jobs
1361} // namespace app_launch1416} // namespace app_launch
13621417
=== modified file 'libubuntu-app-launch/jobs-systemd.h'
--- libubuntu-app-launch/jobs-systemd.h 2017-02-02 22:54:33 +0000
+++ libubuntu-app-launch/jobs-systemd.h 2017-02-02 22:54:34 +0000
@@ -128,6 +128,8 @@
128128
129 static std::vector<std::string> parseExec(std::list<std::pair<std::string, std::string>>& env);129 static std::vector<std::string> parseExec(std::list<std::pair<std::string, std::string>>& env);
130 static void application_start_cb(GObject* obj, GAsyncResult* res, gpointer user_data);130 static void application_start_cb(GObject* obj, GAsyncResult* res, gpointer user_data);
131
132 void resetUnit(const UnitInfo& info) const;
131};133};
132134
133} // namespace manager135} // namespace manager
134136
=== modified file 'tests/jobs-systemd.cpp'
--- tests/jobs-systemd.cpp 2017-02-02 22:54:33 +0000
+++ tests/jobs-systemd.cpp 2017-02-02 22:54:34 +0000
@@ -238,7 +238,7 @@
238 std::function<std::list<std::pair<std::string, std::string>>()> getenvfunc =238 std::function<std::list<std::pair<std::string, std::string>>()> getenvfunc =
239 [&]() -> std::list<std::pair<std::string, std::string>> {239 [&]() -> std::list<std::pair<std::string, std::string>> {
240 gotenv = true;240 gotenv = true;
241 return {};241 return {{"APP_EXEC", "sh"}};
242 };242 };
243243
244 auto inst = manager->launch(multipleAppID(), defaultJobName(), "123", {},244 auto inst = manager->launch(multipleAppID(), defaultJobName(), "123", {},
@@ -265,6 +265,9 @@
265 units.begin()->environment.end(),265 units.begin()->environment.end(),
266 units.begin()->environment.find(std::string{"DBUS_SESSION_BUS_ADDRESS="} + getenv("DBUS_SESSION_BUS_ADDRESS")));266 units.begin()->environment.find(std::string{"DBUS_SESSION_BUS_ADDRESS="} + getenv("DBUS_SESSION_BUS_ADDRESS")));
267267
268 /* Ensure the exec is correct */
269 EXPECT_EQ("/bin/sh", units.begin()->execpath);
270
268 /* Try an entirely custom variable */271 /* Try an entirely custom variable */
269 systemd->managerClear();272 systemd->managerClear();
270 units.clear();273 units.clear();
271274
=== modified file 'tests/systemd-mock.h'
--- tests/systemd-mock.h 2017-02-02 22:54:33 +0000
+++ tests/systemd-mock.h 2017-02-02 22:54:34 +0000
@@ -326,6 +326,8 @@
326 {326 {
327 std::string name;327 std::string name;
328 std::set<std::string> environment;328 std::set<std::string> environment;
329 std::string execpath;
330 std::list<std::string> execline;
329 };331 };
330332
331 std::list<TransientUnit> unitCalls()333 std::list<TransientUnit> unitCalls()
@@ -366,15 +368,16 @@
366 unit.name = name;368 unit.name = name;
367369
368 auto paramarray = g_variant_get_child_value(call.params, 2);370 auto paramarray = g_variant_get_child_value(call.params, 2);
369 gchar* key;371 gchar* ckey;
370 GVariant* var;372 GVariant* var;
371 GVariantIter iter;373 GVariantIter iter;
372 g_variant_iter_init(&iter, paramarray);374 g_variant_iter_init(&iter, paramarray);
373 while (g_variant_iter_loop(&iter, "(sv)", &key, &var))375 while (g_variant_iter_loop(&iter, "(sv)", &ckey, &var))
374 {376 {
375 g_debug("Looking at parameter: %s", key);377 g_debug("Looking at parameter: %s", ckey);
378 std::string key{ckey};
376379
377 if (std::string{key} == "Environment")380 if (key == "Environment")
378 {381 {
379 GVariantIter array;382 GVariantIter array;
380 gchar* envvar;383 gchar* envvar;
@@ -385,6 +388,41 @@
385 unit.environment.emplace(envvar);388 unit.environment.emplace(envvar);
386 }389 }
387 }390 }
391 else if (key == "ExecStart")
392 {
393 /* a(sasb) */
394 if (g_variant_n_children(var) > 1)
395 {
396 g_warning("'ExecStart' has more than one entry, only processing the first");
397 }
398
399 auto tuple = g_variant_get_child_value(var, 0);
400
401 const gchar* cpath = nullptr;
402 g_variant_get_child(tuple, 0, "&s", &cpath);
403
404 if (cpath != nullptr)
405 {
406 unit.execpath = cpath;
407 }
408 else
409 {
410 g_warning("'ExecStart[0][0]' isn't a string?");
411 }
412
413 auto vexecarray = g_variant_get_child_value(tuple, 1);
414 GVariantIter execarray;
415 g_variant_iter_init(&execarray, vexecarray);
416 const gchar* execentry;
417
418 while (g_variant_iter_loop(&execarray, "&s", &execentry))
419 {
420 unit.execline.emplace_back(execentry);
421 }
422
423 g_clear_pointer(&vexecarray, g_variant_unref);
424 g_clear_pointer(&tuple, g_variant_unref);
425 }
388 }426 }
389 g_variant_unref(paramarray);427 g_variant_unref(paramarray);
390428

Subscribers

People subscribed via source and target branches