]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Be more strict about what can be an Alias for template and instances 13990/head
authorJérémy Rosen <jeremy.rosen@smile.fr>
Tue, 3 Dec 2019 14:33:22 +0000 (15:33 +0100)
committerJérémy Rosen <jeremy.rosen@smile.fr>
Wed, 18 Dec 2019 10:00:49 +0000 (11:00 +0100)
* Templates can only use other templates as alisases
* Template instances can use templates or things that expand with an
  instance name

src/shared/install.c

index 0e673b33588f8e824640f322b417b73e9b3bab7b..115a64f5f4e68c7c0a7fef297b8e7786eba6e52c 100644 (file)
@@ -1724,12 +1724,51 @@ static int install_info_symlink_alias(
         assert(config_path);
 
         STRV_FOREACH(s, i->aliases) {
+
                 _cleanup_free_ char *alias_path = NULL, *dst = NULL;
 
                 q = install_full_printf(i, *s, &dst);
                 if (q < 0)
                         return q;
 
+                if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE) &&
+                    !unit_name_is_valid(dst, UNIT_NAME_TEMPLATE) &&
+                    !i->default_instance) {
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Aliases for templates without DefaultInstance must be templates.");
+                }
+
+                if (unit_name_is_valid(i->name, UNIT_NAME_INSTANCE | UNIT_NAME_TEMPLATE) &&
+                    !unit_name_is_valid(dst, UNIT_NAME_TEMPLATE | UNIT_NAME_INSTANCE)) {
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Aliases for template instances must be a templates or template instances containing the instance name.");
+                }
+
+                if (unit_name_is_valid(i->name, UNIT_NAME_INSTANCE | UNIT_NAME_TEMPLATE) &&
+                    unit_name_is_valid(dst, UNIT_NAME_INSTANCE)) {
+                        _cleanup_free_ char *src_inst = NULL, *dst_inst = NULL;
+
+                        q = unit_name_to_instance(i->name, &src_inst);
+                        if (q < 0)
+                                return q;
+
+                        q = unit_name_to_instance(dst, &dst_inst);
+                        if (q < 0)
+                                return q;
+                        if (!strstr(dst_inst, src_inst?src_inst:i->default_instance))
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Aliases for template instances must be a templates or template instances containing the instance name.");
+                }
+
+                if (unit_name_is_valid(i->name, UNIT_NAME_INSTANCE) && unit_name_is_valid(dst, UNIT_NAME_TEMPLATE)) {
+                        _cleanup_free_ char *s_copy = NULL, *instance = NULL;
+                        q = unit_name_to_instance(i->name,&instance);
+                        if (q < 0)
+                                return q;
+
+                        q = unit_name_replace_instance(dst,instance,&s_copy);
+                        if (q < 0)
+                                return q;
+                        free_and_replace(dst, s_copy);
+                }
+
                 alias_path = path_make_absolute(dst, config_path);
                 if (!alias_path)
                         return -ENOMEM;
@@ -1737,6 +1776,22 @@ static int install_info_symlink_alias(
                 q = create_symlink(paths, i->path, alias_path, force, changes, n_changes);
                 if (r == 0)
                         r = q;
+
+                /* if we are a template with a DefaultInstance and we target a template, also create a link from the DefaultInstance*/
+                if (unit_name_is_valid(i->name, UNIT_NAME_TEMPLATE) && unit_name_is_valid(dst, UNIT_NAME_TEMPLATE) && i->default_instance) {
+                        _cleanup_free_ char *s_copy = NULL,*final_path = NULL;
+
+                        q = unit_name_replace_instance(dst,i->default_instance,&s_copy);
+                        if (q < 0)
+                                return q;
+                        final_path = path_make_absolute(s_copy, config_path);
+                        if (!final_path)
+                                return -ENOMEM;
+                        q = create_symlink(paths, i->path, final_path, force, changes, n_changes);
+                        if (r == 0)
+                                r = q;
+                }
+
         }
 
         return r;