[PATCH v3] plugins: ifupdown: support source-directory stanza



From: Scott Sweeny <scott sweeny canonical com>

Enable the ifupdown settings plugin to read interface
definitions from the source directory:

/etc/network/interfaces.d/
---
 src/settings/plugins/ifupdown/interface_parser.c   | 47 ++++++++++++++++------
 .../plugins/ifupdown/tests/test-ifupdown.c         | 23 +++++++++++
 .../ifupdown/tests/test21-source-dir-stanza        |  1 +
 .../test21-source-dir-stanza.eth0                  |  2 +
 4 files changed, 61 insertions(+), 12 deletions(-)
 create mode 100644 src/settings/plugins/ifupdown/tests/test21-source-dir-stanza
 create mode 100644 
src/settings/plugins/ifupdown/tests/test21-source-dir-stanza.d/test21-source-dir-stanza.eth0

diff --git a/src/settings/plugins/ifupdown/interface_parser.c 
b/src/settings/plugins/ifupdown/interface_parser.c
index 7ad902d..30f5794 100644
--- a/src/settings/plugins/ifupdown/interface_parser.c
+++ b/src/settings/plugins/ifupdown/interface_parser.c
@@ -100,7 +100,7 @@ static char *join_values_with_spaces(char *dst, char **src)
        return(dst);
 }
 
-static void _ifparser_source (const char *path, const char *en_dir, int quiet);
+static void _ifparser_source (const char *path, const char *en_dir, int quiet, int dir);
 
 static void
 _recursive_ifparser (const char *eni_file, int quiet)
@@ -189,9 +189,9 @@ _recursive_ifparser (const char *eni_file, int quiet)
                        continue;
                }
 
-               /* There are five different stanzas:
-                * iface, mapping, auto, allow-* and source.
-                * Create a block for each of them except source.  */
+               /* There are six different stanzas:
+                * iface, mapping, auto, allow-*, source, and source-directory.
+                * Create a block for each of them except source and source-directory.  */
 
                /* iface stanza takes at least 3 parameters */
                if (strcmp(token[0], "iface") == 0) {
@@ -226,22 +226,28 @@ _recursive_ifparser (const char *eni_file, int quiet)
                                add_block(token[0], token[i]);
                        skip_to_block = 0;
                }
-               /* source stanza takes one or more filepaths as parameters */
-               else if (strcmp(token[0], "source") == 0) {
+               /* source and source-directory stanzas take one or more paths as parameters */
+               else if (strcmp (token[0], "source") == 0 || strcmp (token[0], "source-directory") == 0) {
                        int i;
                        char *en_dir;
 
                        skip_to_block = 0;
 
                        if (toknum == 1) {
-                               if (!quiet)
-                                       nm_log_warn (LOGD_SETTINGS, "Invalid source line without 
parameters\n");
+                               if (!quiet) {
+                                       nm_log_warn (LOGD_SETTINGS, "Invalid %s line without parameters\n",
+                                                    token[0]);
+                               }
                                continue;
                        }
 
                        en_dir = g_path_get_dirname (eni_file);
-                       for (i = 1; i < toknum; ++i)
-                               _ifparser_source (token[i], en_dir, quiet);
+                       for (i = 1; i < toknum; ++i) {
+                               if (strcmp (token[0], "source-directory") == 0)
+                                       _ifparser_source (token[i], en_dir, quiet, TRUE);
+                               else
+                                       _ifparser_source (token[i], en_dir, quiet, FALSE);
+                       }
                        g_free (en_dir);
                }
                else {
@@ -261,10 +267,13 @@ _recursive_ifparser (const char *eni_file, int quiet)
 }
 
 static void
-_ifparser_source (const char *path, const char *en_dir, int quiet)
+_ifparser_source (const char *path, const char *en_dir, int quiet, int dir)
 {
        char *abs_path;
+       const char *item;
        wordexp_t we;
+       GDir *source_dir;
+       GError *error = NULL;
        uint i;
 
        if (g_path_is_absolute (path))
@@ -281,7 +290,21 @@ _ifparser_source (const char *path, const char *en_dir, int quiet)
                        nm_log_warn (LOGD_SETTINGS, "word expansion for %s failed\n", abs_path);
        } else {
                for (i = 0; i < we.we_wordc; i++)
-                       _recursive_ifparser (we.we_wordv[i], quiet);
+                       if (dir) {
+                               source_dir = g_dir_open (we.we_wordv[i], 0, &error);
+                               if (!source_dir) {
+                                       if (!quiet) {
+                                               nm_log_warn (LOGD_SETTINGS, "Failed to open directory %s: %s",
+                                                            we.we_wordv[i], error->message);
+                                       }
+                                       g_clear_error (&error);
+                               } else {
+                                       while ((item = g_dir_read_name (source_dir)))
+                                               _ifparser_source (item, we.we_wordv[i], quiet, FALSE);
+                                       g_dir_close (source_dir);
+                               }
+                       } else
+                               _recursive_ifparser (we.we_wordv[i], quiet);
                wordfree (&we);
        }
        g_free (abs_path);
diff --git a/src/settings/plugins/ifupdown/tests/test-ifupdown.c 
b/src/settings/plugins/ifupdown/tests/test-ifupdown.c
index 7ce08ae..11b42c7 100644
--- a/src/settings/plugins/ifupdown/tests/test-ifupdown.c
+++ b/src/settings/plugins/ifupdown/tests/test-ifupdown.c
@@ -627,6 +627,27 @@ test20_source_stanza (const char *path)
        expected_free (e);
 }
 
+static void
+test21_source_dir_stanza (const char *path)
+{
+       Expected *e;
+       ExpectedBlock *b;
+
+       e = expected_new ();
+
+       b = expected_block_new ("auto", "eth0");
+       expected_add_block (e, b);
+       b = expected_block_new ("iface", "eth0");
+       expected_add_block (e, b);
+       expected_block_add_key (b, expected_key_new ("inet", "dhcp"));
+
+       init_ifparser_with_file (path, "test21-source-dir-stanza");
+       compare_expected_to_ifparser (e);
+
+       ifparser_destroy ();
+       expected_free (e);
+}
+
 NMTST_DEFINE ();
 
 int
@@ -675,6 +696,8 @@ main (int argc, char **argv)
                              (GTestDataFunc) test19_read_static_ipv4_plen);
        g_test_add_data_func ("/ifupdate/source_stanza", TEST_ENI_DIR,
                              (GTestDataFunc) test20_source_stanza);
+       g_test_add_data_func ("/ifupdate/source_dir_stanza", TEST_ENI_DIR,
+                             (GTestDataFunc) test21_source_dir_stanza);
 
        return g_test_run ();
 }
diff --git a/src/settings/plugins/ifupdown/tests/test21-source-dir-stanza 
b/src/settings/plugins/ifupdown/tests/test21-source-dir-stanza
new file mode 100644
index 0000000..d0604dd
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test21-source-dir-stanza
@@ -0,0 +1 @@
+source-directory test21-source-dir-stanza.d
diff --git a/src/settings/plugins/ifupdown/tests/test21-source-dir-stanza.d/test21-source-dir-stanza.eth0 
b/src/settings/plugins/ifupdown/tests/test21-source-dir-stanza.d/test21-source-dir-stanza.eth0
new file mode 100644
index 0000000..81922ce
--- /dev/null
+++ b/src/settings/plugins/ifupdown/tests/test21-source-dir-stanza.d/test21-source-dir-stanza.eth0
@@ -0,0 +1,2 @@
+auto eth0
+iface eth0 inet dhcp
-- 
2.7.4



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]