Example #1
0
/*!
 * Handle commands to toggle the state of the Hypervisor
 * (between paused and running).
 *
 * \param sub \ref subcommand.
 * \param config \ref cc_oci_config.
 * \param argc Argument count.
 * \param argv Argument vector.
 * \param pause If \c true, pause the VM, else resume it.
 *
 * \return \c true on success, else \c false.
 */
gboolean
handle_command_toggle (const struct subcommand *sub,
		struct cc_oci_config *config,
		int argc, char *argv[], gboolean pause)
{
	struct oci_state      *state = NULL;
	gchar                 *config_file = NULL;
	gboolean               ret;
	const gchar           *action;

	g_assert (sub);
	g_assert (config);

	action = pause ? "pause" : "resume";

	if (handle_default_usage (argc, argv, sub->name,
				&ret, 1, NULL)) {
		return ret;
	}

	/* Used to allow us to find the state file */
	config->optarg_container_id = argv[0];

	ret = cc_oci_get_config_and_state (&config_file, config, &state);
	if (! ret) {
		goto out;
	}

	/* Transfer certain state elements to config to allow the state *
	 * file to be rewritten with full details.
	 */
	if (! cc_oci_config_update (config, state)) {
		goto out;
	}

	ret = cc_oci_toggle (config, state, pause);
	if (! ret) {
		goto out;
	}

	ret = true;

	g_print ("%sd container %s\n", action,
			config->optarg_container_id);

out:
	g_free_if_set (config_file);
	cc_oci_state_free (state);

	if (! ret) {
		g_critical ("failed to %s container %s\n",
				action, config->optarg_container_id);
	}

	return ret;
}
Example #2
0
/*!
 * Determine the containers config file, its configuration
 * and state.
 *
 * \param[out] config_file Dynamically-allocated path to containers
 * config file.
 * \param[out] config \ref cc_oci_config.
 * \param[out] state \ref oci_state.
 *
 * \note Used by the "stop" command.
 *
 * \return \c true on success, else \c false.
 */
gboolean
cc_oci_get_config_and_state (gchar **config_file,
		struct cc_oci_config *config,
		struct oci_state **state)
{
	if ((!config_file) || (!config) || (!state)) {
		return false;
	}

	if (! cc_oci_runtime_path_get (config)) {
			return false;
	}

	if (! cc_oci_state_file_get (config)) {
		return false;
	}

	*state = cc_oci_state_file_read (config->state.state_file_path);
	if (! (*state)) {
		g_critical("failed to read state file for container %s",
		           config->optarg_container_id);
		goto err;
	}

	/* Fill in further details to make the config valid */
	config->bundle_path = g_strdup ((*state)->bundle_path);
	config->state.workload_pid = (*state)->pid;
	config->state.status = (*state)->status;

	g_strlcpy (config->state.comms_path, (*state)->comms_path,
			sizeof (config->state.comms_path));

	g_strlcpy (config->state.procsock_path,
			(*state)->procsock_path,
			sizeof (config->state.procsock_path));

	*config_file = cc_oci_config_file_path ((*state)->bundle_path);
	if (! (*config_file)) {
		goto err;
	}

	return true;

err:
	cc_oci_state_free (*state);
	g_free_if_set (*config_file);
	return false;
}
Example #3
0
} END_TEST

START_TEST(test_cc_oci_state_free) {
	struct oci_state *state = g_new0 (struct oci_state, 1);
	ck_assert(state);

	state->bundle_path = g_strdup("bundle_path");
	state->comms_path = g_strdup("comms_path");
	state->procsock_path = g_strdup("procsock_path");
	state->id = g_strdup("id");
	state->oci_version = g_strdup("oci_version");
	state->mounts = g_slist_append(state->mounts, g_new0(struct cc_oci_mount, 1));
	state->annotations = g_slist_append(state->annotations, g_new0(struct oci_cfg_annotation, 1));

	/* memory leaks will be detected by valgrind */
	cc_oci_state_free(state);
} END_TEST
Example #4
0
/*!
 * Handle commands to stop the Hypervisor cleanly.
 *
 * \param sub \ref subcommand.
 * \param config \ref cc_oci_config.
 * \param argc Argument count.
 * \param argv Argument vector.
 *
 * \return \c true on success, else \c false.
 */
