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

Re: [PATCH 6/8] Convert kickstart functions to use Python.



Ack.

On Thu, 20 Jan 2011, Chris Lumens wrote:

---
loader/kickstart.c |  868 +++++++++++++++++++++++++---------------------------
loader/kickstart.h |    1 -
2 files changed, 415 insertions(+), 454 deletions(-)

diff --git a/loader/kickstart.c b/loader/kickstart.c
index 9e35a50..d10d037 100644
--- a/loader/kickstart.c
+++ b/loader/kickstart.c
@@ -58,68 +58,50 @@
#include "../pyanaconda/isys/isys.h"
#include "../pyanaconda/isys/log.h"

+/* Too bad, but we need constants visible everywhere. */
+static PyObject *constantsMod;
+
/* boot flags */
extern uint64_t flags;

struct ksCommandNames {
    char * name;
-    void (*setupData) (struct loaderData_s *loaderData,
-                       int argc, char ** argv);
+    void (*setupData) (struct loaderData_s *loaderData, PyObject *handler);
} ;

-static void setTextMode(struct loaderData_s * loaderData, int argc,
-                        char ** argv);
-static void setGraphicalMode(struct loaderData_s * loaderData, int argc,
-                             char ** argv);
-static void setCmdlineMode(struct loaderData_s * loaderData, int argc,
-                           char ** argv);
-static void setSELinux(struct loaderData_s * loaderData, int argc,
-                       char ** argv);
-static void setPowerOff(struct loaderData_s * loaderData, int argc,
-                        char ** argv);
-static void setHalt(struct loaderData_s * loaderData, int argc,
-                    char ** argv);
-static void setShutdown(struct loaderData_s * loaderData, int argc,
-                        char ** argv);
-static void setMediaCheck(struct loaderData_s * loaderData, int argc,
-                          char ** argv);
-static void setUpdates(struct loaderData_s * loaderData, int argc,
-                       char ** argv);
-static void setVnc(struct loaderData_s * loaderData, int argc,
-                       char ** argv);
-static void useKickstartDD(struct loaderData_s * loaderData,
-                    int argc, char ** argv);
-static void setKickstartKeyboard(struct loaderData_s * loaderData, int argc,
-                          char ** argv);
-static void setKickstartLanguage(struct loaderData_s * loaderData, int argc,
-                          char ** argv);
-static void setKickstartNetwork(struct loaderData_s * loaderData, int argc,
-                         char ** argv);
-static void setKickstartCD(struct loaderData_s * loaderData, int argc, char ** argv);
-static void setKickstartHD(struct loaderData_s * loaderData, int argc,
-                     char ** argv);
-static void setKickstartNfs(struct loaderData_s * loaderData, int argc,
-                     char ** argv);
-static void setKickstartUrl(struct loaderData_s * loaderData, int argc,
-                     char ** argv);
+static void setDisplayMode(struct loaderData_s * loaderData, PyObject *handler);
+static void setSELinux(struct loaderData_s * loaderData, PyObject *handler);
+static void setShutdown(struct loaderData_s * loaderData, PyObject *handler);
+static void setMediaCheck(struct loaderData_s * loaderData, PyObject *handler);
+static void setUpdates(struct loaderData_s * loaderData, PyObject *handler);
+static void setVnc(struct loaderData_s * loaderData, PyObject *handler);
+static void useKickstartDD(struct loaderData_s * loaderData, PyObject *handler);
+static void setKickstartKeyboard(struct loaderData_s * loaderData, PyObject *handler);
+static void setKickstartLanguage(struct loaderData_s * loaderData, PyObject *handler);
+static void setKickstartNetwork(struct loaderData_s * loaderData, PyObject *handler);
+static void setKickstartCD(struct loaderData_s * loaderData, PyObject *handler);
+static void setKickstartHD(struct loaderData_s * loaderData, PyObject *handler);
+static void setKickstartNfs(struct loaderData_s * loaderData, PyObject *handler);
+static void setKickstartUrl(struct loaderData_s * loaderData, PyObject *handler);
+static void loadKickstartModule(struct loaderData_s * loaderData, PyObject *handler);

