run.c revision 8159d91a9c92aaee66d450ab0daff88f6e1a42b3
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering/***
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering This file is part of systemd.
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering Copyright 2013 Lennart Poettering
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering systemd is free software; you can redistribute it and/or modify it
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering under the terms of the GNU Lesser General Public License as published by
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering (at your option) any later version.
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering systemd is distributed in the hope that it will be useful, but
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering Lesser General Public License for more details.
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering You should have received a copy of the GNU Lesser General Public License
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering***/
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering#include <stdio.h>
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include <getopt.h>
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering#include "sd-bus.h"
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poettering#include "bus-util.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "strv.h"
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "build.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "unit-name.h"
40ca29a1370379d43e44c0ed425eecc7218dcbcaLennart Poettering#include "path-util.h"
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering#include "bus-error.h"
4de33e7f3238a6fe616e61139ab87e221572e5e5Lennart Poettering
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poetteringstatic bool arg_scope = false;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringstatic bool arg_remain_after_exit = false;
cf0fbc49e67b55f8d346fc94de28c90113505297Thomas Hindoe Paaboel Andersenstatic const char *arg_unit = NULL;
4bcc8c3cb57733de6eeb2528a194501fade11e6bZbigniew Jędrzejewski-Szmekstatic const char *arg_description = NULL;
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poetteringstatic const char *arg_slice = NULL;
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poetteringstatic bool arg_send_sighup = false;
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchaginstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poetteringstatic char *arg_host = NULL;
66cb2fde7b0ab6603775ad13c30c004f5fd88f0cLennart Poetteringstatic bool arg_user = false;
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering
b1d4f8e154bf61b5de1b27461ef8e9c8c5e838a1Lennart Poetteringstatic int help(void) {
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin printf("%s [OPTIONS...] COMMAND [ARGS...]\n\n"
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering "Run the specified command in a transient scope or service unit.\n\n"
6577c7cea72f19185ad999c223bcf663c010dc6fLennart Poettering " -h --help Show this help\n"
3d161f991e16369aa59f447eb4cdb90af33261c8Lennart Poettering " --version Show package version\n"
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering " --user Run as user unit\n"
9f2e86af0600e99cff00d1c92f9bb8d38f29896aLennart Poettering " -H --host=[USER@]HOST Operate on remote host\n"
c221420be8744bb0f8b8a8145efc1f247f1aa801Lennart Poettering " -M --machine=CONTAINER Operate on local container\n"
a6c0353b9268d5b780fb7ff05a10cb5031446e5dLennart Poettering " --scope Run this as scope rather than service\n"
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering " --unit=UNIT Run under the specified unit name\n"
1ac67edb7c4d31a287fa98c0b554ae98bd34e71bLennart Poettering " --description=TEXT Description for unit\n"
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering " --slice=SLICE Run in the specified slice\n"
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering " -r --remain-after-exit Leave service around until explicitly stopped\n"
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering " --send-sighup Send SIGHUP when terminating\n",
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering program_invocation_short_name);
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering return 0;
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering}
df31a6c0fe07805cb50045fbe91c2a6e7e430562Lennart Poettering
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho enum {
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho ARG_VERSION = 0x100,
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho ARG_USER,
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho ARG_SYSTEM,
024a8ec137f17cbbc22256ef4aa7f99ec671dbc5Lennart Poettering ARG_SCOPE,
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho ARG_UNIT,
095dc59660c3dde782f32fe5a52b577f7700578bLennart Poettering ARG_DESCRIPTION,
c2756a68401102786be343712c0c35acbd73d28dLennart Poettering ARG_SLICE,
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin ARG_SEND_SIGHUP,
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin };
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin static const struct option options[] = {
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin { "help", no_argument, NULL, 'h' },
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin { "version", no_argument, NULL, ARG_VERSION },
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin { "user", no_argument, NULL, ARG_USER },
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin { "system", no_argument, NULL, ARG_SYSTEM },
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin { "scope", no_argument, NULL, ARG_SCOPE },
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin { "unit", required_argument, NULL, ARG_UNIT },
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin { "description", required_argument, NULL, ARG_DESCRIPTION },
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin { "slice", required_argument, NULL, ARG_SLICE },
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek { "remain-after-exit", no_argument, NULL, 'r' },
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho { "send-sighup", no_argument, NULL, ARG_SEND_SIGHUP },
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho { "host", required_argument, NULL, 'H' },
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho { "machine", required_argument, NULL, 'M' },
cd32b977facd20145f570efbfdf541ffc2780c4eZbigniew Jędrzejewski-Szmek {},
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho };
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin int c;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho assert(argc >= 0);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho assert(argv);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho while ((c = getopt_long(argc, argv, "+hrH:M:", options, NULL)) >= 0) {
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho switch (c) {
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
3d161f991e16369aa59f447eb4cdb90af33261c8Lennart Poettering case 'h':
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return help();
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho case ARG_VERSION:
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho puts(PACKAGE_STRING);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho puts(SYSTEMD_FEATURES);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return 0;
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poettering
095dc59660c3dde782f32fe5a52b577f7700578bLennart Poettering case ARG_USER:
095dc59660c3dde782f32fe5a52b577f7700578bLennart Poettering arg_user = true;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho break;
b57b06258e0b1894edb6d1fc52a80b3c33164892Zbigniew Jędrzejewski-Szmek
b57b06258e0b1894edb6d1fc52a80b3c33164892Zbigniew Jędrzejewski-Szmek case ARG_SYSTEM:
b57b06258e0b1894edb6d1fc52a80b3c33164892Zbigniew Jędrzejewski-Szmek arg_user = false;
b57b06258e0b1894edb6d1fc52a80b3c33164892Zbigniew Jędrzejewski-Szmek break;
b57b06258e0b1894edb6d1fc52a80b3c33164892Zbigniew Jędrzejewski-Szmek
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho case ARG_SCOPE:
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho arg_scope = true;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering break;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering case ARG_UNIT:
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho arg_unit = optarg;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho break;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho case ARG_DESCRIPTION:
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering arg_description = optarg;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering break;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering case ARG_SLICE:
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin arg_slice = optarg;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering break;
66b1e746055b9c56fd72c0451a4cfb2b06cf3f20Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering case ARG_SEND_SIGHUP:
9f2e86af0600e99cff00d1c92f9bb8d38f29896aLennart Poettering arg_send_sighup = true;
c221420be8744bb0f8b8a8145efc1f247f1aa801Lennart Poettering break;
a6c0353b9268d5b780fb7ff05a10cb5031446e5dLennart Poettering
a6c0353b9268d5b780fb7ff05a10cb5031446e5dLennart Poettering case 'r':
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering arg_remain_after_exit = true;
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering break;
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering case 'H':
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho arg_transport = BUS_TRANSPORT_REMOTE;
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poettering arg_host = optarg;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho break;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho case 'M':
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho arg_transport = BUS_TRANSPORT_CONTAINER;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho arg_host = optarg;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho break;
3d161f991e16369aa59f447eb4cdb90af33261c8Lennart Poettering
3d161f991e16369aa59f447eb4cdb90af33261c8Lennart Poettering case '?':
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering return -EINVAL;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering default:
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho assert_not_reached("Unhandled option");
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho }
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho }
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (optind >= argc) {
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho log_error("Command line to execute required.");
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return -EINVAL;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho }
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (arg_user && arg_transport != BUS_TRANSPORT_LOCAL) {
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho log_error("Execution in user context is not supported on non-local systems.");
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return -EINVAL;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho }
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (arg_scope && arg_transport != BUS_TRANSPORT_LOCAL) {
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho log_error("Scope execution is not supported on non-local systems.");
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return -EINVAL;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho }
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poettering
095dc59660c3dde782f32fe5a52b577f7700578bLennart Poettering return 1;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho}
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Chostatic int message_start_transient_unit_new(sd_bus *bus, const char *name, sd_bus_message **ret) {
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho int r;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho assert(bus);
3d161f991e16369aa59f447eb4cdb90af33261c8Lennart Poettering assert(name);
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin assert(ret);
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering log_info("Running as unit %s.", name);
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering r = sd_bus_message_new_method_call(
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering bus,
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering "org.freedesktop.systemd1",
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering "/org/freedesktop/systemd1",
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering "org.freedesktop.systemd1.Manager",
095dc59660c3dde782f32fe5a52b577f7700578bLennart Poettering "StartTransientUnit", &m);
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering if (r < 0)
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering return r;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering r = sd_bus_message_append(m, "ss", name, "fail");
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek if (r < 0)
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek return r;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin r = sd_bus_message_open_container(m, 'a', "(sv)");
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin if (r < 0)
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin return r;
8c7db2fb2186277f9572d58b664cc59792ee4f50Evgeny Vereshchagin
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering r = sd_bus_message_append(m, "(sv)", "Description", "s", arg_description);
3f6fd1ba65f962702753c4ad284b588e59689a23Lennart Poettering if (r < 0)
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering return r;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering if (!isempty(arg_slice)) {
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering _cleanup_free_ char *slice;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
66b1e746055b9c56fd72c0451a4cfb2b06cf3f20Lennart Poettering slice = unit_name_mangle_with_suffix(arg_slice, ".slice");
66b1e746055b9c56fd72c0451a4cfb2b06cf3f20Lennart Poettering if (!slice)
66b1e746055b9c56fd72c0451a4cfb2b06cf3f20Lennart Poettering return -ENOMEM;
66b1e746055b9c56fd72c0451a4cfb2b06cf3f20Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering if (r < 0)
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering return r;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering }
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", arg_send_sighup);
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering if (r < 0)
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering return r;
9f2e86af0600e99cff00d1c92f9bb8d38f29896aLennart Poettering
9f2e86af0600e99cff00d1c92f9bb8d38f29896aLennart Poettering *ret = m;
9f2e86af0600e99cff00d1c92f9bb8d38f29896aLennart Poettering m = NULL;
9f2e86af0600e99cff00d1c92f9bb8d38f29896aLennart Poettering
c221420be8744bb0f8b8a8145efc1f247f1aa801Lennart Poettering return 0;
c221420be8744bb0f8b8a8145efc1f247f1aa801Lennart Poettering}
c221420be8744bb0f8b8a8145efc1f247f1aa801Lennart Poettering
c221420be8744bb0f8b8a8145efc1f247f1aa801Lennart Poetteringstatic int message_start_transient_unit_send(sd_bus *bus, sd_bus_message *m, sd_bus_error *error, sd_bus_message **reply) {
a6c0353b9268d5b780fb7ff05a10cb5031446e5dLennart Poettering int r;
a6c0353b9268d5b780fb7ff05a10cb5031446e5dLennart Poettering
a6c0353b9268d5b780fb7ff05a10cb5031446e5dLennart Poettering assert(bus);
a6c0353b9268d5b780fb7ff05a10cb5031446e5dLennart Poettering assert(m);
6577c7cea72f19185ad999c223bcf663c010dc6fLennart Poettering
6577c7cea72f19185ad999c223bcf663c010dc6fLennart Poettering r = sd_bus_message_close_container(m);
6577c7cea72f19185ad999c223bcf663c010dc6fLennart Poettering if (r < 0)
6577c7cea72f19185ad999c223bcf663c010dc6fLennart Poettering return r;
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering return sd_bus_send_with_reply_and_block(bus, m, 0, error, reply);
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering}
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poetteringstatic int start_transient_service(
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering sd_bus *bus,
de33fc625725d199629ed074d6278504deb23debLennart Poettering char **argv,
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering sd_bus_error *error) {
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering _cleanup_free_ char *name = NULL;
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering char **i;
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering int r;
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering if (arg_unit)
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering name = unit_name_mangle_with_suffix(arg_unit, ".service");
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering else
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering asprintf(&name, "run-%lu.service", (unsigned long) getpid());
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering if (!name)
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering return -ENOMEM;
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering r = message_start_transient_unit_new(bus, name, &m);
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering if (r < 0)
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering return r;
1ac67edb7c4d31a287fa98c0b554ae98bd34e71bLennart Poettering
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering r = sd_bus_message_append(m, "(sv)", "RemainAfterExit", "b", arg_remain_after_exit);
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering if (r < 0)
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering return r;
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering r = sd_bus_message_open_container(m, 'r', "sv");
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering if (r < 0)
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering return r;
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering r = sd_bus_message_append(m, "s", "ExecStart");
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering if (r < 0)
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering return r;
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering r = sd_bus_message_open_container(m, 'v', "a(sasb)");
df31a6c0fe07805cb50045fbe91c2a6e7e430562Lennart Poettering if (r < 0)
df31a6c0fe07805cb50045fbe91c2a6e7e430562Lennart Poettering return r;
df31a6c0fe07805cb50045fbe91c2a6e7e430562Lennart Poettering
df31a6c0fe07805cb50045fbe91c2a6e7e430562Lennart Poettering r = sd_bus_message_open_container(m, 'a', "(sasb)");
df31a6c0fe07805cb50045fbe91c2a6e7e430562Lennart Poettering if (r < 0)
df31a6c0fe07805cb50045fbe91c2a6e7e430562Lennart Poettering return r;
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poettering
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poettering r = sd_bus_message_open_container(m, 'r', "sasb");
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poettering if (r < 0)
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poettering return r;
095dc59660c3dde782f32fe5a52b577f7700578bLennart Poettering
095dc59660c3dde782f32fe5a52b577f7700578bLennart Poettering r = sd_bus_message_append(m, "s", argv[0]);
095dc59660c3dde782f32fe5a52b577f7700578bLennart Poettering if (r < 0)
095dc59660c3dde782f32fe5a52b577f7700578bLennart Poettering return r;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho r = sd_bus_message_open_container(m, 'a', "s");
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (r < 0)
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return r;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho STRV_FOREACH(i, argv) {
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho r = sd_bus_message_append(m, "s", *i);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (r < 0)
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return r;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho }
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho r = sd_bus_message_close_container(m);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (r < 0)
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return r;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho r = sd_bus_message_append(m, "b", false);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (r < 0)
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return r;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho r = sd_bus_message_close_container(m);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (r < 0)
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return r;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho r = sd_bus_message_close_container(m);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (r < 0)
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return r;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho r = sd_bus_message_close_container(m);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (r < 0)
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return r;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho r = sd_bus_message_close_container(m);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (r < 0)
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return r;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return message_start_transient_unit_send(bus, m, error, NULL);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho}
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Chostatic int start_transient_scope(
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho sd_bus *bus,
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho char **argv,
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho sd_bus_error *error) {
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho _cleanup_free_ char *name = NULL;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho int r;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho assert(bus);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (arg_unit)
024a8ec137f17cbbc22256ef4aa7f99ec671dbc5Lennart Poettering name = unit_name_mangle_with_suffix(arg_unit, ".scope");
024a8ec137f17cbbc22256ef4aa7f99ec671dbc5Lennart Poettering else
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho asprintf(&name, "run-%lu.scope", (unsigned long) getpid());
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (!name)
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return -ENOMEM;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho r = message_start_transient_unit_new(bus, name, &m);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (r < 0)
024a8ec137f17cbbc22256ef4aa7f99ec671dbc5Lennart Poettering return r;
024a8ec137f17cbbc22256ef4aa7f99ec671dbc5Lennart Poettering
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho r = sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, (uint32_t) getpid());
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (r < 0)
024a8ec137f17cbbc22256ef4aa7f99ec671dbc5Lennart Poettering return r;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho r = message_start_transient_unit_send(bus, m, error, NULL);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (r < 0)
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return r;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho execvp(argv[0], argv);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho log_error("Failed to execute: %m");
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return -errno;
3d161f991e16369aa59f447eb4cdb90af33261c8Lennart Poettering}
3d161f991e16369aa59f447eb4cdb90af33261c8Lennart Poettering
3d161f991e16369aa59f447eb4cdb90af33261c8Lennart Poetteringint main(int argc, char* argv[]) {
3d161f991e16369aa59f447eb4cdb90af33261c8Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering _cleanup_bus_unref_ sd_bus *bus = NULL;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering _cleanup_free_ char *description = NULL, *command = NULL;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering int r;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering log_parse_environment();
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering log_open();
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho r = parse_argv(argc, argv);
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering if (r <= 0)
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering goto finish;
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering
6c12b52e19640747e96f89d85422941a23dc6b29Lennart Poettering r = find_binary(argv[optind], &command);
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering if (r < 0) {
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering log_error("Failed to find executable %s: %s", argv[optind], strerror(-r));
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering goto finish;
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering }
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering argv[optind] = command;
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering if (!arg_description) {
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering description = strv_join(argv + optind, " ");
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering if (!description) {
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering r = log_oom();
4de33e7f3238a6fe616e61139ab87e221572e5e5Lennart Poettering goto finish;
4de33e7f3238a6fe616e61139ab87e221572e5e5Lennart Poettering }
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering arg_description = description;
c7040b5d1c2c148f12b6a5eef3dfce1661805131Lennart Poettering }
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poettering
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poettering r = bus_open_transport(arg_transport, arg_host, arg_user, &bus);
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poettering if (r < 0) {
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poettering log_error("Failed to create bus connection: %s", strerror(-r));
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poettering goto finish;
024a8ec137f17cbbc22256ef4aa7f99ec671dbc5Lennart Poettering }
024a8ec137f17cbbc22256ef4aa7f99ec671dbc5Lennart Poettering
024a8ec137f17cbbc22256ef4aa7f99ec671dbc5Lennart Poettering if (arg_scope)
024a8ec137f17cbbc22256ef4aa7f99ec671dbc5Lennart Poettering r = start_transient_scope(bus, argv + optind, &error);
024a8ec137f17cbbc22256ef4aa7f99ec671dbc5Lennart Poettering else
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho r = start_transient_service(bus, argv + optind, &error);
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho if (r < 0)
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho log_error("Failed start transient unit: %s", bus_error_message(&error, r));
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Chofinish:
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho}
4c213d6cf416917c61f82d8bee795b8f3a4c5372WaLyong Cho