gboolean
handle_command_stop (const struct subcommand *sub,
		struct cc_oci_config *config,
		int argc, char *argv[])
{
	struct oci_state  *state = NULL;
	gchar             *config_file = NULL;
	gboolean           ret;
	GNode*             root = NULL;

	g_assert (sub);
	g_assert (config);

	if (handle_default_usage (argc, argv, sub->name,
				&ret, 1, NULL)) {
		return ret;
	}

	/* Used to allow us to find the state file */
	config->optarg_container_id = argv[0];

	/* FIXME: deal with containerd calling "delete" twice */
	if (! cc_oci_state_file_exists (config)) {
		g_warning ("state file does not exist for container %s",
				config->optarg_container_id);

		/* don't make this fatal to keep containerd happy */
		ret = true;
		goto out;
	}

	ret = cc_oci_get_config_and_state (&config_file, config, &state);
	if (! ret) {
		goto out;
	}

	/* convert json file to GNode */
	if (! cc_oci_json_parse(&root, config_file)) {
		goto out;
	}

#ifdef DEBUG
	/* show json file converted to GNode */
	cc_oci_node_dump(root);
#endif /*DEBUG*/

	if (! cc_oci_process_config(root, config, stop_spec_handlers)) {
		g_critical ("failed to process config");
		goto out;
	}

	g_free_node(root);

	ret = cc_oci_stop (config, state);
	if (! ret) {
		goto out;
	}

	ret = true;

	g_print ("stopped container %s\n", config->optarg_container_id);

out:
	g_free_if_set (config_file);
	cc_oci_state_free (state);

	if (! ret) {
		g_critical ("failed to stop container %s\n",
				config->optarg_container_id);
	}

	return ret;
}
Example #5
0
} END_TEST


START_TEST(test_cc_oci_state_file_read) {
	struct oci_state *state = NULL;

	/* Needs:
	 *
	 * - ociVersion
	 * - id
	 * - pid
	 * - bundlePath
	 * - commsPath
	 * - processPath
	 * - status
	 */

	ck_assert(! cc_oci_state_file_read(NULL));

	ck_assert(! cc_oci_state_file_read("/abc/123/xyz"));

	ck_assert(! cc_oci_state_file_read(TEST_DATA_DIR
	                "/state-no-bundlePath.json"));

	ck_assert(! cc_oci_state_file_read(TEST_DATA_DIR
	                "/state-no-ociVersion.json"));

	ck_assert(! cc_oci_state_file_read(TEST_DATA_DIR
	                "/state-no-id.json"));

	ck_assert(! cc_oci_state_file_read(TEST_DATA_DIR
	                "/state-no-commsPath.json"));

	ck_assert(! cc_oci_state_file_read(TEST_DATA_DIR
	                "/state-no-processPath.json"));

	ck_assert(! cc_oci_state_file_read(TEST_DATA_DIR
	                "/state-no-console.json"));

	ck_assert(! cc_oci_state_file_read(TEST_DATA_DIR
	                "/state-no-console-path.json"));

	ck_assert(! cc_oci_state_file_read(TEST_DATA_DIR
	                "/state-no-console-socket.json"));

	ck_assert(! cc_oci_state_file_read(TEST_DATA_DIR
	                "/state-no-vm-object.json"));

	/* Annotations are optional*/
	state = cc_oci_state_file_read(TEST_DATA_DIR
	                "/state-no-annotations.json");
	ck_assert (state);
	cc_oci_state_free (state);

	/* Mounts are optional */
	state = cc_oci_state_file_read(TEST_DATA_DIR
	                "/state-no-mounts.json");
	ck_assert (state);
	cc_oci_state_free (state);

	state = cc_oci_state_file_read(TEST_DATA_DIR
	                "/state-mounts-no-mount-destination.json");
	ck_assert (state);
	cc_oci_state_free (state);

	state = cc_oci_state_file_read(TEST_DATA_DIR
	                "/state-mounts-no-mount-directory_created.json");
	ck_assert (state);
	cc_oci_state_free (state);

	state = cc_oci_state_file_read(TEST_DATA_DIR "/state.json");
	ck_assert(state);
	ck_assert(state->oci_version);
	ck_assert(state->id);
	ck_assert(state->pid);
	ck_assert(state->bundle_path);
	ck_assert(state->comms_path);
	ck_assert(state->procsock_path);
	ck_assert(state->status);
	ck_assert(state->annotations);
	cc_oci_state_free(state);

} END_TEST