struct ksCommandNames ksTable[] = {
    { "cdrom", setKickstartCD },
-    { "cmdline", setCmdlineMode },
+    { "cmdline", setDisplayMode },
    { "device", loadKickstartModule },
    { "driverdisk", useKickstartDD },
-    { "graphical", setGraphicalMode },
-    { "halt", setHalt },
+    { "graphical", setDisplayMode },
+    { "halt", setShutdown },
    { "harddrive", setKickstartHD },
    { "keyboard", setKickstartKeyboard },
    { "lang", setKickstartLanguage },
    { "mediacheck", setMediaCheck },
    { "network", setKickstartNetwork },
    { "nfs", setKickstartNfs },
-    { "poweroff", setPowerOff },
+    { "poweroff", setShutdown },
    { "selinux", setSELinux },
    { "shutdown", setShutdown },
-    { "text", setTextMode },
+    { "text", setDisplayMode },
    { "updates", setUpdates },
    { "url", setKickstartUrl },
    { "vnc", setVnc },
@@ -128,11 +110,14 @@ struct ksCommandNames ksTable[] = {

/* INTERNAL PYTHON INTERFACE FUNCTIONS */

-static PyObject *getCallable(PyObject *module, const char *name) {
+static PyObject *getObject(PyObject *module, const char *name, unsigned int isCallable) {
    PyObject *obj = NULL;

    obj = PyObject_GetAttrString(module, name);
-    if (!obj || !PyCallable_Check(obj)) {
+    if (!obj)
+        return NULL;
+
+    if (isCallable && !PyCallable_Check(obj)) {
        Py_XDECREF(obj);
        return NULL;
    }
@@ -150,7 +135,7 @@ static PyObject *import(const char *moduleName) {
static PyObject *makeHandler(PyObject *module) {
    PyObject *func, *handler;

-    func = getCallable(module, "makeVersion");
+    func = getObject(module, "makeVersion", 1);
    if (!func)
        return NULL;

@@ -205,28 +190,42 @@ static void handleException() {

/* Returns the handler.<command>.<attr> object if it exists, or NULL on error. */
static PyObject *getattr(PyObject *handler, const char *command, const char *attr) {
-    PyObject *commandObj, *attrObj;
+    PyObject *commandObj = NULL, *attrObj = NULL;

    commandObj = PyObject_GetAttrString(handler, command);
    if (!commandObj)
-        return NULL;
+        goto cleanup;

    attrObj = PyObject_GetAttrString(commandObj, attr);
-    if (!attrObj) {
-        Py_DECREF(commandObj);
-        return NULL;
-    }
+    if (!attrObj)
+        goto cleanup;

+cleanup:
+    Py_XDECREF(commandObj);
    return attrObj;
}

+static PyObject *getDataList(PyObject *handler, const char *command) {
+    PyObject *attrObj = getattr(handler, command, "dataList");
+    PyObject *retval = NULL;
+
+    if (!attrObj || !PyCallable_Check(attrObj))
+        goto cleanup;
+
+    retval = PyObject_CallObject(attrObj, NULL);
+
+cleanup:
+    Py_XDECREF(attrObj);
+    return retval;
+}
+
/* Perform the same tasks as pykickstart.parser.preprocessKickstart.  Currently
 * this is just fetching and expanding %ksappend lines.
 */
static PyObject *preprocessKickstart(PyObject *module, const char *inputFile) {
    PyObject *output = NULL, *func;

-    func = getCallable(module, "preprocessKickstart");
+    func = getObject(module, "preprocessKickstart", 1);
    if (!func)
        return NULL;

@@ -255,6 +254,20 @@ static PyObject *readKickstart(PyObject *parser, PyObject *f) {
    return retval;
}

+/* PYTHON HELPERS */
+
+static unsigned int isNotEmpty(PyObject *obj) {
+    return obj && PyString_Check(obj) && strcmp("", PyString_AsString(obj));
+}
+
+static unsigned int objIsStr(PyObject *obj, const char *str) {
+    return obj && PyString_Check(obj) && !strcmp(str, PyString_AsString(obj));
+}
+
+static unsigned int isTrue(PyObject *obj) {
+    return obj && PyBool_Check(obj) && obj == Py_True;
+}
+
int kickstartFromRemovable(char *kssrc) {
    struct device ** devices;
    char *p, *kspath;
@@ -319,55 +332,37 @@ int getKickstartFromBlockDevice(char *device, char *path) {
    return getFileFromBlockDevice(device, path, "/tmp/ks.cfg");
}

-void loadKickstartModule(struct loaderData_s * loaderData,
-                         int argc, char **argv) {
-    gchar *opts = NULL;
-    gchar *module = NULL;
-    gchar **args = NULL, **remaining = NULL;
-    gboolean rc;
-    GOptionContext *optCon = g_option_context_new(NULL);
-    GError *optErr = NULL;
-    GOptionEntry ksDeviceOptions[] = {
-        { "opts", 0, 0, G_OPTION_ARG_STRING, &opts, NULL, NULL },
-        { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining,
-          NULL, NULL },
-        { NULL },
-    };
-
-    g_option_context_set_help_enabled(optCon, FALSE);
-    g_option_context_add_main_entries(optCon, ksDeviceOptions, NULL);
-
-    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
-        startNewt();
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Bad argument to device kickstart method "
-                         "command: %s"), optErr->message);
-        g_error_free(optErr);
-        g_option_context_free(optCon);
+void loadKickstartModule(struct loaderData_s * loaderData, PyObject *handler) {
+    Py_ssize_t i;
+    PyObject *list = getDataList(handler, "device");
+
+    if (!list)
        return;
-    }

-    g_option_context_free(optCon);
+    for (i = 0; i < PyList_Size(list); i++) {
+        PyObject *ele = PyList_GetItem(list, i);
+        PyObject *moduleName, *moduleOpts;

-    if ((remaining != NULL) && (g_strv_length(remaining) == 1)) {
-        module = remaining[0];
-    }
+        if (!ele)
+            continue;

-    if (!module) {
-        startNewt();
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("A module name must be specified for "
-                         "the kickstart device command."));
-        return;
-    }
+        moduleName = getObject(ele, "moduleName", 0);
+        moduleOpts = getObject(ele, "moduleOpts", 0);
+
+        if (isNotEmpty(moduleName)) {
+            if (isNotEmpty(moduleOpts)) {
+                gchar **args = g_strsplit(PyString_AsString(moduleOpts), " ", 0);
+                mlLoadModule(PyString_AsString(moduleName), args);
+                g_strfreev(args);
+            }  else
+                mlLoadModule(PyString_AsString(moduleName), NULL);
+        }

-    if (opts) {
-        args = g_strsplit(opts, " ", 0);
+        Py_XDECREF(moduleName);
+        Py_XDECREF(moduleOpts);
    }

-    rc = mlLoadModule(module, args);
-    g_strfreev(args);
-    return;
+    Py_XDECREF(list);
}

static char *newKickstartLocation(const char *origLocation) {
@@ -495,292 +490,246 @@ void getKickstartFile(struct loaderData_s *loaderData) {
    return;
}

-static void setVnc(struct loaderData_s * loaderData, int argc,
-                   char ** argv) {
-    logMessage(INFO, "kickstart forcing graphical mode over vnc");
-    flags |= LOADER_FLAGS_GRAPHICAL | LOADER_FLAGS_EARLY_NETWORKING;
-    return;
-}
+static void setVnc(struct loaderData_s * loaderData, PyObject *handler) {
+    PyObject *vncEnabled = getattr(handler, "vnc", "enabled");

-static void setUpdates(struct loaderData_s * loaderData, int argc,
-                       char ** argv) {
-   if (argc == 1)
-      flags |= LOADER_FLAGS_UPDATES;
-   else if (argc == 2)
-      loaderData->updatessrc = strdup(argv[1]);
-   else
-      logMessage(WARNING, "updates command given with incorrect arguments");
-}
+    if (isTrue(vncEnabled)) {
+        logMessage(INFO, "kickstart forcing graphical mode over vnc");
+        flags |= LOADER_FLAGS_GRAPHICAL | LOADER_FLAGS_EARLY_NETWORKING;
+    }

-static void setTextMode(struct loaderData_s * loaderData, int argc,
-                        char ** argv) {
-    logMessage(INFO, "kickstart forcing text mode");
-    flags |= LOADER_FLAGS_TEXT;
-    return;
+    Py_XDECREF(vncEnabled);
}

-static void setGraphicalMode(struct loaderData_s * loaderData, int argc,
-                        char ** argv) {
-    logMessage(INFO, "kickstart forcing graphical mode");
-    flags |= LOADER_FLAGS_GRAPHICAL;
-    return;
-}
+static void setUpdates(struct loaderData_s * loaderData, PyObject *handler) {
+    PyObject *url = getattr(handler, "updates", "url");

-static void setCmdlineMode(struct loaderData_s * loaderData, int argc,
-                           char ** argv) {
-    logMessage(INFO, "kickstart forcing cmdline mode");
-    flags |= LOADER_FLAGS_CMDLINE;
-    return;
-}
+    if (!isNotEmpty(url) || objIsStr(url, "floppy"))
+        flags |= LOADER_FLAGS_UPDATES;
+    else if (isNotEmpty(url))
+        loaderData->updatessrc = strdup(PyString_AsString(url));

-static void setSELinux(struct loaderData_s * loaderData, int argc,
-                       char ** argv) {
-    flags |= LOADER_FLAGS_SELINUX;
-    return;
+    Py_XDECREF(url);
}

-static void setPowerOff(struct loaderData_s * loaderData, int argc,
-                        char ** argv) {
-    if (!FL_NOKILL(flags))
-        flags |= LOADER_FLAGS_POWEROFF;
-    return;
+static void setDisplayMode(struct loaderData_s * loaderData, PyObject *handler) {
+    PyObject *textObj = getObject(constantsMod, "DISPLAY_MODE_TEXT", 0);
+    PyObject *graphicalObj = getObject(constantsMod, "DISPLAY_MODE_GRAPHICAL", 0);
+    PyObject *settingObj = getattr(handler, "displaymode", "displayMode");
+
+    if (!settingObj)
+        goto cleanup;
+
+    if (settingObj == textObj) {
+        logMessage(INFO, "kickstart forcing text mode");
+        flags |= LOADER_FLAGS_TEXT;
+    } else if (settingObj == graphicalObj) {
+        logMessage(INFO, "kickstart forcing graphical mode");
+        flags |= LOADER_FLAGS_GRAPHICAL;
+    } else {
+        logMessage(INFO, "kickstart forcing cmdline mode");
+        flags |= LOADER_FLAGS_CMDLINE;
+    }
+
+cleanup:
+    Py_XDECREF(textObj);
+    Py_XDECREF(graphicalObj);
+    Py_XDECREF(settingObj);
}

-static void setHalt(struct loaderData_s * loaderData, int argc,
-                    char ** argv) {
-    if (!FL_NOKILL(flags))
-        flags |= LOADER_FLAGS_HALT;
-    return;
+static void setSELinux(struct loaderData_s * loaderData, PyObject *handler) {
+    PyObject *disabledObj = getObject(constantsMod, "SELINUX_DISABLED", 0);
+    PyObject *settingObj = getattr(handler, "selinux", "selinux");
+
+    if (settingObj && settingObj != disabledObj)
+        flags |= LOADER_FLAGS_SELINUX;
+
+    Py_XDECREF(disabledObj);
+    Py_XDECREF(settingObj);
}

-static void setShutdown(struct loaderData_s * loaderData, int argc,
-                    char ** argv) {
-    gint eject = 0, reboot = 0, halt = 0, poweroff = 0;
-    GOptionContext *optCon = g_option_context_new(NULL);
-    GError *optErr = NULL;
-    GOptionEntry ksOptions[] = {
-        { "eject", 'e', 0, G_OPTION_ARG_INT, &eject, NULL, NULL },
-        { "reboot", 'r', 0, G_OPTION_ARG_INT, &reboot, NULL, NULL },
-        { "halt", 'h', 0, G_OPTION_ARG_INT, &halt, NULL, NULL },
-        { "poweroff", 'p', 0, G_OPTION_ARG_INT, &poweroff, NULL, NULL },
-        { NULL },
-    };
-
-    g_option_context_set_help_enabled(optCon, FALSE);
-    g_option_context_add_main_entries(optCon, ksOptions, NULL);
-
-    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
-        startNewt();
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Bad argument to shutdown kickstart method "
-                         "command: %s"), optErr->message);
-        g_error_free(optErr);
-        g_option_context_free(optCon);
-        return;
-    }
+static void setShutdown(struct loaderData_s * loaderData, PyObject *handler) {
+    PyObject *shutdownObj = getObject(constantsMod, "KS_SHUTDOWN", 0);
+    PyObject *settingObj = getattr(handler, "reboot", "action");

-    g_option_context_free(optCon);
+    if (!settingObj)
+        goto cleanup;

-    if (FL_NOKILL(flags)) {
+    if (FL_NOKILL(flags))
        flags |= LOADER_FLAGS_HALT;
-    } else  {
-        if (poweroff)
+    else {
+        if (settingObj == shutdownObj)
            flags |= LOADER_FLAGS_POWEROFF;
-        if ((!poweroff && !reboot) || (halt))
+        else
            flags |= LOADER_FLAGS_HALT;
    }
+
+cleanup:
+    Py_XDECREF(shutdownObj);
+    Py_XDECREF(settingObj);
}

-static void setMediaCheck(struct loaderData_s * loaderData, int argc,
-                          char ** argv) {
-    flags |= LOADER_FLAGS_MEDIACHECK;
-    return;
+static void setMediaCheck(struct loaderData_s * loaderData, PyObject *handler) {
+    PyObject *mediaCheckEnabled = getattr(handler, "mediacheck", "mediacheck");
+
+    if (isTrue(mediaCheckEnabled))
+        flags |= LOADER_FLAGS_MEDIACHECK;
+
+    Py_XDECREF(mediaCheckEnabled);
}

-static void useKickstartDD(struct loaderData_s * loaderData,
-                    int argc, char ** argv) {
-    char * dev = NULL;
-    char * biospart = NULL, * p = NULL;
-    gchar *fstype = NULL, *src = NULL;
-    gint usebiosdev = 0;
-    gchar **remaining = NULL;
-    GOptionContext *optCon = g_option_context_new(NULL);
-    GError *optErr = NULL;
-    GOptionEntry ksDDOptions[] = {
-        /* The --type option is deprecated and now has no effect. */
-        { "type", 0, 0, G_OPTION_ARG_STRING, &fstype, NULL, NULL },
-        { "source", 0, 0, G_OPTION_ARG_STRING, &src, NULL, NULL },
-        { "biospart", 0, 0, G_OPTION_ARG_INT, &usebiosdev, NULL, NULL },
-        { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining,
-          NULL, NULL },
-        { NULL },
-    };
-
-    g_option_context_set_help_enabled(optCon, FALSE);
-    g_option_context_add_main_entries(optCon, ksDDOptions, NULL);
-
-    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("The following invalid argument was specified for "
-                         "the kickstart driver disk command: %s"),
-                       optErr->message);
-        g_error_free(optErr);
-        g_option_context_free(optCon);
-        g_strfreev(remaining);
+static void useKickstartDD(struct loaderData_s * loaderData, PyObject *handler) {
+    Py_ssize_t i;
+    PyObject *list = getDataList(handler, "driverdisk");
+
+    if (!list)
        return;
-    }

-    g_option_context_free(optCon);
+    for (i = 0; i < PyList_Size(list); i++) {
+        PyObject *ele = PyList_GetItem(list, i);
+        PyObject *attr;

-    if ((remaining != NULL) && (g_strv_length(remaining) == 1)) {
-        dev = remaining[0];
-    }
+        if (!ele)
+            continue;

-    if (!dev && !src) {
-        logMessage(ERROR, "bad arguments to kickstart driver disk command");
-        return;
-    }
+        attr = getObject(ele, "source", 0);
+        if (isNotEmpty(attr)) {
+            getDDFromSource(loaderData, PyString_AsString(attr), NULL);
+            goto cleanup;
+        }

-    if (usebiosdev != 0) {
-        p = strchr(dev,'p');
-        if (!p){
-            logMessage(ERROR, "Bad argument for biospart");
-            return;
+        Py_XDECREF(attr);
+        attr = getObject(ele, "partition", 0);
+
+        if (isNotEmpty(attr)) {
+            getDDFromDev(loaderData, PyString_AsString(attr), NULL);
+            goto cleanup;
        }
-        *p = '\0';
-
-        biospart = getBiosDisk(dev);
-        if (biospart == NULL) {
-            logMessage(ERROR, "Unable to locate BIOS dev %s",dev);
-            return;
+
+        Py_XDECREF(attr);
+        attr = getObject(ele, "biospart", 0);
+
+        if (isNotEmpty(attr)) {
+            char *dev = strdup(PyString_AsString(attr));
+            char *biospart = NULL, *p = NULL;
+
+            p = strchr(dev,'p');
+            if (!p){
+                logMessage(ERROR, "Bad argument for biospart");
+                goto cleanup;
+            }
+            *p = '\0';
+
+            biospart = getBiosDisk(dev);
+            if (biospart == NULL) {
+                logMessage(ERROR, "Unable to locate BIOS dev %s",dev);
+                goto cleanup;
+            }
+
+            free(dev);
+            dev = malloc(strlen(biospart) + strlen(p + 1) + 2);
+            sprintf(dev, "%s%s", biospart, p + 1);
+            getDDFromDev(loaderData, dev, NULL);
        }
-        dev = malloc(strlen(biospart) + strlen(p + 1) + 2);
-        sprintf(dev, "%s%s", biospart, p + 1);
-    }

-    if (dev) {
-        getDDFromDev(loaderData, dev, NULL);
-    } else {
-        getDDFromSource(loaderData, src, NULL);
+cleanup:
+        Py_XDECREF(attr);
    }

-    g_strfreev(remaining);
-    return;
+    Py_XDECREF(list);
}

-static void setKickstartKeyboard(struct loaderData_s * loaderData, int argc,
-                          char ** argv) {
-    if (argc < 2) {
-        logMessage(ERROR, "no argument passed to keyboard kickstart command");
-        return;
+static void setKickstartKeyboard(struct loaderData_s * loaderData, PyObject *handler) {
+    PyObject *kbdObj = getattr(handler, "keyboard", "keyboard");
+
+    if (isNotEmpty(kbdObj)) {
+        loaderData->kbd = strdup(PyString_AsString(kbdObj));
+        loaderData->kbd_set = 1;
    }

-    loaderData->kbd = argv[1];
-    loaderData->kbd_set = 1;
+    Py_XDECREF(kbdObj);
}

-static void setKickstartLanguage(struct loaderData_s * loaderData, int argc,
-                          char ** argv) {
-    if (argc < 2) {
-        logMessage(ERROR, "no argument passed to lang kickstart command");
-        return;
+static void setKickstartLanguage(struct loaderData_s * loaderData, PyObject *handler) {
+    PyObject *langObj = getattr(handler, "lang", "lang");
+
+    if (isNotEmpty(langObj)) {
+        loaderData->lang = strdup(PyString_AsString(langObj));
+        loaderData->lang_set = 1;
    }

-    loaderData->lang = argv[1];
-    loaderData->lang_set = 1;
+    Py_XDECREF(langObj);
}

-static void setKickstartNetwork(struct loaderData_s * loaderData, int argc,
-                         char ** argv) {
-    iface_t iface;
-    gchar *bootProto = NULL, *device = NULL, *class = NULL, *ethtool = NULL;
-    gchar *essid = NULL, *wepkey = NULL, *onboot = NULL, *gateway = NULL;
-    gint mtu = 1500, dhcpTimeout = -1;
-    gboolean noipv4 = FALSE, noipv6 = FALSE, noDns = FALSE, noksdev = FALSE;
-    GOptionContext *optCon = g_option_context_new(NULL);
-    GError *optErr = NULL;
-    struct in_addr addr;
-#ifdef ENABLE_IPV6
-    struct in6_addr addr6;
-#endif
-    int rc;
-    GOptionEntry ksOptions[] = {
-        { "bootproto", 0, 0, G_OPTION_ARG_STRING, &bootProto, NULL, NULL },
-        { "device", 0, 0, G_OPTION_ARG_STRING, &device, NULL, NULL },
-        { "dhcpclass", 0, 0, G_OPTION_ARG_STRING, &class, NULL, NULL },
-        { "gateway", 'g', 0, G_OPTION_ARG_STRING, &gateway,
-          NULL, NULL },
-        { "ip", 'i', 0, G_OPTION_ARG_STRING, &loaderData->ipv4, NULL, NULL },
-#ifdef ENABLE_IPV6
-        { "ipv6", 0, 0, G_OPTION_ARG_STRING, &loaderData->ipv6, NULL, NULL },
-#endif
-        { "mtu", 0, 0, G_OPTION_ARG_INT, &mtu, NULL, NULL },
-        { "nameserver", 'n', 0, G_OPTION_ARG_STRING, &loaderData->dns,
-          NULL, NULL },
-        { "netmask", 'm', 0, G_OPTION_ARG_STRING, &loaderData->netmask,
-          NULL, NULL },
-        { "noipv4", 0, 0, G_OPTION_ARG_NONE, &noipv4, NULL, NULL },
-        { "noipv6", 0, 0, G_OPTION_ARG_NONE, &noipv6, NULL, NULL },
-        { "nodns", 0, 0, G_OPTION_ARG_NONE, &noDns, NULL, NULL },
-        { "hostname", 'h', 0, G_OPTION_ARG_STRING, &loaderData->hostname,
-          NULL, NULL },
-        { "ethtool", 0, 0, G_OPTION_ARG_STRING, &ethtool, NULL, NULL },
-        { "essid", 0, 0, G_OPTION_ARG_STRING, &essid, NULL, NULL },
-        { "wepkey", 0, 0, G_OPTION_ARG_STRING, &wepkey, NULL, NULL },
-        { "onboot", 0, 0, G_OPTION_ARG_STRING, &onboot, NULL, NULL },
-        { "notksdevice", 0, 0, G_OPTION_ARG_NONE, &noksdev, NULL, NULL },
-        { "dhcptimeout", 0, 0, G_OPTION_ARG_INT, &dhcpTimeout, NULL, NULL },
-        { NULL },
-    };
+static void _setNetworkString(PyObject *obj, const char *name, char **dest, int *sentinel) {
+    PyObject *attr = getObject(obj, name, 0);

-    iface_init_iface_t(&iface);
+    if (!isNotEmpty(attr))
+        goto cleanup;

-    g_option_context_set_help_enabled(optCon, FALSE);
-    g_option_context_add_main_entries(optCon, ksOptions, NULL);
+    if (*dest)
+        free(*dest);
+    *dest = strdup(PyString_AsString(attr));

-    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Bad argument to kickstart network command: %s"),
-                       optErr->message);
-        g_error_free(optErr);
-    }
+    Py_XDECREF(attr);
+
+    if (sentinel)
+        *sentinel = 1;
+
+cleanup:
+    Py_XDECREF(attr);
+}

-    g_option_context_free(optCon);
+static void setKickstartNetwork(struct loaderData_s * loaderData, PyObject *handler) {
+    PyObject *list = getDataList(handler, "network");
+    PyObject *ele, *attr, *noksdev;
+    iface_t iface;
+
+    if (!list)
+        return;
+
+    /* For now, just use the first network device as the one for loader. */
+    ele = PyList_GetItem(list, 0);
+    if (!ele)
+        goto cleanup;
+
+    iface_init_iface_t(&iface);

    /* if they've specified dhcp/bootp use dhcp for the interface */
-    if (bootProto && (!strncmp(bootProto, "dhcp", 4) ||
-                       !strncmp(bootProto, "bootp", 4))) {
+    attr = getObject(ele, "bootProto", 0);
+    if (objIsStr(attr, "dhcp") || objIsStr(attr, "bootp")) {
        loaderData->ipv4 = strdup("dhcp");
        loaderData->ipinfo_set = 1;
    } else if (loaderData->ipv4) {
-        /* JKFIXME: this assumes a bit... */
        loaderData->ipinfo_set = 1;
    }

-    /* now make sure the specified bootproto is valid */
-    if (bootProto && strcmp(bootProto, "dhcp") && strcmp(bootProto, "bootp") &&
-        strcmp(bootProto, "static") && strcmp(bootProto, "query")) {
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Bad bootproto %s specified in network command"),
-                       bootProto);
-    }
+    Py_XDECREF(attr);

    /* --gateway is common for ipv4 and ipv6, same as in loader UI */
-    if (gateway) {
+    attr = getObject(ele, "gateway", 0);
+    if (isNotEmpty(attr)) {
+        char *gateway = strdup(PyString_AsString(attr));
+        int rc;
+        struct in_addr addr;
+#ifdef ENABLE_IPV6
+        struct in6_addr addr6;
+#endif
+
        if ((rc = inet_pton(AF_INET, gateway, &addr)) == 1) {
-            loaderData->gateway = strdup(gateway);
+            loaderData->gateway = gateway;
        } else if (rc == 0) {
#ifdef ENABLE_IPV6
-            if ((rc = inet_pton(AF_INET6, gateway, &addr6)) == 1) {
-                loaderData->gateway6 = strdup(gateway);
+            if ((rc == inet_pton(AF_INET6, gateway, &addr6)) == 1) {
+                loaderData->gateway6 = gateway;
            } else if (rc == 0) {
#endif
                logMessage(WARNING,
                           "invalid address in kickstart --gateway");
#ifdef ENABLE_IPV6
            } else {
-                 logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
-                               strerror(errno));
+                logMessage(ERROR, "%s (%d): %s", __func__, __LINE__,
+                           strerror(errno));
            }
#endif
        } else {
@@ -789,8 +738,14 @@ static void setKickstartNetwork(struct loaderData_s * loaderData, int argc,
        }
    }

-    if (!noksdev) {
-        if (device) {
+    Py_XDECREF(attr);
+
+    noksdev = getObject(ele, "notksdevice", 0);
+    if (!isTrue(noksdev)) {
+        attr = getObject(ele, "device", 0);
+        if (isNotEmpty(attr)) {
+            char *device = PyString_AsString(attr);
+
            /* If --device=MAC was given, translate into a device name now. */
            if (index(device, ':') != NULL)
                loaderData->netDev = iface_mac2device(device);
@@ -800,52 +755,56 @@ static void setKickstartNetwork(struct loaderData_s * loaderData, int argc,
            loaderData->netDev_set = 1;
        }

-        if (class) {
-            loaderData->netCls = strdup(class);
-            loaderData->netCls_set = 1;
-        }
+        Py_XDECREF(attr);

-        if (ethtool) {
-            if (loaderData->ethtool)
-                free(loaderData->ethtool);
-            loaderData->ethtool = strdup(ethtool);
-            free(ethtool);
-        }
+        _setNetworkString(ele, "dhcpclass", &loaderData->netCls, &loaderData->netCls_set);
+        _setNetworkString(ele, "ethtool", &loaderData->ethtool, NULL);
+        _setNetworkString(ele, "essid", &loaderData->essid, NULL);
+        _setNetworkString(ele, "wepkey", &loaderData->wepkey, NULL);

-        if (essid) {
-            if (loaderData->essid)
-                free(loaderData->essid);
-            loaderData->essid = strdup(essid);
-            free(essid);
-        }
+        attr = getObject(ele, "noipv4", 0);
+        if (isTrue(attr))
+            flags |= LOADER_FLAGS_NOIPV4;

-        if (wepkey) {
-            if (loaderData->wepkey)
-                free(loaderData->wepkey);
-            loaderData->wepkey = strdup(wepkey);
-            free(wepkey);
-        }
+        Py_XDECREF(attr);
+
+        attr = getObject(ele, "mtu", 0);
+        if (isNotEmpty(attr)) {
+            /* Don't free this string! */
+            char *mtu = PyString_AsString(attr);
+
+            errno = 0;
+            loaderData->mtu = strtol(mtu, NULL, 10);

-        if (mtu) {
-           loaderData->mtu = mtu;
+            if ((errno == ERANGE && (loaderData->mtu == LONG_MIN ||
+                                     loaderData->mtu == LONG_MAX)) ||
+                (errno != 0 && loaderData->mtu == 0)) {
+                logMessage(ERROR, "%s: %d: %m", __func__, __LINE__);
+                abort();
+            }
        }

-        if (noipv4)
-            flags |= LOADER_FLAGS_NOIPV4;
+        Py_XDECREF(attr);

#ifdef ENABLE_IPV6
-        if (noipv6)
+        attr = getObject(ele, "noipv6", 0);
+        if (isTrue(attr))
            flags |= LOADER_FLAGS_NOIPV6;

-        if (loaderData->ipv6) {
+        if (loaderData->ipv6)
            loaderData->ipv6info_set = 1;
-        }
+
+        Py_XDECREF(attr);
#endif
    }

-    if (noDns) {
+    attr = getObject(ele, "nodns", 0);
+    if (isTrue(attr))
        loaderData->noDns = 1;
-    }
+
+    Py_XDECREF(attr);
+
+    Py_XDECREF(noksdev);

    /* Make sure the network is always up if there's a network line in the
     * kickstart file, as %post/%pre scripts might require that.
@@ -854,166 +813,165 @@ static void setKickstartNetwork(struct loaderData_s * loaderData, int argc,
        if (kickstartNetworkUp(loaderData, &iface))
            logMessage(ERROR, "unable to bring up network");
    }
-}

-static void setKickstartCD(struct loaderData_s * loaderData, int argc, char ** argv) {
-    logMessage(INFO, "kickstartFromCD");
-    loaderData->method = METHOD_CDROM;
+cleanup:
+    Py_XDECREF(list);
}

-static void setKickstartHD(struct loaderData_s * loaderData, int argc,
-                     char ** argv) {
-    char *p;
-    gchar *biospart = NULL, *partition = NULL, *dir = NULL;
-    GOptionContext *optCon = g_option_context_new(NULL);
-    GError *optErr = NULL;
-    GOptionEntry ksHDOptions[] = {
-        { "biospart", 0, 0, G_OPTION_ARG_STRING, &biospart, NULL, NULL },
-        { "partition", 0, 0, G_OPTION_ARG_STRING, &partition, NULL, NULL },
-        { "dir", 0, 0, G_OPTION_ARG_STRING, &dir, NULL, NULL },
-        { NULL },
-    };
+static void setKickstartCD(struct loaderData_s * loaderData, PyObject *handler) {
+    PyObject *methodObj = getattr(handler, "method", "method");

-    logMessage(INFO, "kickstartFromHD");
+    if (objIsStr(methodObj, "cdrom")) {
+        logMessage(INFO, "kickstartFromCD");
+        loaderData->method = METHOD_CDROM;
+    }

-    g_option_context_set_help_enabled(optCon, FALSE);
-    g_option_context_add_main_entries(optCon, ksHDOptions, NULL);
+    Py_XDECREF(methodObj);
+}

-    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
-        startNewt();
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Bad argument to HD kickstart method "
-                         "command: %s"), optErr->message);
-        g_error_free(optErr);
-        g_option_context_free(optCon);
-        return;
-    }
+static void setKickstartHD(struct loaderData_s * loaderData, PyObject *handler) {
+    PyObject *methodObj = getattr(handler, "method", "method");
+    PyObject *biospartObj = NULL;
+    char *partition = NULL, *dir = NULL;
+
+    if (!objIsStr(methodObj, "harddrive"))
+        goto cleanup;

-    g_option_context_free(optCon);
+    logMessage(INFO, "kickstartFromHD");

-    if (biospart) {
-        char * dev;
+    biospartObj = getattr(handler, "method", "biospart");
+    if (isNotEmpty(biospartObj)) {
+        char *biospart = strdup(PyString_AsString(biospartObj));
+        char *dev, *p;

        p = strchr(biospart,'p');
-        if(!p){
+        if(!p) {
            logMessage(ERROR, "Bad argument for --biospart");
-            return;
+            free(biospart);
+            goto cleanup;
        }
+
        *p = '\0';
        dev = getBiosDisk(biospart);
        if (dev == NULL) {
            logMessage(ERROR, "Unable to location BIOS partition %s", biospart);
-            return;
+            free(biospart);
+            goto cleanup;
        }
+
        partition = malloc(strlen(dev) + strlen(p + 1) + 2);
        sprintf(partition, "%s%s", dev, p + 1);
    }

    loaderData->method = METHOD_HD;
-    checked_asprintf(&loaderData->instRepo, "hd:%s:%s", partition, dir);

+    if (!partition)
+        partition = strdup(PyString_AsString(getattr(handler, "method", "partition")));
+
+    dir = strdup(PyString_AsString(getattr(handler, "method", "dir")));
+
+    checked_asprintf(&loaderData->instRepo, "hd:%s:%s", partition, dir);
    logMessage(INFO, "results of hd ks, partition is %s, dir is %s", partition,
               dir);
-}

-static void setKickstartNfs(struct loaderData_s * loaderData, int argc,
-                     char ** argv) {
-    gchar *host = NULL, *dir = NULL, *mountOpts = NULL;
-    GOptionContext *optCon = g_option_context_new(NULL);
-    GError *optErr = NULL;
-    GOptionEntry ksNfsOptions[] = {
-        { "server", 0, 0, G_OPTION_ARG_STRING, &host, NULL, NULL },
-        { "dir", 0, 0, G_OPTION_ARG_STRING, &dir, NULL, NULL },
-        { "opts", 0, 0, G_OPTION_ARG_STRING, &mountOpts, NULL, NULL },
-        { NULL },
-    };
+    free(partition);
+    free(dir);
+cleanup:
+    Py_XDECREF(methodObj);
+    Py_XDECREF(biospartObj);
+}

-    logMessage(INFO, "kickstartFromNfs");
+static void setKickstartNfs(struct loaderData_s * loaderData, PyObject *handler) {
+    PyObject *methodObj = getattr(handler, "method", "method");
+    PyObject *hostObj = NULL, *dirObj = NULL, *optsObj = NULL;
+    char *host, *dir;

-    g_option_context_set_help_enabled(optCon, FALSE);
-    g_option_context_add_main_entries(optCon, ksNfsOptions, NULL);
+    if (!objIsStr(methodObj, "nfs"))
+        goto cleanup;

-    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
-        startNewt();
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Bad argument to NFS kickstart method "
-                         "command: %s"), optErr->message);
-        g_error_free(optErr);
-        g_option_context_free(optCon);
-        return;
-    }
+    logMessage(INFO, "kickstartFromNfs");

-    g_option_context_free(optCon);
+    hostObj = getattr(handler, "method", "server");
+    dirObj = getattr(handler, "method", "dir");
+    optsObj = getattr(handler, "method", "opts");

-    if (!host || !dir) {
+    if (!isNotEmpty(hostObj) || !isNotEmpty(dirObj)) {
        logMessage(ERROR, "host and directory for nfs kickstart not specified");
-        return;
+        goto cleanup;
    }

-    logMessage(INFO, "results of nfs, host is %s, dir is %s, opts are '%s'",
-               host, dir, mountOpts);
+    /* Don't free these strings! */
+    host = PyString_AsString(hostObj);
+    dir = PyString_AsString(dirObj);

    loaderData->method = METHOD_NFS;
-    if (mountOpts) {
-        checked_asprintf(&loaderData->instRepo, "nfs:%s:%s:%s", host, mountOpts, dir);
+
+    if (isNotEmpty(optsObj)) {
+        logMessage(INFO, "results of nfs, host is %s, dir is %s, opts are '%s'",
+                   host, dir, PyString_AsString(optsObj));
+        checked_asprintf(&loaderData->instRepo, "nfs:%s:%s:%s",
+                         host, PyString_AsString(optsObj), dir);
    } else {
+        logMessage(INFO, "results of nfs, host is %s, dir is %s", host, dir);
        checked_asprintf(&loaderData->instRepo, "nfs:%s:%s", host, dir);
    }
+
+cleanup:
+    Py_XDECREF(methodObj);
+    Py_XDECREF(hostObj);
+    Py_XDECREF(dirObj);
+    Py_XDECREF(optsObj);
}

-static void setKickstartUrl(struct loaderData_s * loaderData, int argc,
-                     char ** argv) {
-    gchar *url = NULL, *proxy = NULL;
-    gboolean noverifyssl = FALSE;
-    GOptionContext *optCon = g_option_context_new(NULL);
-    GError *optErr = NULL;
-    GOptionEntry ksUrlOptions[] = {
-        { "url", 0, 0, G_OPTION_ARG_STRING, &url, NULL, NULL },
-        { "proxy", 0, 0, G_OPTION_ARG_STRING, &proxy, NULL, NULL },
-        { "noverifyssl", 0, 0, G_OPTION_ARG_NONE, &noverifyssl, NULL, NULL },
-        { NULL },
-    };
+static void setKickstartUrl(struct loaderData_s * loaderData, PyObject *handler) {
+    char *url = NULL;
+    PyObject *methodObj = getattr(handler, "method", "method");
+    PyObject *urlObj = NULL;
+    PyObject *noverifysslObj = NULL, *proxyObj = NULL;

-    logMessage(INFO, "kickstartFromUrl");
+    if (!objIsStr(methodObj, "url"))
+        goto cleanup;

-    g_option_context_set_help_enabled(optCon, FALSE);
-    g_option_context_add_main_entries(optCon, ksUrlOptions, NULL);
-
-    if (!g_option_context_parse(optCon, &argc, &argv, &optErr)) {
-        startNewt();
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Bad argument to URL kickstart method "
-                         "command: %s"), optErr->message);
-        g_error_free(optErr);
-        g_option_context_free(optCon);
-        return;
-    }
+    urlObj = getattr(handler, "method", "url");

-    g_option_context_free(optCon);
+    if (!isNotEmpty(urlObj))
+        goto cleanup;

-    if (!url) {
-        newtWinMessage(_("Kickstart Error"), _("OK"),
-                       _("Must supply a --url argument to Url kickstart method."));
-        return;
-    }
+    /* Don't free this string! */
+    url = PyString_AsString(urlObj);
+    logMessage(INFO, "kickstartFromUrl");

    /* determine install type */
    if (strncmp(url, "http", 4) && strncmp(url, "ftp://";, 6)) {
        newtWinMessage(_("Kickstart Error"), _("OK"),
                       _("Unknown Url method %s"), url);
-        return;
+        goto cleanup;
    }

+    noverifysslObj = getattr(handler, "method", "noverifyssl");
+    proxyObj = getattr(handler, "method", "proxy");
+
    loaderData->instRepo = strdup(url);
-    loaderData->instRepo_noverifyssl = noverifyssl;
    loaderData->method = METHOD_URL;

-    if (proxy) {
-        splitProxyParam(proxy, &loaderData->proxyUser,
-			       &loaderData->proxyPassword,
-			       &loaderData->proxy);
+    if (isTrue(noverifysslObj))
+        loaderData->instRepo_noverifyssl = 1;
+    else
+        loaderData->instRepo_noverifyssl = 0;
+
+    if (isNotEmpty(proxyObj)) {
+        splitProxyParam(PyString_AsString(proxyObj), &loaderData->proxyUser,
+                        &loaderData->proxyPassword,
+                        &loaderData->proxy);
    }
+
    logMessage(INFO, "results of url ks, url %s", url);
+
+cleanup:
+    Py_XDECREF(methodObj);
+    Py_XDECREF(urlObj);
+    Py_XDECREF(noverifysslObj);
+    Py_XDECREF(proxyObj);
}

int runKickstart(struct loaderData_s * loaderData, const char *file) {
@@ -1034,12 +992,15 @@ int runKickstart(struct loaderData_s * loaderData, const char *file) {
    if ((parserMod = import("pykickstart.parser")) == NULL)
        goto quit;

+    if ((constantsMod = import("pykickstart.constants")) == NULL)
+        goto quit;
+
    /* make the KickstartHandler object */
    if ((handler = makeHandler(versionMod)) == NULL)
        goto quit;

    /* make the KickstartParser object */
-    if ((callable = getCallable(parserMod, "KickstartParser")) == NULL)
+    if ((callable = getObject(parserMod, "KickstartParser", 1)) == NULL)
        goto quit;
    else
        parser = makeParser(callable, handler);
@@ -1059,12 +1020,13 @@ int runKickstart(struct loaderData_s * loaderData, const char *file) {
         * themselves will decide if they should do anything or not.
         */
        for (cmd = ksTable; cmd->name; cmd++)
-            cmd->setupData(loaderData, 0, NULL);
+            cmd->setupData(loaderData, handler);
    }

    rc = 1;

quit:
+    Py_XDECREF(constantsMod);
    Py_XDECREF(versionMod);
    Py_XDECREF(callable);
    Py_XDECREF(parserMod);
diff --git a/loader/kickstart.h b/loader/kickstart.h
index db9bb83..8f1c734 100644
--- a/loader/kickstart.h
+++ b/loader/kickstart.h
@@ -25,6 +25,5 @@ int isKickstartFileRemote(char *ksFile);
void getKickstartFile(struct loaderData_s * loaderData);
int runKickstart(struct loaderData_s * loaderData, const char *file);
int getKickstartFromBlockDevice(char *device, char *path);
-void loadKickstartModule(struct loaderData_s *, int, char **);

#endif


--
David Cantrell <dcantrell redhat com>
Supervisor, Installer Engineering Team
Red Hat, Inc. | Honolulu, HI | UTC-10


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