Ejemplo n.º 1
0
static void
on_get_unit_file_state_done (GObject *object,
                             GAsyncResult *res,
                             gpointer user_data)
{
  GetServiceInfoData *data = user_data;
  GError *error = NULL;

  gs_unref_variant GVariant *result = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);
  if (error)
    {
      end_invocation_take_gerror (data->invocation, error);
      g_free (data);
      return;
    }

  const gchar *state;
  g_variant_get (result, "(&s)", &state);

  GVariantBuilder bob;
  g_variant_builder_init (&bob, G_VARIANT_TYPE("a{sv}"));

  g_variant_builder_add (&bob, "{sv}", "Id", g_variant_new_string (data->name));
  g_variant_builder_add (&bob, "{sv}", "IsTemplate", g_variant_new_boolean (TRUE));
  g_variant_builder_add (&bob, "{sv}", "UnitFileState", g_variant_new_string (state));

  cockpit_services_complete_get_service_info (COCKPIT_SERVICES (data->services), data->invocation,
                                              g_variant_builder_end (&bob));
  g_free (data->name);
  g_free (data);
}
Ejemplo n.º 2
0
static void
on_list_units_done (GObject *object,
                    GAsyncResult *res,
                    gpointer user_data)
{
  ListServicesData *data = user_data;
  GError *error = NULL;

  data->units = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);
  if (error)
    {
      end_invocation_take_gerror (data->invocation, error);
      g_free (data);
      return;
    }

  g_dbus_proxy_call (data->services->systemd,
                     "ListUnitFiles",
                     NULL,
                     G_DBUS_CALL_FLAGS_NONE,
                     G_MAXINT,
                     NULL,
                     on_list_files_done,
                     data);
}
Ejemplo n.º 3
0
static void
on_service_action_done (GObject *object,
                        GAsyncResult *res,
                        gpointer user_data)
{
  ServiceActionData *data = user_data;
  GError *error = NULL;

  gs_unref_variant GVariant *result = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);
  if (error)
    {
      end_invocation_take_gerror (data->invocation, error);
      g_free (data);
      return;
    }

  if (data->flags & FOR_FILES)
    {
      gboolean carries_install_info;
      gs_unref_variant GVariant *changes;
      if (data->flags & INSTALL_INFO)
        g_variant_get (result, "(b@a(sss))", &carries_install_info, &changes);
      else
        g_variant_get (result, "(@a(sss))", &changes);

      if ((data->flags & INSTALL_INFO) && !carries_install_info)
        {
          g_dbus_method_invocation_return_error (data->invocation,
                                                 COCKPIT_ERROR, COCKPIT_ERROR_FAILED,
                                                 "Service has not been designed to be enabled or disabled.");
          g_free (data);
          return;
        }

      g_dbus_proxy_call (data->services->systemd,
                         "Reload",
                         NULL,
                         G_DBUS_CALL_FLAGS_NONE,
                         G_MAXINT,
                         NULL,
                         on_reload_done,
                         data);
    }
  else
    {
      cockpit_services_complete_service_action (COCKPIT_SERVICES (data->services),
                                                data->invocation);
      g_free (data);
    }
}
Ejemplo n.º 4
0
static void
on_load_unit_done (GObject *object,
                   GAsyncResult *res,
                   gpointer user_data)
{
  GetServiceInfoData *data = user_data;
  GError *error = NULL;

  gs_unref_variant GVariant *result = g_dbus_proxy_call_finish (G_DBUS_PROXY(object), res, &error);
  if (error)
    {
      end_invocation_take_gerror (data->invocation, error);
      g_free (data);
      return;
    }

  const gchar *path;
  g_variant_get (result, "(&o)", &path);
  if (path)
    {
      GDBusConnection *conn = g_dbus_proxy_get_connection (data->services->systemd);
      g_dbus_connection_call (conn,
                              "org.freedesktop.systemd1",
                              path,
                              "org.freedesktop.DBus.Properties",
                              "GetAll",
                              g_variant_new ("(s)", ""),
                              G_VARIANT_TYPE ("(a{sv})"),
                              0,
                              -1,
                              NULL,
                              on_get_all_done_for_info,
                              data);
    }
  else
    {
      g_dbus_method_invocation_return_error (data->invocation,
                                             COCKPIT_ERROR, COCKPIT_ERROR_FAILED,
                                             "Heh.");
      g_free (data);
    }
}
Ejemplo n.º 5
0
static gboolean
handle_service_action (CockpitServices *object,
                       GDBusMethodInvocation *invocation,
                       const gchar *arg_name,
                       const gchar *arg_action)
{
  GError *error;
  Services *services = SERVICES (object);
  const gchar *argv[6];
  int i;
  gint status;

  const gchar *method = arg_action;
  gboolean force = FALSE;

  if (g_str_has_prefix (arg_action, "force-"))
    {
      force = TRUE;
      method = arg_action + strlen ("force-");
    }

  i = 0;
  argv[i++] = "pkexec";
  argv[i++] = "systemctl";
  if (force)
    argv[i++] = "--force";
  argv[i++] = method;
  argv[i++] = arg_name;
  argv[i++] = NULL;

  error = NULL;
  if (g_spawn_sync (NULL, (gchar**)argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, &status, &error))
    g_spawn_check_exit_status (status, &error);

  if (error)
    end_invocation_take_gerror (invocation, error);
  else
    cockpit_services_complete_service_action (COCKPIT_SERVICES (services), invocation);

  return TRUE;
}
Ejemplo n.º 6
0
static void
on_reload_done (GObject *object,
                GAsyncResult *res,
                gpointer user_data)
{
  ServiceActionData *data = user_data;
  GError *error = NULL;

  GVariant *result = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);
  if (error)
    {
      end_invocation_take_gerror (data->invocation, error);
      g_free (data);
      return;
    }

  g_variant_unref (result);
  cockpit_services_complete_service_action (COCKPIT_SERVICES (data->services),
                                            data->invocation);
  g_free (data);
}
Ejemplo n.º 7
0
static void
on_op_done (GObject *object,
            GAsyncResult *res,
            gpointer user_data)
{
  Realms *realms = REALMS (user_data);

  GError *error = NULL;
  GVariant *join_result = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);

  if (error)
    end_invocation_take_gerror (realms, error);
  else
    {
      if (strcmp (realms->op, "Join") == 0)
        cockpit_realms_complete_join (COCKPIT_REALMS (realms), realms->op_invocation);
      else
        cockpit_realms_complete_leave (COCKPIT_REALMS (realms), realms->op_invocation);
      clear_invocation (realms);
      g_variant_unref (join_result);
    }
}
Ejemplo n.º 8
0
static void
on_get_all_done_for_info (GObject *object,
                          GAsyncResult *res,
                          gpointer user_data)
{
  GetServiceInfoData *data = user_data;
  GError *error = NULL;
  gs_unref_variant GVariant *reply = g_dbus_connection_call_finish (G_DBUS_CONNECTION (object), res, &error);

  if (error)
    {
      end_invocation_take_gerror (data->invocation, error);
      g_free (data);
      return;
    }

  gs_unref_variant GVariant *props;
  g_variant_get (reply, "(@a{sv})", &props);

  GVariantBuilder bob;
  g_variant_builder_init (&bob, G_VARIANT_TYPE("a{sv}"));

  copy_entry (&bob, props, "Id");
  copy_entry (&bob, props, "Description");
  copy_entry (&bob, props, "LoadState");
  copy_entry (&bob, props, "ActiveState");
  copy_entry (&bob, props, "SubState");
  copy_entry (&bob, props, "UnitFileState");
  copy_entry (&bob, props, "ExecMainStartTimestamp");
  copy_entry (&bob, props, "ExecMainExitTimestamp");
  copy_entry (&bob, props, "ActiveEnterTimestamp");
  copy_entry (&bob, props, "ActiveExitTimestamp");
  copy_entry (&bob, props, "InactiveEnterTimestamp");
  copy_entry (&bob, props, "InactiveExitTimestamp");
  copy_entry (&bob, props, "ConditionTimestamp");
  copy_entry (&bob, props, "SourcePath");
  copy_entry (&bob, props, "FragmentPath");
  copy_entry (&bob, props, "LoadError");
  copy_entry (&bob, props, "ConditionResult");
  copy_entry (&bob, props, "StatusText");
  copy_entry (&bob, props, "DefaultControlGroup");

  const gchar *id = NULL, *cgroup = NULL;
  uint32_t main_pid = 0, exec_main_pid = 0, control_pid = 0;

  g_variant_lookup (props, "Id", "&s", &id);
  g_variant_lookup (props, "DefaultControlGroup", "&s", &cgroup);
  g_variant_lookup (props, "ExecMainPid", "u", &exec_main_pid);
  g_variant_lookup (props, "MainPid", "u", &main_pid);
  g_variant_lookup (props, "ControlPid", "u", &control_pid);

  if (cgroup)
    {
      pid_t extra_pids[3];
      int n_extra_pids = 0;
      if (main_pid > 0)
        extra_pids[n_extra_pids++] = main_pid;
      if (exec_main_pid > 0)
        extra_pids[n_extra_pids++] = exec_main_pid;
      if (control_pid > 0)
        extra_pids[n_extra_pids++] = control_pid;

      GVariant *c = collect_cgroup_and_extra_by_spec (cgroup, FALSE, TRUE, extra_pids, n_extra_pids);
      if (c)
        g_variant_builder_add (&bob, "{sv}", "Processes", c);
    }

  cockpit_services_complete_get_service_info (COCKPIT_SERVICES (data->services), data->invocation,
                                              g_variant_builder_end (&bob));
  g_free (data);
}
Ejemplo n.º 9
0
static void
on_list_files_done (GObject *object,
                    GAsyncResult *res,
                    gpointer user_data)
{
  ListServicesData *data = user_data;
  GError *error = NULL;

  data->files = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);
  if (error)
    {
      end_invocation_take_gerror (data->invocation, error);
      g_variant_unref (data->units);
      g_free (data);
      return;
    }

  data->result = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, listed_service_free);

  gs_free_variant_iter GVariantIter *unit_iter = NULL;
  const gchar *name, *description, *load_state, *active_state, *sub_state, *file_state;

  g_variant_get (data->units, "(a*)", &unit_iter);
  while (g_variant_iter_next (unit_iter, "(&s&s&s&s&s&s&ou&s&o)",
                              &name,
                              &description,
                              &load_state,
                              &active_state,
                              &sub_state,
                              NULL,   // follow unit
                              NULL,   // object path
                              NULL,   // job id
                              NULL,   // job type
                              NULL))  // job object path
    {
      if (!g_hash_table_lookup (data->result, name))
        {
          ListedService *s = listed_service_new ();
          s->name = name;
          s->description = description;
          s->load_state = load_state;
          s->active_state = active_state;
          s->sub_state = sub_state;
          s->file_state = "";
          g_hash_table_insert (data->result, (void *)name, s);
        }
    }

  gs_free_variant_iter GVariantIter *file_iter = NULL;

  g_variant_get (data->files, "(a*)", &file_iter);
  while (g_variant_iter_next (file_iter, "(&s&s)", &name, &file_state))
    {
      gchar *base = g_path_get_basename (name);
      ListedService *s = g_hash_table_lookup (data->result, base);
      if (s)
        s->file_state = file_state;
      else
        {
          ListedService *s = listed_service_new ();
          s->name = base;
          s->description = get_service_description (name);
          s->load_state = "";
          s->active_state = "";
          s->sub_state = "";
          s->file_state = file_state;
          s->needs_free = TRUE;
          g_hash_table_insert (data->result, (void *)base, s);
        }
    }

  GVariantBuilder bob;
  g_variant_builder_init (&bob, G_VARIANT_TYPE("a(ssssss)"));
  g_hash_table_foreach (data->result, add_listed_service_to_builder, &bob);

  cockpit_services_complete_list_services (COCKPIT_SERVICES (data->services), data->invocation,
                                           g_variant_builder_end (&bob));

  g_variant_unref (data->units);
  g_variant_unref (data->files);
  g_hash_table_destroy (data->result);
  g_free (data);
}
Ejemplo n.º 10
0
static void
on_discover_for_op_done (GObject *object,
                         GAsyncResult *res,
                         gpointer user_data)
{
  Realms *realms = REALMS (user_data);

  if (realms->op_cancelled)
    {
      end_invocation_with_error (realms, COCKPIT_ERROR_CANCELLED,
                                 "Cancelled");
      return;
    }

  GError *error = NULL;
  gs_unref_variant GVariant *discover_result = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);
  if (error)
    {
      end_invocation_take_gerror (realms, error);
      return;
    }

  gs_free_variant_iter GVariantIter *object_paths = NULL;
  g_variant_get (discover_result, "(iao)", NULL, &object_paths);

  const gchar *first_object = NULL;
  if (!g_variant_iter_next (object_paths, "&o", &first_object))
    {
      end_invocation_with_error (realms, COCKPIT_ERROR_NO_SUCH_REALM,
                                 "No such realm: %s", realms->op_name);
      return;
    }

  gs_unref_object GDBusProxy *kerberos =
    g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
                                   (G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES
                                    | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS),
                                   NULL,
                                   "org.freedesktop.realmd",
                                   first_object,
                                   "org.freedesktop.realmd.KerberosMembership",
                                   NULL,
                                   &error);
  if (error)
    {
      end_invocation_take_gerror (realms, error);
      return;
    }

  GVariant *creds = translate_kerberos_credentials (realms->op_creds);

  GVariantBuilder options;
  g_variant_builder_init (&options, G_VARIANT_TYPE ("a{sv}"));

  copy_option (&options, realms->op_options, "computer-ou");
  g_variant_builder_add (&options, "{sv}",
                         "operation", g_variant_new_string (realms->op_id));

  g_dbus_proxy_call (kerberos,
                     realms->op,
                     g_variant_new ("(@(ssv)a{sv})", creds, &options),
                     G_DBUS_CALL_FLAGS_NONE,
                     G_MAXINT,
                     NULL,
                     on_op_done,
                     realms);
}