--- 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, ðtool, 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 -- 1.7.1.1 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list