244 | | ACTION_CONTINUE = 0 |
245 | | ACTION_ABORT = 1 |
246 | | |
247 | | if DEBIAN_BUILD_PACKAGE : |
248 | | ETC_DIR = "./debian/tmp/etc/pykota/" |
249 | | else : |
250 | | ETC_DIR = "/etc/pykota/" |
251 | | |
252 | | def checkOldModule(path) : |
253 | | """Checks if an old PyKota module is still in the destination (in case of upgrade).""" |
254 | | fname = os.path.join(sysconfig.get_python_lib(), "pykota", path) |
255 | | for ext in ["py", "pyc", "pyo"] : |
256 | | fullname = "%s.%s" % (fname, ext) |
257 | | if os.path.isfile(fullname) and not DEBIAN_BUILD_PACKAGE : |
258 | | sys.stderr.write("ERROR : old module %s still exists. Remove it and restart installation.\n" % fullname) |
259 | | sys.stderr.write("INSTALLATION ABORTED !\n") |
260 | | sys.exit(-1) |
261 | | |
262 | | def checkOldScript(cmd) : |
263 | | """Checks if an old shell script is still around in /usr/bin.""" |
264 | | return os.path.isfile(os.path.join("/usr/bin", cmd)) |
265 | | |
266 | | def checkModule(module) : |
267 | | """Checks if a Python module is available or not.""" |
268 | | try : |
269 | | exec "import %s" % module |
270 | | except ImportError : |
271 | | return 0 |
272 | | else : |
273 | | return 1 |
274 | | |
275 | | def checkCommand(command) : |
276 | | """Checks if a command is available or not.""" |
277 | | input = os.popen("type %s 2>/dev/null" % command) |
278 | | result = input.read().strip() |
279 | | input.close() |
280 | | return result |
281 | | |
282 | | def checkWithPrompt(prompt, module=None, command=None, helper=None) : |
283 | | """Tells the user what will be checked, and asks him what to do if something is absent.""" |
284 | | sys.stdout.write("Checking for %s availability : " % prompt) |
285 | | sys.stdout.flush() |
286 | | if command is not None : |
287 | | result = checkCommand(command) |
288 | | elif module is not None : |
289 | | result = checkModule(module) |
290 | | if result : |
291 | | sys.stdout.write("OK\n") |
292 | | return ACTION_CONTINUE |
293 | | else : |
294 | | sys.stdout.write("NO.\n") |
295 | | sys.stderr.write("ERROR : %s not available !\n" % prompt) |
296 | | if helper is not None and not DEBIAN_BUILD_PACKAGE : |
297 | | sys.stdout.write("%s\n" % helper) |
298 | | sys.stdout.write("You may continue safely if you don't need this functionnality.\n") |
299 | | answer = raw_input("%s is missing. Do you want to continue anyway (y/N) ? " % prompt) |
300 | | if DEBIAN_BUILD_PACKAGE : |
301 | | return ACTION_CONTINUE |
302 | | elif answer[0:1].upper() == 'Y' : |
303 | | return ACTION_CONTINUE |
304 | | else : |
305 | | return ACTION_ABORT |
306 | | |
307 | | if ("install" in sys.argv) and not ("help" in sys.argv) : |
308 | | # checks if Python version is correct, we need >= 2.1 |
309 | | if not (sys.version > "2.1") : |
310 | | sys.stderr.write("PyKota needs at least Python v2.1 !\nYour version seems to be older than that, please update.\nAborted !\n") |
311 | | sys.exit(-1) |
312 | | |
313 | | # checks if a configuration file is present in the new location |
314 | | if not os.path.isfile(os.path.join(ETC_DIR,"pykota.conf")) : |
315 | | if not os.path.isdir(ETC_DIR) : |
316 | | try : |
317 | | os.mkdir(ETC_DIR) |
318 | | except OSError, msg : |
319 | | sys.stderr.write("An error occured while creating the etc/pykota directory.\n%s\n" % msg) |
320 | | sys.exit(-1) |
321 | | |
322 | | if os.path.isfile("/etc/pykota.conf") and not DEBIAN_BUILD_PACKAGE : |
323 | | # upgrade from pre-1.14 to 1.14 and above |
324 | | sys.stdout.write("From version 1.14 on, PyKota expects to find its configuration\nfile in /etc/pykota/ instead of /etc/\n") |
325 | | sys.stdout.write("It seems that you've got a configuration file in the old location,\nso it will not be used anymore,\nand there's no configuration file in the new location.\n") |
326 | | answer = raw_input("Do you want to move /etc/pykota.conf to /etc/pykota/pykota.conf (y/N) ? ") |
327 | | if answer[0:1].upper() == 'Y' : |
328 | | try : |
329 | | os.rename("/etc/pykota.conf", os.path.join(ETC_DIR,"pykota.conf")) |
330 | | except OSError : |
331 | | sys.stderr.write("ERROR : An error occured while moving /etc/pykota.conf to /etc/pykota/pykota.conf\nAborted !\n") |
332 | | sys.exit(-1) |
333 | | else : |
334 | | sys.stdout.write("Configuration file /etc/pykota.conf moved to /etc/pykota/pykota.conf.\n") |
335 | | else : |
336 | | sys.stderr.write("WARNING : Configuration file /etc/pykota.conf won't be used ! Move it to /etc/pykota/ instead.\n") |
337 | | sys.stderr.write("PyKota installation will continue anyway,\nbut the software won't run until you put a proper configuration file in /etc/pykota/\n") |
338 | | dummy = raw_input("Please press ENTER when you have read the message above. ") |
339 | | else : |
340 | | # first installation |
341 | | if DEBIAN_BUILD_PACKAGE : |
342 | | try : |
343 | | shutil.copy("conf/pykota.conf.sample", os.path.join(ETC_DIR,"pykota.conf")) |
344 | | shutil.copy("conf/pykotadmin.conf.sample", os.path.join(ETC_DIR,"pykotadmin.conf")) |
345 | | except IOError, msg : |
346 | | sys.stderr.write("WARNING : Problem while installing sample configuration files in /etc/pykota/, please do it manually.\n%s\n" % msg) |
347 | | else : |
348 | | if os.path.isfile("conf/pykota.conf.sample") : |
349 | | answer = raw_input("Do you want to install\n\tconf/pykota.conf.sample as /etc/pykota/pykota.conf (y/N) ? ") |
350 | | if answer[0:1].upper() == 'Y' : |
351 | | try : |
352 | | shutil.copy("conf/pykota.conf.sample", os.path.join(ETC_DIR,"pykota.conf")) |
353 | | shutil.copy("conf/pykotadmin.conf.sample", os.path.join(ETC_DIR,"pykotadmin.conf")) |
354 | | except IOError, msg : |
355 | | sys.stderr.write("WARNING : Problem while installing sample configuration files in /etc/pykota/, please do it manually.\n%s\n" % msg) |
356 | | else : |
357 | | sys.stdout.write("Configuration file /etc/pykota/pykota.conf and /etc/pykota/pykotadmin.conf installed.\nDon't forget to adapt these files to your needs.\n") |
358 | | else : |
359 | | sys.stderr.write("WARNING : PyKota won't run without a configuration file !\n") |
360 | | else : |
361 | | # Problem ? |
362 | | sys.stderr.write("WARNING : PyKota's sample configuration file cannot be found.\nWhat you have downloaded seems to be incomplete,\nor you are not in the pykota directory.\nPlease double check, and restart the installation procedure.\n") |
363 | | dummy = raw_input("Please press ENTER when you have read the message above. ") |
364 | | else : |
365 | | # already at 1.14 or above. |
366 | | # Now check if old scripts are still in /usr/bin |
367 | | for script in ["cupspykota", "pykota", "waitprinter.sh", "papwaitprinter.sh", "mailandpopup.sh", "pagecount.pl"] : |
368 | | if checkOldScript(script) and not DEBIAN_BUILD_PACKAGE : |
369 | | sys.stderr.write("WARNING : the %s script is still present in /usr/bin, but the new version will be installed in /usr/share/pykota, please remove the %s script from /usr/bin and double check that your configuration is correct.\n" % (script, script)) |
370 | | if script == "cupspykota" : |
371 | | sys.stderr.write("\nBe sure to also remove the old symbolic link from /usr/lib/cups/backend/cupspykota to /usr/bin/cupspykota. You'll have to recreate it once the installation has finished successfully.\n") |
372 | | sys.stderr.write("\nINSTALLATION ABORTED !\nPlease correct the problem and restart installation.\n") |
373 | | sys.exit(-1) |
374 | | |
375 | | # now checks if pre-1.19alpha8 code is still there |
376 | | for module in ["accounters/querying", "accounters/external", "requesters/snmp", "requesters/external"] : |
377 | | checkOldModule(module) |
378 | | |
379 | | # Second stage, we will fail if onfiguration is incorrect for security reasons |
380 | | from pykota.config import PyKotaConfig,PyKotaConfigError |
381 | | try : |
382 | | conf = PyKotaConfig(ETC_DIR) |
383 | | except PyKotaConfigError, msg : |
384 | | sys.stedrr.write("%s\nINSTALLATION ABORTED !\nPlease restart installation.\n" % msg) |
385 | | sys.exit(-1) |
386 | | else : |
387 | | hasadmin = conf.getGlobalOption("storageadmin", ignore=1) |
388 | | hasadminpw = conf.getGlobalOption("storageadminpw", ignore=1) |
389 | | hasuser = conf.getGlobalOption("storageuser", ignore=1) |
390 | | if hasadmin or hasadminpw : |
391 | | sys.stderr.write("From version 1.14 on, PyKota expects that /etc/pykota/pykota.conf doesn't contain the Quota Storage Administrator's name and optional password.\n") |
392 | | sys.stderr.write("Please put these in a [global] section in /etc/pykota/pykotadmin.conf\n") |
393 | | sys.stderr.write("Then replace these values with 'storageuser' and 'storageuserpw' in /etc/pykota/pykota.conf\n") |
394 | | sys.stderr.write("These two fields were re-introduced to allow any user to read to his own quota, without allowing them to modify it.\n") |
395 | | sys.stderr.write("You can look at the conf/pykota.conf.sample and conf/pykotadmin.conf.sample files for examples.\n") |
396 | | sys.stderr.write("YOU HAVE TO DO THESE MODIFICATIONS MANUALLY, AND RESTART THE INSTALLATION.\n") |
397 | | sys.stderr.write("INSTALLATION ABORTED FOR SECURITY REASONS.\n") |
398 | | sys.exit(-1) |
399 | | if not hasuser : |
400 | | sys.stderr.write("From version 1.14 on, PyKota expects that /etc/pykota/pykota.conf contains the Quota Storage Normal User's name and optional password.\n") |
401 | | sys.stderr.write("Please put these in a [global] section in /etc/pykota/pykota.conf\n") |
402 | | sys.stderr.write("These fields are respectively named 'storageuser' and 'storageuserpw'.\n") |
403 | | sys.stderr.write("These two fields were re-introduced to allow any user to read to his own quota, without allowing them to modify it.\n") |
404 | | sys.stderr.write("You can look at the conf/pykota.conf.sample and conf/pykotadmin.conf.sample files for examples.\n") |
405 | | sys.stderr.write("YOU HAVE TO DO THESE MODIFICATIONS MANUALLY, AND RESTART THE INSTALLATION.\n") |
406 | | sys.stderr.write("INSTALLATION ABORTED FOR SECURITY REASONS.\n") |
407 | | sys.exit(-1) |
408 | | |
409 | | sb = conf.getStorageBackend() |
410 | | if (sb.get("storageadmin") is None) or (sb.get("storageuser") is None) : |
411 | | sys.stderr.write("From version 1.14 on, PyKota expects that /etc/pykota/pykota.conf contains the Quota Storage Normal User's name and optional password which gives READONLY access to the Print Quota DataBase,") |
412 | | sys.stderr.write("and that /etc/pykota/pykotadmin.conf contains the Quota Storage Administrator's name and optional password which gives READ/WRITE access to the Print Quota DataBase.\n") |
413 | | sys.stderr.write("Your configuration doesn't seem to be OK, please modify your configuration files in /etc/pykota/\n") |
414 | | sys.stderr.write("AND RESTART THE INSTALLATION.\n") |
415 | | sys.stderr.write("INSTALLATION ABORTED FOR SECURITY REASONS.\n") |
416 | | sys.exit(-1) |
417 | | |
418 | | # warns for new LDAP fields |
419 | | if sb.get("storagebackend") == "ldapstorage" : |
420 | | usermail = conf.getGlobalOption("usermail", ignore=1) |
421 | | newuser = conf.getGlobalOption("newuser", ignore=1) |
422 | | newgroup = conf.getGlobalOption("newgroup", ignore=1) |
423 | | if not (usermail and newuser and newgroup) : |
424 | | sys.stderr.write("From version 1.14 on, PyKota LDAP Support needs three additional configuration fields.\n") |
425 | | sys.stderr.write("Please put the 'usermail', 'newuser' and 'newgroup' configuration fields in a\n[global] section in /etc/pykota/pykota.conf\n") |
426 | | sys.stderr.write("You can look at the conf/pykota.conf.sample file for examples.\n") |
427 | | sys.stderr.write("YOU HAVE TO DO THESE MODIFICATIONS MANUALLY, AND RESTART THE INSTALLATION.\n") |
428 | | sys.stderr.write("INSTALLATION ABORTED BECAUSE CONFIGURATION INCOMPLETE.\n") |
429 | | sys.exit(-1) |
430 | | |
431 | | #### INFO #### |
432 | | |
433 | | # Say something about caching mechanism and disabling job history |
434 | | if not DEBIAN_BUILD_PACKAGE : |
435 | | sys.stdout.write("You can now activate the database caching mechanism\nwhich is disabled by default.\nIt is especially recommended with the LDAP backend.\n") |
436 | | sys.stdout.write("You can now disable the preservation of the complete\njob history which is enabled by default.\nIt is probably more useful with the LDAP backend.\n") |
437 | | sys.stdout.write("PLEASE LOOK AT THE SAMPLE CONFIGURATION FILE conf/pykota.conf.sample\n") |
438 | | sys.stdout.write("TO LEARN HOW TO DO\n") |
439 | | dummy = raw_input("Please press ENTER when you have read the message above. ") |
440 | | sys.stdout.write("\n") |
441 | | |
442 | | # change files permissions |
443 | | os.chmod(os.path.join(ETC_DIR,"pykota.conf"), 0644) |
444 | | os.chmod(os.path.join(ETC_DIR,"pykotadmin.conf"), 0640) |
445 | | |
446 | | #### INFO #### |
447 | | |
448 | | # WARNING MESSAGE |
449 | | if not DEBIAN_BUILD_PACKAGE : |
450 | | sys.stdout.write("WARNING : IF YOU ARE UPGRADING FROM A PRE-1.19alpha17 TO 1.19alpha17 OR ABOVE\n") |
451 | | sys.stdout.write("AND USE THE POSTGRESQL BACKEND, THEN YOU HAVE TO MODIFY YOUR\n") |
452 | | sys.stdout.write("DATABASE SCHEMA USING initscripts/postgresql/upgrade-to-1.19.sql\n") |
453 | | sys.stdout.write("PLEASE READ DOCUMENTATION IN initscripts/postgresql/ TO LEARN HOW TO DO.\n") |
454 | | sys.stdout.write("YOU CAN DO THAT AFTER THE INSTALLATION IS FINISHED, OR PRESS CTRL+C NOW.\n") |
455 | | sys.stdout.write("\n\nYOU DON'T HAVE ANYTHING SPECIAL TO DO IF THIS IS YOUR FIRST INSTALLATION\nOR IF YOU ARE ALREADY RUNNING VERSION 1.19alpha17 OR ABOVE.\n\n") |
456 | | dummy = raw_input("Please press ENTER when you have read the message above. ") |
457 | | |
458 | | sys.stdout.write("\n\nWARNING : IF YOU ARE UPGRADING FROM A PRE-1.19alpha10 TO 1.19alpha10 OR ABOVE\n") |
459 | | sys.stdout.write("YOU **MUST** MODIFY YOUR /etc/pykota/pykota.conf FILE BECAUSE accounter\n") |
460 | | sys.stdout.write("AND requester DIRECTIVES SUPPORTED VALUES HAVE CHANGED.\n\n") |
461 | | sys.stdout.write("YOU CAN DO THAT AFTER THE INSTALLATION IS FINISHED, OR PRESS CTRL+C NOW.\n") |
462 | | sys.stdout.write("\n\nYOU DON'T HAVE ANYTHING SPECIAL TO DO IF THIS IS YOUR FIRST INSTALLATION\nOR IF YOU ARE ALREADY RUNNING VERSION 1.19alpha10 OR ABOVE.\n\n") |
463 | | dummy = raw_input("Please press ENTER when you have read the message above. ") |
464 | | |
465 | | # checks if some needed Python modules are there or not. |
466 | | if not DEBIAN_BUILD_PACKAGE : |
467 | | modulestocheck = [ ("PygreSQL", "pg", "PygreSQL is mandatory if you want to use PostgreSQL as the quota storage backend.\nSee http://www.pygresql.org"), |
468 | | ("mxDateTime", "mx.DateTime", "eGenix' mxDateTime is mandatory for PyKota to work.\nSee http://www.egenix.com"), |
469 | | ("Python-LDAP", "ldap", "Python-LDAP is mandatory if you plan to use an LDAP\ndirectory as the quota storage backend.\nSee http://python-ldap.sf.net"), |
470 | | ("Python-OSD", "pyosd", "Python-OSD is recommended if you plan to use the X Window On Screen Display\nprint quota reminder named pykosd."), |
471 | | ("Python-SNMP", "pysnmp", "Python-SNMP is recommended if you plan to use hardware\naccounting with printers which support SNMP.\nSee http://pysnmp.sf.net"), |
472 | | ("Python-JAXML", "jaxml", "Python-JAXML is recommended if you plan to dump datas in the XML format.\nSee http://www.librelogiciel.com/software/"), |
473 | | ] |
474 | | commandstocheck = [("SNMP Tools", "snmpget", "SNMP Tools are needed if you want to use SNMP enabled printers."), ("Netatalk", "pap", "Netatalk is needed if you want to use AppleTalk enabled printers.")] |
475 | | for (name, module, helper) in modulestocheck : |
476 | | action = checkWithPrompt(name, module=module, helper=helper) |
477 | | if action == ACTION_ABORT : |
478 | | sys.stderr.write("Aborted !\n") |
479 | | sys.exit(-1) |
480 | | |
481 | | # checks if some software are there or not. |
482 | | for (name, command, helper) in commandstocheck : |
483 | | action = checkWithPrompt(name, command=command, helper=helper) |
484 | | if action == ACTION_ABORT : |
485 | | sys.stderr.write("Aborted !\n") |
486 | | sys.exit(-1) |
487 | | |