mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-10 07:00:53 +00:00
podman: include image layers in overlay
We want the image layers so we can find the files in the base image correctly.
This commit is contained in:
@ -74,6 +74,7 @@ struct _SysprofPodman
|
|||||||
{
|
{
|
||||||
JsonParser *containers_parser;
|
JsonParser *containers_parser;
|
||||||
JsonParser *layers_parser;
|
JsonParser *layers_parser;
|
||||||
|
JsonParser *images_parser;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -81,6 +82,7 @@ sysprof_podman_free (SysprofPodman *self)
|
|||||||
{
|
{
|
||||||
g_clear_object (&self->containers_parser);
|
g_clear_object (&self->containers_parser);
|
||||||
g_clear_object (&self->layers_parser);
|
g_clear_object (&self->layers_parser);
|
||||||
|
g_clear_object (&self->images_parser);
|
||||||
g_slice_free (SysprofPodman, self);
|
g_slice_free (SysprofPodman, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +118,22 @@ load_layers (SysprofPodman *self)
|
|||||||
json_parser_load_from_file (self->layers_parser, path, NULL);
|
json_parser_load_from_file (self->layers_parser, path, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
load_images (SysprofPodman *self)
|
||||||
|
{
|
||||||
|
g_autofree char *path = NULL;
|
||||||
|
|
||||||
|
g_assert (self != NULL);
|
||||||
|
|
||||||
|
path = g_build_filename (g_get_user_data_dir (),
|
||||||
|
"containers",
|
||||||
|
"storage",
|
||||||
|
"overlay-images",
|
||||||
|
"images.json",
|
||||||
|
NULL);
|
||||||
|
json_parser_load_from_file (self->images_parser, path, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
SysprofPodman *
|
SysprofPodman *
|
||||||
sysprof_podman_snapshot_current_user (void)
|
sysprof_podman_snapshot_current_user (void)
|
||||||
{
|
{
|
||||||
@ -124,17 +142,57 @@ sysprof_podman_snapshot_current_user (void)
|
|||||||
self = g_slice_new0 (SysprofPodman);
|
self = g_slice_new0 (SysprofPodman);
|
||||||
self->containers_parser = json_parser_new ();
|
self->containers_parser = json_parser_new ();
|
||||||
self->layers_parser = json_parser_new ();
|
self->layers_parser = json_parser_new ();
|
||||||
|
self->images_parser = json_parser_new ();
|
||||||
|
|
||||||
load_containers (self);
|
load_containers (self);
|
||||||
load_layers (self);
|
load_layers (self);
|
||||||
|
load_images (self);
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
find_image_layer (JsonParser *parser,
|
||||||
|
const char *image)
|
||||||
|
{
|
||||||
|
JsonNode *root;
|
||||||
|
JsonArray *ar;
|
||||||
|
guint n_items;
|
||||||
|
|
||||||
|
g_assert (JSON_IS_PARSER (parser));
|
||||||
|
g_assert (image != NULL);
|
||||||
|
|
||||||
|
if (!(root = json_parser_get_root (parser)) ||
|
||||||
|
!JSON_NODE_HOLDS_ARRAY (root) ||
|
||||||
|
!(ar = json_node_get_array (root)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
n_items = json_array_get_length (ar);
|
||||||
|
|
||||||
|
for (guint i = 0; i < n_items; i++)
|
||||||
|
{
|
||||||
|
JsonObject *item = json_array_get_object_element (ar, i);
|
||||||
|
const char *id;
|
||||||
|
const char *layer;
|
||||||
|
|
||||||
|
if (item == NULL ||
|
||||||
|
!json_object_has_member (item, "id") ||
|
||||||
|
!json_object_has_member (item, "layer") ||
|
||||||
|
!(id = json_object_get_string_member (item, "id")) ||
|
||||||
|
strcmp (id, image) != 0 ||
|
||||||
|
!(layer = json_object_get_string_member (item, "layer")))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
find_parent_layer (JsonParser *parser,
|
find_parent_layer (JsonParser *parser,
|
||||||
const char *layer,
|
const char *layer,
|
||||||
GPtrArray *seen)
|
GHashTable *seen)
|
||||||
{
|
{
|
||||||
JsonNode *root;
|
JsonNode *root;
|
||||||
JsonArray *ar;
|
JsonArray *ar;
|
||||||
@ -165,12 +223,8 @@ find_parent_layer (JsonParser *parser,
|
|||||||
!(parent = json_object_get_string_member (item, "parent")))
|
!(parent = json_object_get_string_member (item, "parent")))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Avoid cycles by checking if we've seen this parent */
|
if (g_hash_table_contains (seen, parent))
|
||||||
for (guint j = 0; j < seen->len; j++)
|
return NULL;
|
||||||
{
|
|
||||||
if (strcmp (parent, g_ptr_array_index (seen, j)) == 0)
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
@ -178,14 +232,35 @@ find_parent_layer (JsonParser *parser,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
get_layer_dir (const char *layer)
|
||||||
|
{
|
||||||
|
/* We don't use XDG data dir because this might be in a container
|
||||||
|
* or flatpak environment that doesn't match. And generally, it's
|
||||||
|
* always .local.
|
||||||
|
*/
|
||||||
|
return g_build_filename (g_get_home_dir (),
|
||||||
|
".local",
|
||||||
|
"share",
|
||||||
|
"containers",
|
||||||
|
"storage",
|
||||||
|
"overlay",
|
||||||
|
layer,
|
||||||
|
"diff",
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
gchar **
|
gchar **
|
||||||
sysprof_podman_get_layers (SysprofPodman *self,
|
sysprof_podman_get_layers (SysprofPodman *self,
|
||||||
const char *container)
|
const char *container)
|
||||||
{
|
{
|
||||||
const char *layer = NULL;
|
const char *layer = NULL;
|
||||||
GPtrArray *layers;
|
const char *image = NULL;
|
||||||
|
GHashTable *layers;
|
||||||
JsonNode *root;
|
JsonNode *root;
|
||||||
JsonArray *ar;
|
JsonArray *ar;
|
||||||
|
const char **keys;
|
||||||
|
char **ret;
|
||||||
guint n_items;
|
guint n_items;
|
||||||
|
|
||||||
g_return_val_if_fail (self != NULL, NULL);
|
g_return_val_if_fail (self != NULL, NULL);
|
||||||
@ -214,18 +289,30 @@ sysprof_podman_get_layers (SysprofPodman *self,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
layer = item_layer;
|
layer = item_layer;
|
||||||
|
image = json_object_get_string_member (item, "image");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now we need to try to locate the layer and all of the parents
|
layers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||||
* within the layers.json so that we populate from the most recent
|
|
||||||
* layer to those beneath it.
|
|
||||||
*/
|
|
||||||
layers = g_ptr_array_new ();
|
|
||||||
g_ptr_array_add (layers, g_strdup (layer));
|
|
||||||
while ((layer = find_parent_layer (self->layers_parser, layer, layers)))
|
|
||||||
g_ptr_array_add (layers, g_strdup (layer));
|
|
||||||
g_ptr_array_add (layers, NULL);
|
|
||||||
|
|
||||||
return (char **)g_ptr_array_free (layers, FALSE);
|
/* Add all our known layers starting from current layer */
|
||||||
|
do
|
||||||
|
g_hash_table_add (layers, get_layer_dir (layer));
|
||||||
|
while ((layer = find_parent_layer (self->layers_parser, layer, layers)));
|
||||||
|
|
||||||
|
/* If an image was specified, add its layer */
|
||||||
|
if ((layer = find_image_layer (self->images_parser, image)))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
g_hash_table_add (layers, get_layer_dir (layer));
|
||||||
|
while ((layer = find_parent_layer (self->layers_parser, layer, layers)));
|
||||||
|
}
|
||||||
|
|
||||||
|
keys = (const char **)g_hash_table_get_keys_as_array (layers, NULL);
|
||||||
|
ret = g_strdupv ((char **)keys);
|
||||||
|
|
||||||
|
g_hash_table_unref (layers);
|
||||||
|
g_free (keys);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user