Re: frontend switching for cdebconf
On Thu, Sep 04, 2003 at 11:31:59PM +0200, Sebastian Ley wrote:
> Hello,
>
> for various reasons [1] it is useful that we can switch the frontend of
> cdebconf during the install process. I have a patch attached that
> enhances cdebconf with this capability. Usage is simple, before each GO,
> cdebconf checks whether the value of a question debconf/frontend differs
> from the currently used frontend.
This seems like a great approach. My only concern is that
DEBIAN_FRONTEND may not always be set. If there's only one frontend
available, and it gets used, does DEBIAN_FRONTEND get set? What's the
current behavior?
>
> If this is so, cdebconf destroys the old frontend, creates a new one and
> asks the question(s) of the GO-round with the new frontend.
>
> Switching the frontend is then done with a simple setting of the above
> question.
>
> A little drawback: If the loading of the new frontend fails, cdebconf
> will presently die. A fallback to the previous frontend would be
> desirable but that involves quite a bit of restructuring.
>
> Please test the patch and give comments. At this point I would like to
> advertise for testing my other cdebconf patch, which was described in my
> mail "Custom widgets for cdebconf". Theses two patches (or an
> alternative) are essential for the implemetation of a graphical
> installer.
>
> Regards,
> Sebastian
>
> [1] E.g. these reasons:
> 1. On the floppy we can drop the newt drontend, starting only with
> the text frontend. Do all the stuff for loading modules from a
> second floppy automatically, include the newt frontend there and
> switch to using it. That will save space on the first floppy.
> 2. Since there is no way to put all prerequisites for a graphical
> installer onto one boot image, we need frontend switching for
> the inclusion of a graphical installer.
>
> diff -u -r1.6 cdebconf-udeb.templates
> +++ debian/cdebconf-udeb.templates 4 Sep 2003 17:12:29 -0000
> @@ -17,3 +17,9 @@
> .
> For example, this question is of medium priority, and if your priority
> were already 'high' or 'critical', you wouldn't see this question.
> +
> +Template: debconf/frontend
> +Type: string
> +Description: Frontend to use
> + This is an internal setting. Change this setting in your script to
> + switch the cdebconf frontend upon the next GO command.
> diff -u -r1.49 commands.c
> +++ src/commands.c 4 Sep 2003 17:12:29 -0000
> @@ -6,6 +6,8 @@
> #include "template.h"
> #include "strutl.h"
>
> +#include <dlfcn.h>
> +
> #define CHECKARGC(pred) \
> ({\
> char *out; \
> @@ -183,9 +185,30 @@
> char *argv[3];
> int argc;
> char *out;
> + char *running_frontend = NULL;
> + char *requested_frontend = NULL;
> + struct question *q;
>
> argc = strcmdsplit(arg, argv, DIM(argv) - 1);
> CHECKARGC(== 0);
> +
> + q = mod->questions->methods.get(mod->questions, "debconf/frontend");
> + if (q)
> + requested_frontend = question_getvalue(q, "");
> + question_deref(q);
> +
> + running_frontend = getenv("DEBIAN_FRONTEND");
> +
> + if (requested_frontend && strcmp(running_frontend, requested_frontend) != 0) {
> + q = mod->frontend->questions;
> + mod->frontend->methods.shutdown(mod->frontend);
> + dlclose(mod->frontend->handle);
> + DELETE(mod->frontend);
> + setenv("DEBIAN_FRONTEND",requested_frontend,1);
> + mod->frontend = frontend_new(mod->config, mod->templates, mod->questions);
> + mod->frontend->questions = q;
> + }
> +
> if (mod->frontend->methods.go(mod->frontend) == CMDSTATUS_GOBACK)
> {
> asprintf(&out, "%u backup", CMDSTATUS_GOBACK);
> diff -u -r1.22 debconf.c
> +++ src/debconf.c 4 Sep 2003 17:12:29 -0000
> @@ -40,14 +40,14 @@
>
> static void cleanup()
> {
> - if (frontend != NULL)
> - frontend_delete(frontend);
> - if (questions != NULL)
> - question_db_delete(questions);
> - if (templates != NULL)
> - template_db_delete(templates);
> - if (config != NULL)
> - config_delete(config);
> + if (confmodule->frontend != NULL)
> + frontend_delete(confmodule->frontend);
> + if (confmodule->questions != NULL)
> + question_db_delete(confmodule->questions);
> + if (confmodule->templates != NULL)
> + template_db_delete(confmodule->templates);
> + if (confmodule->config != NULL)
> + config_delete(confmodule->config);
> }
>
> void sighandler(int sig)
> @@ -119,8 +119,10 @@
> /* initialize database and frontend modules */
> if ((templates = template_db_new(config, NULL)) == 0)
> DIE("Cannot initialize DebConf template database");
> + templates->methods.load(templates);
> if ((questions = question_db_new(config, templates, NULL)) == 0)
> DIE("Cannot initialize DebConf configuration database");
> + questions->methods.load(questions);
> if ((frontend = frontend_new(config, templates, questions)) == 0)
> DIE("Cannot initialize DebConf frontend");
> /* set title */
> @@ -137,10 +139,6 @@
> snprintf(buf, sizeof(buf), "Configuring %s", pkg);
> frontend->methods.set_title(frontend, buf);
> }
> -
> - /* load templates and config */
> - templates->methods.load(templates);
> - questions->methods.load(questions);
>
> /* startup the confmodule; run the config script and talk to it */
> confmodule = confmodule_new(config, templates, questions, frontend);
> diff -u -r1.21 frontend.c
> +++ src/frontend.c 4 Sep 2003 17:12:29 -0000
> @@ -122,6 +122,7 @@
> struct frontend_module *mod;
> char tmp[256];
> const char *modpath, *modname;
> + struct question *q;
>
> modname = getenv("DEBIAN_FRONTEND");
> if (modname == NULL)
> @@ -144,6 +145,10 @@
> DIE("Frontend instance driver not defined (%s)", tmp);
>
> setenv("DEBIAN_FRONTEND",modname,1);
> + q = qdb->methods.get(qdb, "debconf/frontend");
> + if (q)
> + question_setvalue(q, modname);
> + question_deref(q);
> snprintf(tmp, sizeof(tmp), "%s/%s.so", modpath, modname);
> if ((dlh = dlopen(tmp, RTLD_NOW)) == NULL)
> DIE("Cannot load frontend module %s: %s", tmp, dlerror());
--
encrypted email preferred
http://www.revolutionsummersd.com
Another American Revolution is coming...
Reply to: