TABLE_SET_COLOR, startswith(img->name, ".") ? ANSI_GREY : NULL,
TABLE_STRING, image_type_to_string(img->type),
TABLE_STRING, image_class_to_string(img->class),
- TABLE_BOOLEAN, img->read_only,
- TABLE_SET_COLOR, !img->read_only ? ANSI_HIGHLIGHT_GREEN : ANSI_HIGHLIGHT_RED,
+ TABLE_BOOLEAN, image_is_read_only(img),
+ TABLE_SET_COLOR, image_is_read_only(img) ? ANSI_HIGHLIGHT_RED : ANSI_HIGHLIGHT_GREEN,
TABLE_PATH, img->path,
TABLE_TIMESTAMP, img->mtime != 0 ? img->mtime : img->crtime,
TABLE_SIZE, img->usage,
i->name,
image_type_to_string(i->type),
i->path,
- i->read_only,
+ image_is_read_only(i),
i->crtime,
i->mtime,
i->usage,
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, image_type, ImageType);
+static int property_get_read_only(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ Image *image = ASSERT_PTR(userdata);
+
+ return sd_bus_message_append(ASSERT_PTR(reply), "b", image_is_read_only(image));
+}
+
int bus_image_method_remove(
sd_bus_message *message,
void *userdata,
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Image, name), 0),
SD_BUS_PROPERTY("Path", "s", NULL, offsetof(Image, path), 0),
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Image, type), 0),
- SD_BUS_PROPERTY("ReadOnly", "b", bus_property_get_bool, offsetof(Image, read_only), 0),
+ SD_BUS_PROPERTY("ReadOnly", "b", property_get_read_only, 0, 0),
SD_BUS_PROPERTY("CreationTimestamp", "t", NULL, offsetof(Image, crtime), 0),
SD_BUS_PROPERTY("ModificationTimestamp", "t", NULL, offsetof(Image, mtime), 0),
SD_BUS_PROPERTY("Usage", "t", NULL, offsetof(Image, usage), 0),
r = sd_bus_message_append(reply, "(ssbttto)",
image->name,
image_type_to_string(image->type),
- image->read_only,
+ image_is_read_only(image),
image->crtime,
image->mtime,
image->usage,
JSON_BUILD_PAIR_STRING_NON_EMPTY("path", image->path),
SD_JSON_BUILD_PAIR_STRING("type", image_type_to_string(image->type)),
SD_JSON_BUILD_PAIR_STRING("class", image_class_to_string(image->class)),
- SD_JSON_BUILD_PAIR_BOOLEAN("readOnly", image->read_only),
+ SD_JSON_BUILD_PAIR_BOOLEAN("readOnly", image_is_read_only(image)),
JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("creationTimestamp", image->crtime),
JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("modificationTimestamp", image->mtime),
JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL("usage", image->usage, UINT64_MAX),
return log_oom();
if (!arg_ephemeral)
- arg_read_only = arg_read_only || i->read_only;
+ arg_read_only = arg_read_only || image_is_read_only(i);
} else {
r = safe_getcwd(&arg_directory);
if (r < 0)
r = sd_bus_message_append(reply, "(ssbtttso)",
image->name,
image_type_to_string(image->type),
- image->read_only,
+ image_is_read_only(image),
image->crtime,
image->mtime,
image->usage,
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, image_type, ImageType);
+static int property_get_read_only(
+ sd_bus *bus,
+ const char *path,
+ const char *interface,
+ const char *property,
+ sd_bus_message *reply,
+ void *userdata,
+ sd_bus_error *error) {
+
+ Image *image = ASSERT_PTR(userdata);
+
+ return sd_bus_message_append(ASSERT_PTR(reply), "b", image_is_read_only(image));
+}
+
int bus_image_common_get_os_release(
Manager *m,
sd_bus_message *message,
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Image, name), 0),
SD_BUS_PROPERTY("Path", "s", NULL, offsetof(Image, path), 0),
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Image, type), 0),
- SD_BUS_PROPERTY("ReadOnly", "b", bus_property_get_bool, offsetof(Image, read_only), 0),
+ SD_BUS_PROPERTY("ReadOnly", "b", property_get_read_only, 0, 0),
SD_BUS_PROPERTY("CreationTimestamp", "t", NULL, offsetof(Image, crtime), 0),
SD_BUS_PROPERTY("ModificationTimestamp", "t", NULL, offsetof(Image, mtime), 0),
SD_BUS_PROPERTY("Usage", "t", NULL, offsetof(Image, usage), 0),
assert(i);
- if (image_is_vendor(i) || image_is_host(i))
+ if (image_is_vendor(i) || image_is_host(i) || image_is_hidden(i))
return -EROFS;
/* Make sure we don't interfere with a running nspawn */
SD_JSON_BUILD_PAIR_STRING("Class", image_class_to_string(img->class)),
SD_JSON_BUILD_PAIR_STRING("Name", img->name),
SD_JSON_BUILD_PAIR_CONDITION(!!img->path, "Path", SD_JSON_BUILD_STRING(img->path)),
- SD_JSON_BUILD_PAIR_BOOLEAN("ReadOnly", img->read_only),
+ SD_JSON_BUILD_PAIR_BOOLEAN("ReadOnly", image_is_read_only(img)),
SD_JSON_BUILD_PAIR_CONDITION(img->crtime != 0, "CreationTimestamp", SD_JSON_BUILD_UNSIGNED(img->crtime)),
SD_JSON_BUILD_PAIR_CONDITION(img->mtime != 0, "ModificationTimestamp", SD_JSON_BUILD_UNSIGNED(img->mtime)),
SD_JSON_BUILD_PAIR_CONDITION(img->usage != UINT64_MAX, "Usage", SD_JSON_BUILD_UNSIGNED(img->usage)),
return NULL;
}
-static inline bool image_is_hidden(const struct Image *i) {
+static inline bool image_is_hidden(const Image *i) {
assert(i);
return i->name && i->name[0] == '.';
}
-bool image_is_vendor(const struct Image *i);
-bool image_is_host(const struct Image *i);
+static inline int image_is_read_only(const Image *i) {
+ assert(i);
+
+ /* We enforce the rule that hidden images are always read-only too. If people want to change hidden
+ * images they should make a copy first, and make that one mutable */
+
+ if (image_is_hidden(i))
+ return true;
+
+ return i->read_only;
+}
+
+bool image_is_vendor(const Image *i);
+bool image_is_host(const Image *i);
-int image_to_json(const struct Image *i, sd_json_variant **ret);
+int image_to_json(const Image *i, sd_json_variant **ret);
int image_root_pick(RuntimeScope scope, ImageClass c, bool runtime, char **ret);