debconf-helper.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #!/usr/bin/python3
  2. # vim:set fileencoding=utf-8 et ts=4 sts=4 sw=4:
  3. # This file is shared between postinst and config
  4. import configparser
  5. import debconf
  6. import os
  7. import sys
  8. PREFIX_SIZE=len('apt-listchannges')
  9. DEFAULT_SEEN_DB='/var/lib/apt/listchanges.db'
  10. SECTION='apt'
  11. def _tmpl2Key(name):
  12. return name[PREFIX_SIZE:].replace('-', '_')
  13. def _debug(*args):
  14. if 'APT_LISTCHANGES_DEBCONF_DEBUG' in os.environ:
  15. print(*args, file=sys.stderr)
  16. def _handleString(cfgkey, config, template, db, fromConfig):
  17. _debug("handleString(", template, cfgkey, fromConfig, ")")
  18. if fromConfig:
  19. value = config.get(SECTION, cfgkey)
  20. if value == 'none': value = ''
  21. db.set(template, value)
  22. else:
  23. value = db.getString(template)
  24. if value == '': value = 'none'
  25. config.set(SECTION, cfgkey, value)
  26. def _handleList(cfgkey, config, template, db, fromConfig):
  27. _debug("handleList(", template, cfgkey, fromConfig, ")")
  28. if fromConfig:
  29. value = config.get(SECTION, cfgkey)
  30. db.set(template, value.lower())
  31. else:
  32. value = db.getString(template)
  33. config.set(SECTION, cfgkey, value)
  34. def _handleBoolean(cfgkey, config, template, db, fromConfig):
  35. value = config.getboolean(SECTION, cfgkey, fallback=None)
  36. _debug("handleBoolean(", template, cfgkey, fromConfig, "), old config value:", value)
  37. if fromConfig:
  38. db.set(template, str(value).lower())
  39. else:
  40. newvalue = db.getBoolean(template)
  41. if value == None or value != newvalue:
  42. config.set(SECTION, cfgkey, str(newvalue).lower())
  43. def _handleSeen(cfgkey, config, template, db, fromConfig):
  44. # The 'save-seen' is very special: a path in config file,
  45. # but in debconf is stored as boolean...
  46. value = config.get(SECTION, cfgkey, fallback=None)
  47. _debug("handleSeen(", template, cfgkey, fromConfig, "), old config value:", value)
  48. if fromConfig:
  49. db.set(template, str(value and value != 'none').lower())
  50. elif not db.getBoolean(template):
  51. value = 'none'
  52. elif not value or value == 'none':
  53. value = DEFAULT_SEEN_DB
  54. config.set(SECTION, cfgkey, value)
  55. NAMES = {'apt-listchanges/frontend' : _handleList,
  56. 'apt-listchanges/confirm' : _handleBoolean,
  57. 'apt-listchanges/email-address': _handleString,
  58. 'apt-listchanges/save-seen' : _handleSeen,
  59. 'apt-listchanges/which' : _handleList }
  60. def _updateDebconfFromConfig(config, db):
  61. _debug("updateDebconfFromConfig()")
  62. for tmpl in sorted(NAMES):
  63. cfgkey = _tmpl2Key(tmpl)
  64. if config.has_option(SECTION, cfgkey):
  65. NAMES[tmpl](cfgkey, config, tmpl, db, True)
  66. def _communicateWithDebconf(config, db, is_postinst):
  67. _debug("communicateWithDebconf(", is_postinst, ")")
  68. # Handle frontend first
  69. tmpl = 'apt-listchanges/frontend'
  70. if not is_postinst:
  71. db.forceInput(debconf.MEDIUM, tmpl)
  72. db.go()
  73. frontend = db.get(tmpl)
  74. if is_postinst:
  75. NAMES[tmpl](_tmpl2Key(tmpl), config, tmpl, db, False)
  76. del NAMES[tmpl]
  77. if frontend == 'none':
  78. return
  79. if frontend == 'mail':
  80. del NAMES['apt-listchanges/confirm']
  81. # Handle remaining variables
  82. if not is_postinst:
  83. for tmpl in sorted(NAMES):
  84. db.forceInput(debconf.LOW, tmpl)
  85. db.go()
  86. else:
  87. for tmpl in sorted(NAMES):
  88. NAMES[tmpl](_tmpl2Key(tmpl), config, tmpl, db, False)
  89. def main(argv):
  90. if len(argv) < 3:
  91. print("Usage: script postinst|config config_file mainscript_params",
  92. file=sys.stderr)
  93. sys.exit(1)
  94. debconf.runFrontEnd()
  95. is_postinst = argv[1] == 'postinst' # otherwise it is config
  96. config_file = argv[2]
  97. _debug("apt-listchanges debconf script started(", is_postinst, config_file, ")")
  98. config = configparser.ConfigParser()
  99. config.read(config_file)
  100. if not config.has_section(SECTION):
  101. config.add_section(SECTION)
  102. try:
  103. output = os.fdopen(3, "wt")
  104. except Exception as ex:
  105. _debug("failed to open file descriptor 3", str(ex))
  106. output = sys.stdout
  107. db = debconf.Debconf(write=output)
  108. if not is_postinst:
  109. _updateDebconfFromConfig(config, db)
  110. _communicateWithDebconf(config, db, is_postinst)
  111. if is_postinst:
  112. with open(config_file + '.new', 'wt') as newfile:
  113. config.write(newfile, space_around_delimiters=False)
  114. os.fchmod(newfile.fileno(), 0o644)
  115. if __name__ == "__main__":
  116. main(sys.argv)
  117. sys.exit(0)