diff --git a/pykolab/setup/setup_imap.py b/pykolab/setup/setup_imap.py index 57b4023..584787c 100644 --- a/pykolab/setup/setup_imap.py +++ b/pykolab/setup/setup_imap.py @@ -1,174 +1,178 @@ # -*- coding: utf-8 -*- # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com) # # Jeroen van Meeuwen (Kolab Systems) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # from augeas import Augeas from Cheetah.Template import Template import os import subprocess import components import pykolab from pykolab import utils from pykolab.constants import * from pykolab.translate import _ log = pykolab.getLogger('pykolab.setup') conf = pykolab.getConf() def __init__(): components.register( 'imap', execute, description=description(), after=['ldap'] ) def description(): return _("Setup IMAP.") def execute(*args, **kw): """ Apply the necessary settings to /etc/imapd.conf """ imapd_settings = { "ldap_servers": conf.get('ldap', 'ldap_uri'), "ldap_base": conf.get('ldap', 'base_dn'), "ldap_bind_dn": conf.get('ldap', 'service_bind_dn'), "ldap_password": conf.get('ldap', 'service_bind_pw'), "ldap_filter": '(|(&(|(uid=%s)(uid=cyrus-murder))(uid=%%U))(&(|(uid=%%U)(mail=%%U@%%d)(mail=%%U@%%r))(objectclass=kolabinetorgperson)))' % (conf.get('cyrus-imap', 'admin_login')), "ldap_user_attribute": conf.get('cyrus-sasl', 'result_attribute'), "ldap_group_base": conf.get('ldap', 'base_dn'), "ldap_group_filter": "(&(cn=%u)(objectclass=ldapsubentry)(objectclass=nsroledefinition))", "ldap_group_scope": "one", "ldap_member_base": conf.get('ldap','user_base_dn'), "ldap_member_method": "attribute", "ldap_member_attribute": "nsrole", "admins": conf.get('cyrus-imap', 'admin_login'), "postuser": "shared", } template_file = None if os.path.isfile('/etc/kolab/templates/imapd.conf.tpl'): template_file = '/etc/kolab/templates/imapd.conf.tpl' elif os.path.isfile('/usr/share/kolab/templates/imapd.conf.tpl'): template_file = '/usr/share/kolab/templates/imapd.conf.tpl' elif os.path.isfile(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'imapd.conf.tpl'))): template_file = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'imapd.conf.tpl')) if not template_file == None: fp = open(template_file, 'r') template_definition = fp.read() fp.close() t = Template(template_definition, searchList=[imapd_settings]) fp = open('/etc/imapd.conf', 'w') fp.write(t.__str__()) fp.close() else: log.error(_("Could not write out Cyrus IMAP configuration file /etc/imapd.conf")) return cyrus_settings = {} template_file = None if os.path.isfile('/etc/kolab/templates/cyrus.conf.tpl'): template_file = '/etc/kolab/templates/cyrus.conf.tpl' elif os.path.isfile('/usr/share/kolab/templates/cyrus.conf.tpl'): template_file = '/usr/share/kolab/templates/cyrus.conf.tpl' elif os.path.isfile(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'cyrus.conf.tpl'))): template_file = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'cyrus.conf.tpl')) if not template_file == None: fp = open(template_file, 'r') template_definition = fp.read() fp.close() t = Template(template_definition, searchList=[cyrus_settings]) fp = open('/etc/cyrus.conf', 'w') fp.write(t.__str__()) fp.close() else: log.error(_("Could not write out Cyrus IMAP configuration file /etc/cyrus.conf")) return annotations = [ "/vendor/kolab/activesync,mailbox,string,backend,value.priv,r", "/vendor/kolab/color,mailbox,string,backend,value.shared value.priv,a", "/vendor/kolab/displayname,mailbox,string,backend,value.shared value.priv,a", "/vendor/kolab/folder-test,mailbox,string,backend,value.shared value.priv,a", "/vendor/kolab/folder-type,mailbox,string,backend,value.shared value.priv,a", "/vendor/kolab/incidences-for,mailbox,string,backend,value.shared value.priv,a", "/vendor/kolab/pxfb-readable-for,mailbox,string,backend,value.shared value.priv,a", "/vendor/kolab/uniqueid,mailbox,string,backend,value.shared value.priv,a", "/vendor/kolab/h-share-attr-desc,mailbox,string,backend,value.shared value.priv,a", "/vendor/horde/share-params,mailbox,string,backend,value.shared value.priv,a", "/vendor/x-toltec/test,mailbox,string,backend,value.shared value.priv,a", ] fp = open('/etc/imapd.annotations.conf', 'w') fp.write("\n".join(annotations)) fp.close() if os.path.isfile('/etc/default/kolab-saslauthd'): myaugeas = Augeas() setting = os.path.join('/files/etc/default/kolab-saslauthd','START') if not myaugeas.get(setting) == 'yes': myaugeas.set(setting,'yes') myaugeas.save() myaugeas.close() + imapservice = 'cyrus-imapd.service' + if os.path.isfile('/usr/lib/systemd/system/cyrus.service'): + imapservice = 'cyrus.service' + if os.path.isfile('/bin/systemctl'): subprocess.call(['systemctl', 'stop', 'saslauthd.service']) subprocess.call(['systemctl', 'restart', 'kolab-saslauthd.service']) - subprocess.call(['systemctl', 'restart', 'cyrus-imapd.service']) + subprocess.call(['systemctl', 'restart', imapservice]) elif os.path.isfile('/sbin/service'): subprocess.call(['service', 'saslauthd', 'stop']) subprocess.call(['service', 'kolab-saslauthd', 'restart']) subprocess.call(['service', 'cyrus-imapd', 'restart']) elif os.path.isfile('/usr/sbin/service'): subprocess.call(['/usr/sbin/service','saslauthd','stop']) subprocess.call(['/usr/sbin/service','kolab-saslauthd','restart']) subprocess.call(['/usr/sbin/service','cyrus-imapd','restart']) else: log.error(_("Could not start the cyrus-imapd and kolab-saslauthd services.")) if os.path.isfile('/bin/systemctl'): subprocess.call(['systemctl', 'disable', 'saslauthd.service']) subprocess.call(['systemctl', 'enable', 'kolab-saslauthd.service']) - subprocess.call(['systemctl', 'enable', 'cyrus-imapd.service']) + subprocess.call(['systemctl', 'enable', imapservice]) elif os.path.isfile('/sbin/chkconfig'): subprocess.call(['chkconfig', 'saslauthd', 'off']) subprocess.call(['chkconfig', 'kolab-saslauthd', 'on']) subprocess.call(['chkconfig', 'cyrus-imapd', 'on']) elif os.path.isfile('/usr/sbin/update-rc.d'): subprocess.call(['/usr/sbin/update-rc.d', 'saslauthd', 'disable']) subprocess.call(['/usr/sbin/update-rc.d', 'kolab-saslauthd', 'defaults']) subprocess.call(['/usr/sbin/update-rc.d', 'cyrus-imapd', 'defaults']) else: log.error(_("Could not configure to start on boot, the " + \ "cyrus-imapd and kolab-saslauthd services.")) diff --git a/pykolab/setup/setup_mta.py b/pykolab/setup/setup_mta.py index 56109fe..f2883a7 100644 --- a/pykolab/setup/setup_mta.py +++ b/pykolab/setup/setup_mta.py @@ -1,473 +1,487 @@ # -*- coding: utf-8 -*- # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com) # # Jeroen van Meeuwen (Kolab Systems) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # from augeas import Augeas from Cheetah.Template import Template import os import shutil import subprocess import components import pykolab from pykolab import utils from pykolab.constants import * from pykolab.translate import _ log = pykolab.getLogger('pykolab.setup') conf = pykolab.getConf() def __init__(): components.register('mta', execute, description=description(), after=['ldap']) def description(): return _("Setup MTA.") def execute(*args, **kw): group_filter = conf.get('ldap','kolab_group_filter') if group_filter == None: group_filter = conf.get('ldap','group_filter') user_filter = conf.get('ldap','kolab_user_filter') if user_filter == None: user_filter = conf.get('ldap','user_filter') resource_filter = conf.get('ldap', 'resource_filter') sharedfolder_filter = conf.get('ldap', 'sharedfolder_filter') server_host = utils.parse_ldap_uri(conf.get('ldap', 'ldap_uri'))[1] files = { "/etc/postfix/ldap/local_recipient_maps.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = (&(|(mail=%%s)(alias=%%s))(|%(kolab_user_filter)s%(kolab_group_filter)s%(resource_filter)s%(sharedfolder_filter)s)) result_attribute = mail """ % { "base_dn": conf.get('ldap', 'base_dn'), "server_host": server_host, "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), "kolab_user_filter": user_filter, "kolab_group_filter": group_filter, "resource_filter": resource_filter, "sharedfolder_filter": sharedfolder_filter, }, "/etc/postfix/ldap/mydestination.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(domain_base_dn)s scope = sub bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = %(domain_filter)s result_attribute = %(domain_name_attribute)s """ % { "server_host": server_host, "domain_base_dn": conf.get('ldap', 'domain_base_dn'), "domain_filter": conf.get('ldap', 'domain_filter').replace('*', '%s'), "domain_name_attribute": conf.get('ldap', 'domain_name_attribute'), "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/mailenabled_distgroups.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(group_base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s # This finds the mail enabled distribution group LDAP entry query_filter = (&(|(mail=%%s)(alias=%%s))(objectClass=kolabgroupofuniquenames)(objectclass=groupofuniquenames)(!(objectclass=groupofurls))) # From this type of group, get all uniqueMember DNs special_result_attribute = uniqueMember # Only from those DNs, get the mail result_attribute = leaf_result_attribute = mail """ % { "server_host": server_host, "group_base_dn": conf.get('ldap', 'group_base_dn'), "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/mailenabled_dynamic_distgroups.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(group_base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s # This finds the mail enabled dynamic distribution group LDAP entry query_filter = (&(|(mail=%%s)(alias=%%s))(objectClass=kolabgroupofuniquenames)(objectClass=groupOfURLs)) # From this type of group, get all memberURL searches/references special_result_attribute = memberURL # Only from those DNs, get the mail result_attribute = leaf_result_attribute = mail """ % { "server_host": server_host, "group_base_dn": conf.get('ldap', 'group_base_dn'), "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/transport_maps.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = (&(|(mailAlternateAddress=%%s)(alias=%%s)(mail=%%s))(objectclass=kolabinetorgperson)) result_attribute = mail result_format = lmtp:unix:/var/lib/imap/socket/lmtp """ % { "base_dn": conf.get('ldap', 'base_dn'), "server_host": server_host, "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/virtual_alias_maps.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = (&(|(mail=%%s)(alias=%%s))(objectclass=kolabinetorgperson)) result_attribute = mail """ % { "base_dn": conf.get('ldap', 'base_dn'), "server_host": server_host, "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/virtual_alias_maps_mailforwarding.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = (&(|(mail=%%s)(alias=%%s))(objectclass=mailrecipient)(objectclass=inetorgperson)(mailforwardingaddress=*)) result_attribute = mailForwardingAddress """ % { "base_dn": conf.get('ldap', 'base_dn'), "server_host": server_host, "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/virtual_alias_maps_sharedfolders.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = (&(|(mail=%%s)(alias=%%s))(objectclass=kolabsharedfolder)(kolabFolderType=mail)) result_attribute = kolabtargetfolder result_format = "shared+%%s" """ % { "base_dn": conf.get('ldap', 'base_dn'), "server_host": server_host, "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, } if not os.path.isdir('/etc/postfix/ldap'): os.mkdir('/etc/postfix/ldap/', 0770) for filename in files.keys(): fp = open(filename, 'w') fp.write(files[filename]) fp.close() fp = open('/etc/postfix/transport', 'a') fp.write("\n# Shared Folder Delivery for %(domain)s:\nshared@%(domain)s\t\tlmtp:unix:/var/lib/imap/socket/lmtp\n" % {'domain': conf.get('kolab', 'primary_domain')}) fp.close() subprocess.call(["postmap", "/etc/postfix/transport"]) postfix_main_settings = { "inet_interfaces": "all", "recipient_delimiter": "+", "local_recipient_maps": "ldap:/etc/postfix/ldap/local_recipient_maps.cf", "mydestination": "ldap:/etc/postfix/ldap/mydestination.cf", "transport_maps": "ldap:/etc/postfix/ldap/transport_maps.cf, hash:/etc/postfix/transport", "virtual_alias_maps": "$alias_maps, ldap:/etc/postfix/ldap/virtual_alias_maps.cf, ldap:/etc/postfix/ldap/virtual_alias_maps_mailforwarding.cf, ldap:/etc/postfix/ldap/virtual_alias_maps_sharedfolders.cf, ldap:/etc/postfix/ldap/mailenabled_distgroups.cf, ldap:/etc/postfix/ldap/mailenabled_dynamic_distgroups.cf", "smtpd_tls_auth_only": "yes", "smtpd_tls_security_level": "may", "smtp_tls_security_level": "may", "smtpd_sasl_auth_enable": "yes", "smtpd_sender_login_maps": "$local_recipient_maps", "smtpd_sender_restrictions": "permit_mynetworks, reject_sender_login_mismatch", "smtpd_recipient_restrictions": "permit_mynetworks, reject_unauth_pipelining, reject_rbl_client zen.spamhaus.org, reject_non_fqdn_recipient, reject_invalid_helo_hostname, reject_unknown_recipient_domain, reject_unauth_destination, check_policy_service unix:private/recipient_policy_incoming, permit", "smtpd_sender_restrictions": "permit_mynetworks, check_policy_service unix:private/sender_policy_incoming", "submission_recipient_restrictions": "check_policy_service unix:private/submission_policy, permit_sasl_authenticated, reject", "submission_sender_restrictions": "reject_non_fqdn_sender, check_policy_service unix:private/submission_policy, permit_sasl_authenticated, reject", "submission_data_restrictions": "check_policy_service unix:private/submission_policy", "content_filter": "smtp-amavis:[127.0.0.1]:10024" } if os.path.isfile('/etc/pki/tls/certs/make-dummy-cert') and not os.path.isfile('/etc/pki/tls/private/localhost.pem'): subprocess.call(['/etc/pki/tls/certs/make-dummy-cert', '/etc/pki/tls/private/localhost.pem']) if os.path.isfile('/etc/pki/tls/private/localhost.pem'): postfix_main_settings['smtpd_tls_cert_file'] = "/etc/pki/tls/private/localhost.pem" postfix_main_settings['smtpd_tls_key_file'] = "/etc/pki/tls/private/localhost.pem" if not os.path.isfile('/etc/postfix/main.cf'): if os.path.isfile('/usr/share/postfix/main.cf.debian'): shutil.copy( '/usr/share/postfix/main.cf.debian', '/etc/postfix/main.cf' ) # Copy header checks files for hc_file in [ 'inbound', 'internal', 'submission' ]: if not os.path.isfile("/etc/postfix/header_checks.%s" % (hc_file)): if os.path.isfile('/etc/kolab/templates/header_checks.%s' % (hc_file)): input_file = '/etc/kolab/templates/header_checks.%s' % (hc_file) elif os.path.isfile('/usr/share/kolab/templates/header_checks.%s' % (hc_file)): input_file = '/usr/share/kolab/templates/header_checks.%s' % (hc_file) elif os.path.isfile(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'header_checks.%s' % (hc_file)))): input_file = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'header_checks.%s' % (hc_file))) shutil.copy(input_file, "/etc/postfix/header_checks.%s" % (hc_file)) subprocess.call(["postmap", "/etc/postfix/header_checks.%s" % (hc_file)]) myaugeas = Augeas() setting_base = '/files/etc/postfix/main.cf/' for setting_key in postfix_main_settings.keys(): setting = os.path.join(setting_base,setting_key) current_value = myaugeas.get(setting) if current_value == None: try: myaugeas.set(setting, postfix_main_settings[setting_key]) except: insert_paths = myaugeas.match('/files/etc/postfix/main.cf/*') insert_path = insert_paths[(len(insert_paths)-1)] myaugeas.insert(insert_path, setting_key, False) log.debug(_("Setting key %r to %r") % (setting_key, postfix_main_settings[setting_key]), level=8) myaugeas.set(setting, postfix_main_settings[setting_key]) myaugeas.save() postfix_master_settings = { } if os.path.exists('/usr/lib/postfix/kolab_smtp_access_policy'): postfix_master_settings['kolab_sap_executable_path'] = '/usr/lib/postfix/kolab_smtp_access_policy' else: postfix_master_settings['kolab_sap_executable_path'] = '/usr/libexec/postfix/kolab_smtp_access_policy' template_file = None if os.path.isfile('/etc/kolab/templates/master.cf.tpl'): template_file = '/etc/kolab/templates/master.cf.tpl' elif os.path.isfile('/usr/share/kolab/templates/master.cf.tpl'): template_file = '/usr/share/kolab/templates/master.cf.tpl' elif os.path.isfile(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'master.cf.tpl'))): template_file = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'master.cf.tpl')) if not template_file == None: fp = open(template_file, 'r') template_definition = fp.read() fp.close() t = Template(template_definition, searchList=[postfix_master_settings]) fp = open('/etc/postfix/master.cf', 'w') fp.write(t.__str__()) fp.close() else: log.error(_("Could not write out Postfix configuration file /etc/postfix/master.cf")) return if os.path.isdir('/etc/postfix/sasl/'): fp = open('/etc/postfix/sasl/smtpd.conf', 'w') fp.write("pwcheck_method: saslauthd\n") fp.write("mech_list: plain login\n") fp.close() amavisd_settings = { 'ldap_server': '%(server_host)s', 'ldap_bind_dn': conf.get('ldap', 'service_bind_dn'), 'ldap_bind_pw': conf.get('ldap', 'service_bind_pw'), 'primary_domain': conf.get('kolab', 'primary_domain'), 'ldap_filter': "(|(mail=%m)(alias=%m))", 'ldap_base_dn': conf.get('ldap', 'base_dn'), 'clamdsock': '/var/spool/amavisd/clamd.sock', } template_file = None # On RPM installations, Amavis configuration is contained within a single file. - if os.path.isfile("/etc/amavisd/amavisd.conf"): + amavisconf_paths = [ + "/etc/amavisd.conf", + "/etc/amavis/amavisd.conf", + "/etc/amavisd/amavisd.conf" + ] + + amavis_conf = '' + for amavisconf_path in amavisconf_paths: + if os.path.isfile(amavisconf_path): + amavis_conf = amavisconf_path + break + + if os.path.isfile(amavis_conf): if os.path.isfile('/etc/kolab/templates/amavisd.conf.tpl'): template_file = '/etc/kolab/templates/amavisd.conf.tpl' elif os.path.isfile('/usr/share/kolab/templates/amavisd.conf.tpl'): template_file = '/usr/share/kolab/templates/amavisd.conf.tpl' elif os.path.isfile(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'amavisd.conf.tpl'))): template_file = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'amavisd.conf.tpl')) if not template_file == None: fp = open(template_file, 'r') template_definition = fp.read() fp.close() if os.path.isfile('/etc/clamd.d/amavisd.conf'): amavisdconf_content = file('/etc/clamd.d/amavisd.conf') for line in amavisdconf_content: if line.startswith('LocalSocket'): amavisd_settings['clamdsock'] = line[len('LocalSocket '):].strip() t = Template(template_definition, searchList=[amavisd_settings]) fp = None - if os.path.isdir('/etc/amavisd'): - fp = open('/etc/amavisd/amavisd.conf', 'w') - elif os.path.isdir('/etc/amavis'): - fp = open('/etc/amavis/amavisd.conf', 'w') - elif os.path.isfile('/etc/amavisd.conf'): - fp = open('/etc/amavisd.conf', 'w') + fp = open(amavis_conf, 'w') if not fp == None: fp.write(t.__str__()) fp.close() else: log.error(_("Could not write out Amavis configuration file amavisd.conf")) return # On APT installations, /etc/amavis/conf.d/ is a directory with many more files. # # Somebody could work on enhancement request #1080 to configure LDAP lookups, # while really it isn't required. else: log.info(_("Not writing out any configuration for Amavis.")) # On debian wheezy amavisd-new expects '/etc/mailname' - possibly remediable through # the #1080 enhancement mentioned above, but here's a quick fix. f = open('/etc/mailname','w') f.writelines(conf.get('kolab', 'primary_domain')) f.close() if os.path.isfile('/etc/default/spamassassin'): myaugeas = Augeas() setting = os.path.join('/files/etc/default/spamassassin','ENABLED') if not myaugeas.get(setting) == '1': myaugeas.set(setting,'1') myaugeas.save() myaugeas.close() if os.path.isfile('/etc/default/wallace'): myaugeas = Augeas() setting = os.path.join('/files/etc/default/wallace','START') if not myaugeas.get(setting) == 'yes': myaugeas.set(setting,'yes') myaugeas.save() myaugeas.close() + amavisservice = 'amavisd.service' + clamavservice = 'clamd@amavisd.service' + if os.path.isfile('/usr/lib/systemd/system/amavis.service'): + amavisservice = 'amavis.service' + if os.path.isfile('/usr/lib/systemd/system/clamd.service'): + clamavservice = 'clamd.service' + if os.path.isfile('/bin/systemctl'): subprocess.call(['systemctl', 'restart', 'postfix.service']) - subprocess.call(['systemctl', 'restart', 'amavisd.service']) - subprocess.call(['systemctl', 'restart', 'clamd@amavisd.service']) + subprocess.call(['systemctl', 'restart', amavisservice]) + subprocess.call(['systemctl', 'restart', clamavservice]) subprocess.call(['systemctl', 'restart', 'wallace.service']) elif os.path.isfile('/sbin/service'): subprocess.call(['service', 'postfix', 'restart']) subprocess.call(['service', 'amavisd', 'restart']) subprocess.call(['service', 'clamd.amavisd', 'restart']) subprocess.call(['service', 'wallace', 'restart']) elif os.path.isfile('/usr/sbin/service'): subprocess.call(['/usr/sbin/service','postfix','restart']) subprocess.call(['/usr/sbin/service','amavis','restart']) subprocess.call(['/usr/sbin/service','clamav-daemon','restart']) subprocess.call(['/usr/sbin/service','wallace','restart']) else: log.error(_("Could not start the postfix, clamav and amavisd services services.")) if os.path.isfile('/bin/systemctl'): subprocess.call(['systemctl', 'enable', 'postfix.service']) - subprocess.call(['systemctl', 'enable', 'amavisd.service']) - subprocess.call(['systemctl', 'enable', 'clamd@amavisd.service']) + subprocess.call(['systemctl', 'enable', amavisservice]) + subprocess.call(['systemctl', 'enable', clamavservice]) subprocess.call(['systemctl', 'enable', 'wallace.service']) elif os.path.isfile('/sbin/chkconfig'): subprocess.call(['chkconfig', 'postfix', 'on']) subprocess.call(['chkconfig', 'amavisd', 'on']) subprocess.call(['chkconfig', 'clamd.amavisd', 'on']) subprocess.call(['chkconfig', 'wallace', 'on']) elif os.path.isfile('/usr/sbin/update-rc.d'): subprocess.call(['/usr/sbin/update-rc.d', 'postfix', 'defaults']) subprocess.call(['/usr/sbin/update-rc.d', 'amavis', 'defaults']) subprocess.call(['/usr/sbin/update-rc.d', 'clamav-daemon', 'defaults']) subprocess.call(['/usr/sbin/update-rc.d', 'wallace', 'defaults']) else: log.error(_("Could not configure to start on boot, the " + \ "postfix, clamav and amavisd services.")) diff --git a/pykolab/setup/setup_mysql.py b/pykolab/setup/setup_mysql.py index 8c38111..2b3e17c 100644 --- a/pykolab/setup/setup_mysql.py +++ b/pykolab/setup/setup_mysql.py @@ -1,212 +1,214 @@ # -*- coding: utf-8 -*- # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com) # # Jeroen van Meeuwen (Kolab Systems) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import os import subprocess import tempfile import time import components import pykolab from pykolab import utils from pykolab.constants import * from pykolab.translate import _ log = pykolab.getLogger('pykolab.setup') conf = pykolab.getConf() def __init__(): components.register('mysql', execute, description=description()) def cli_options(): ldap_group = conf.add_cli_parser_option_group(_("MySQL Options")) ldap_group.add_option( "--mysqlserver", dest = "mysqlserver", action = "store", help = _("Specify whether to use an (existing) or (new) MySQL server.") ) def description(): return _("Setup MySQL.") def execute(*args, **kw): socket_paths = [ "/var/lib/mysql/mysql.sock", "/var/run/mysqld/mysqld.sock", "/var/run/mysql/mysql.sock", "/var/run/mysqld/mysqld.pid" ] # on CentOS7, there is MariaDB instead of MySQL mysqlservice = 'mysqld.service' if os.path.isfile('/usr/lib/systemd/system/mariadb.service'): mysqlservice = 'mariadb.service' - if os.path.isfile('/bin/systemctl') and not os.path.isfile('/usr/lib/systemd/system/' + mysqlservice): + elif os.path.isfile('/usr/lib/systemd/system/mysql.service'): + mysqlservice = 'mysql.service' + if not os.path.isfile('/usr/lib/systemd/system/' + mysqlservice): # on Debian Jessie, systemctl restart mysql mysqlservice = 'mysql' if os.path.isfile('/bin/systemctl'): subprocess.call(['/bin/systemctl', 'restart', mysqlservice]) elif os.path.isfile('/sbin/service'): subprocess.call(['/sbin/service', 'mysqld', 'restart']) elif os.path.isfile('/usr/sbin/service'): subprocess.call(['/usr/sbin/service','mysql','restart']) else: log.error(_("Could not start the MySQL database service.")) if os.path.isfile('/bin/systemctl'): subprocess.call(['/bin/systemctl', 'enable', mysqlservice]) elif os.path.isfile('/sbin/chkconfig'): subprocess.call(['/sbin/chkconfig', 'mysqld', 'on']) elif os.path.isfile('/usr/sbin/update-rc.d'): subprocess.call(['/usr/sbin/update-rc.d', 'mysql', 'defaults']) else: log.error(_("Could not configure to start on boot, the " + \ "MySQL database service.")) log.info(_("Waiting for at most 30 seconds for MySQL/MariaDB to settle...")) max_wait = 30 while max_wait > 0: for socket_path in socket_paths: if os.path.exists(socket_path): max_wait = 0 if max_wait > 0: max_wait = max_wait - 1 time.sleep(1) options = { 1: "Existing MySQL server (with root password already set).", 2: "New MySQL server (needs to be initialized)." } answer = 0 if len([x for x in socket_paths if os.path.exists(x)]) > 0: if conf.mysqlserver: if conf.mysqlserver == 'existing': answer = 1 elif conf.mysqlserver == 'new': answer = 2 if answer == 0: answer = utils.ask_menu(_("What MySQL server are we setting up?"), options) if answer == "1" or answer == 1: print >> sys.stderr, utils.multiline_message( _(""" Please supply the root password for MySQL, so we can set up user accounts for other components that use MySQL. """) ) mysql_root_password = utils.ask_question( _("MySQL root password"), password=True ) else: print >> sys.stderr, utils.multiline_message( _(""" Please supply a root password for MySQL. This password will be the administrative user for this MySQL server, and it should be kept a secret. After this setup process has completed, Kolab is going to discard and forget about this password, but you will need it for administrative tasks in MySQL. """) ) mysql_root_password = utils.ask_question( _("MySQL root password"), default=utils.generate_password(), password=True, confirm=True ) p1 = subprocess.Popen(['echo', 'UPDATE mysql.user SET Password=PASSWORD(\'%s\') WHERE User=\'root\';' % (mysql_root_password)], stdout=subprocess.PIPE) p2 = subprocess.Popen(['mysql'], stdin=p1.stdout) p1.stdout.close() p2.communicate() p1 = subprocess.Popen(['echo', 'FLUSH PRIVILEGES;'], stdout=subprocess.PIPE) p2 = subprocess.Popen(['mysql'], stdin=p1.stdout) p1.stdout.close() p2.communicate() data = """ [mysql] user=root password='%s' """ % (mysql_root_password) fp = open('/tmp/kolab-setup-my.cnf', 'w') os.chmod('/tmp/kolab-setup-my.cnf', 0600) fp.write(data) fp.close() schema_file = None for root, directories, filenames in os.walk('/usr/share/doc/'): for filename in filenames: if filename.startswith('kolab_wap') and filename.endswith('.sql'): # Skip the Oracle file if filename.endswith('oracle.sql'): continue schema_file = os.path.join(root,filename) if not schema_file == None: p1 = subprocess.Popen(['echo', 'create database kolab;'], stdout=subprocess.PIPE) p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'], stdin=p1.stdout) p1.stdout.close() p2.communicate() print >> sys.stderr, utils.multiline_message( _(""" Please supply a password for the MySQL user 'kolab'. This password will be used by Kolab services, such as the Web Administration Panel. """) ) mysql_kolab_password = utils.ask_question( _("MySQL kolab password"), default=utils.generate_password(), password=True, confirm=True ) p1 = subprocess.Popen(['echo', 'GRANT ALL PRIVILEGES ON kolab.* TO \'kolab\'@\'localhost\' IDENTIFIED BY \'%s\';' % (mysql_kolab_password)], stdout=subprocess.PIPE) p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'], stdin=p1.stdout) p1.stdout.close() p2.communicate() p1 = subprocess.Popen(['cat', schema_file], stdout=subprocess.PIPE) p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf', 'kolab'], stdin=p1.stdout) p1.stdout.close() p2.communicate() conf.command_set('kolab_wap', 'sql_uri', 'mysql://kolab:%s@localhost/kolab' % (mysql_kolab_password)) conf.command_set('kolab_smtp_access_policy', 'cache_uri', 'mysql://kolab:%s@localhost/kolab' % (mysql_kolab_password)) else: log.warning(_("Could not find the MySQL Kolab schema file")) diff --git a/pykolab/setup/setup_roundcube.py b/pykolab/setup/setup_roundcube.py index 22eb9ab..6519a79 100644 --- a/pykolab/setup/setup_roundcube.py +++ b/pykolab/setup/setup_roundcube.py @@ -1,278 +1,285 @@ # -*- coding: utf-8 -*- # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com) # # Jeroen van Meeuwen (Kolab Systems) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # from Cheetah.Template import Template import grp import hashlib import os import random import re import subprocess import sys import time import components import pykolab from pykolab import utils from pykolab.constants import * from pykolab.translate import _ log = pykolab.getLogger('pykolab.setup') conf = pykolab.getConf() def __init__(): components.register('roundcube', execute, description=description(), after=['mysql','ldap']) def description(): return _("Setup Roundcube.") def execute(*args, **kw): print >> sys.stderr, utils.multiline_message( _(""" Please supply a password for the MySQL user 'roundcube'. This password will be used by the Roundcube webmail interface. """) ) mysql_roundcube_password = utils.ask_question( _("MySQL roundcube password"), default=utils.generate_password(), password=True, confirm=True ) conf.mysql_roundcube_password = mysql_roundcube_password rc_settings = { 'des_key': re.sub( r'[^a-zA-Z0-9]', "", "%s%s" % ( hashlib.md5("%s" % random.random()).digest().encode("base64"), hashlib.md5("%s" % random.random()).digest().encode("base64") ) )[:24], 'imap_admin_login': conf.get('cyrus-imap', 'admin_login'), 'imap_admin_password': conf.get('cyrus-imap', 'admin_password'), 'ldap_base_dn': conf.get('ldap', 'base_dn'), 'ldap_group_base_dn': conf.get('ldap', 'group_base_dn'), 'ldap_group_filter': conf.get('ldap', 'group_filter'), 'ldap_ldap_uri': conf.get('ldap', 'ldap_uri'), 'ldap_resource_base_dn': conf.get('ldap', 'resource_base_dn'), 'ldap_resource_filter': conf.get('ldap', 'resource_filter'), 'ldap_service_bind_dn': conf.get('ldap', 'service_bind_dn'), 'ldap_service_bind_pw': conf.get('ldap', 'service_bind_pw'), 'ldap_user_base_dn': conf.get('ldap', 'user_base_dn'), 'ldap_user_filter': conf.get('ldap', 'user_filter'), 'primary_domain': conf.get('kolab','primary_domain'), 'mysql_uri': 'mysqli://roundcube:%s@localhost/roundcube' % (mysql_roundcube_password), 'conf': conf } - if os.access('/usr/share/roundcubemail/skins/enterprise/', os.R_OK): + rc_paths = [ + "/usr/share/roundcubemail/", + "/usr/share/roundcube/", + "/srv/www/roundcubemail/", + "/var/www/roundcubemail/" + ] + + rcpath = '' + for rc_path in rc_paths: + if os.path.isdir(rc_path): + rcpath = rc_path + break + + if not os.path.isdir(rcpath): + log.error(_("Roundcube installation path not found.")) + return + + if os.access(rcpath + 'skins/enterprise/', os.R_OK): rc_settings['skin'] = 'enterprise' - elif os.access('/usr/share/roundcubemail/skins/chameleon/', os.R_OK): + elif os.access(rcpath + 'skins/chameleon/', os.R_OK): rc_settings['skin'] = 'chameleon' else: rc_settings['skin'] = 'larry' want_files = [ 'acl.inc.php', 'calendar.inc.php', 'config.inc.php', 'kolab_addressbook.inc.php', 'kolab_auth.inc.php', 'kolab_delegation.inc.php', 'kolab_files.inc.php', 'kolab_folders.inc.php', 'libkolab.inc.php', 'managesieve.inc.php', 'owncloud.inc.php', 'password.inc.php', 'recipient_to_contact.inc.php', 'terms.html', 'terms.inc.php' ] for want_file in want_files: template_file = None if os.path.isfile('/etc/kolab/templates/roundcubemail/%s.tpl' % (want_file)): template_file = '/etc/kolab/templates/roundcubemail/%s.tpl' % (want_file) elif os.path.isfile('/usr/share/kolab/templates/roundcubemail/%s.tpl' % (want_file)): template_file = '/usr/share/kolab/templates/roundcubemail/%s.tpl' % (want_file) elif os.path.isfile(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'roundcubemail', '%s.tpl' % (want_file)))): template_file = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'roundcubemail', '%s.tpl' % (want_file))) if not template_file == None: log.debug(_("Using template file %r") % (template_file), level=8) fp = open(template_file, 'r') template_definition = fp.read() fp.close() t = Template(template_definition, searchList=[rc_settings]) log.debug( _("Successfully compiled template %r, writing out to %r") % (template_file, want_file), level=8 ) fp = None if os.path.isdir('/etc/roundcubemail'): fp = open('/etc/roundcubemail/%s' % (want_file), 'w') elif os.path.isdir('/etc/roundcube'): fp = open('/etc/roundcube/%s' % (want_file), 'w') if not fp == None: fp.write(t.__str__()) fp.close() schema_files = [] for root, directories, filenames in os.walk('/usr/share/doc/'): directories.sort() for directory in directories: if directory.startswith("roundcubemail"): for nested_root, nested_directories, nested_filenames in os.walk(os.path.join(root, directory)): for filename in nested_filenames: if filename.startswith('mysql.initial') and filename.endswith('.sql'): schema_filepath = os.path.join(nested_root,filename) if not schema_filepath in schema_files: schema_files.append(schema_filepath) if len(schema_files) > 0: break break - if os.path.isdir('/usr/share/roundcubemail'): - rcpath = '/usr/share/roundcubemail/' - elif os.path.isdir('/usr/share/roundcube'): - rcpath = '/usr/share/roundcube/' - else: - log.error(_("Roundcube installation path not found.")) - return - for root, directories, filenames in os.walk(rcpath + 'plugins/calendar/drivers/kolab/'): for filename in filenames: if filename.startswith('mysql') and filename.endswith('.sql'): schema_filepath = os.path.join(root,filename) if not schema_filepath in schema_files: schema_files.append(schema_filepath) for root, directories, filenames in os.walk(rcpath + 'plugins/libkolab/'): for filename in filenames: if filename.startswith('mysql') and filename.endswith('.sql'): schema_filepath = os.path.join(root,filename) if not schema_filepath in schema_files: schema_files.append(schema_filepath) if not os.path.isfile('/tmp/kolab-setup-my.cnf'): utils.multiline_message( """Please supply the MySQL root password""" ) mysql_root_password = utils.ask_question( _("MySQL root password"), password=True ) data = """ [mysql] user=root password='%s' """ % (mysql_root_password) fp = open('/tmp/kolab-setup-my.cnf', 'w') os.chmod('/tmp/kolab-setup-my.cnf', 0600) fp.write(data) fp.close() p1 = subprocess.Popen(['echo', 'create database roundcube;'], stdout=subprocess.PIPE) p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'], stdin=p1.stdout) p1.stdout.close() p2.communicate() p1 = subprocess.Popen(['echo', 'GRANT ALL PRIVILEGES ON roundcube.* TO \'roundcube\'@\'localhost\' IDENTIFIED BY \'%s\';' % (mysql_roundcube_password)], stdout=subprocess.PIPE) p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'], stdin=p1.stdout) p1.stdout.close() p2.communicate() for schema_file in schema_files: p1 = subprocess.Popen(['cat', schema_file], stdout=subprocess.PIPE) p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf', 'roundcube'], stdin=p1.stdout) p1.stdout.close() p2.communicate() p1 = subprocess.Popen(['echo', 'FLUSH PRIVILEGES;'], stdout=subprocess.PIPE) p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf'], stdin=p1.stdout) p1.stdout.close() p2.communicate() time.sleep(2) # Find Roundcube configuration that is not readable by the # webserver user/group. if os.path.isdir('/etc/roundcubemail/'): rccpath = "/etc/roundcubemail/" elif os.path.isdir('/etc/roundcube/'): rccpath = "/etc/roundcube" else: log.warning(_("Cannot find the configuration directory for roundcube.")) rccpath = None root_uid = 0 - for webserver_group in [ 'apache', 'www-data' ]: + for webserver_group in [ 'apache', 'www-data', 'www' ]: try: (a,b,webserver_gid,c) = grp.getgrnam(webserver_group) break except Exception, errmsg: pass if not rccpath == None: for root, directories, filenames in os.walk(rccpath): for filename in filenames: os.chown(os.path.join(root, filename), root_uid, webserver_gid) + httpservice = 'httpd.service' + if os.path.isfile('/usr/lib/systemd/system/apache2.service'): + httpservice = 'apache2.service' + if os.path.isfile('/bin/systemctl'): - if os.path.isfile('/etc/debian_version'): - subprocess.call(['/bin/systemctl', 'restart', 'apache2.service']) - else: - subprocess.call(['/bin/systemctl', 'restart', 'httpd.service']) + subprocess.call(['/bin/systemctl', 'restart', httpservice]) elif os.path.isfile('/sbin/service'): subprocess.call(['/sbin/service', 'httpd', 'restart']) elif os.path.isfile('/usr/sbin/service'): subprocess.call(['/usr/sbin/service','apache2','restart']) else: log.error(_("Could not start the webserver server service.")) if os.path.isfile('/bin/systemctl'): - if os.path.isfile('/etc/debian_version'): - subprocess.call(['/bin/systemctl', 'enable', 'apache2.service']) - else: - subprocess.call(['/bin/systemctl', 'enable', 'httpd.service']) + subprocess.call(['/bin/systemctl', 'enable', httpservice]) elif os.path.isfile('/sbin/chkconfig'): subprocess.call(['/sbin/chkconfig', 'httpd', 'on']) elif os.path.isfile('/usr/sbin/update-rc.d'): subprocess.call(['/usr/sbin/update-rc.d', 'apache2', 'defaults']) else: log.error(_("Could not configure to start on boot, the " + \ "webserver server service.")) diff --git a/pykolab/setup/setup_syncroton.py b/pykolab/setup/setup_syncroton.py index 9fdb04c..2f02d98 100644 --- a/pykolab/setup/setup_syncroton.py +++ b/pykolab/setup/setup_syncroton.py @@ -1,113 +1,111 @@ # -*- coding: utf-8 -*- # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com) # # Jeroen van Meeuwen (Kolab Systems) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # import os import subprocess import sys import time import components import pykolab from pykolab import utils from pykolab.constants import * from pykolab.translate import _ log = pykolab.getLogger('pykolab.setup') conf = pykolab.getConf() def __init__(): components.register('syncroton', execute, description=description(), after=['mysql','ldap','roundcube']) def description(): return _("Setup Syncroton.") def execute(*args, **kw): schema_files = [] for root, directories, filenames in os.walk('/usr/share/doc/'): for directory in directories: if directory.startswith("kolab-syncroton"): for root, directories, filenames in os.walk(os.path.join(root, directory)): for filename in filenames: if filename.startswith('mysql.initial') and filename.endswith('.sql'): schema_filepath = os.path.join(root,filename) if not schema_filepath in schema_files: schema_files.append(schema_filepath) break if len(schema_files) > 0: break if len(schema_files) > 0: break if not os.path.isfile('/tmp/kolab-setup-my.cnf'): utils.multiline_message( """Please supply the MySQL root password""" ) mysql_root_password = utils.ask_question( _("MySQL root password"), password=True ) data = """ [mysql] user=root password='%s' """ % (mysql_root_password) fp = open('/tmp/kolab-setup-my.cnf', 'w') os.chmod('/tmp/kolab-setup-my.cnf', 0600) fp.write(data) fp.close() for schema_file in schema_files: p1 = subprocess.Popen(['cat', schema_file], stdout=subprocess.PIPE) p2 = subprocess.Popen(['mysql', '--defaults-file=/tmp/kolab-setup-my.cnf', 'roundcube'], stdin=p1.stdout) p1.stdout.close() p2.communicate() time.sleep(2) + httpservice = 'httpd.service' + if os.path.isfile('/usr/lib/systemd/system/apache2.service'): + httpservice = 'apache2.service' + if os.path.isfile('/bin/systemctl'): - if os.path.isfile('/etc/debian_version'): - subprocess.call(['/bin/systemctl', 'restart', 'apache2.service']) - else: - subprocess.call(['/bin/systemctl', 'restart', 'httpd.service']) + subprocess.call(['/bin/systemctl', 'restart', httpservice]) elif os.path.isfile('/sbin/service'): subprocess.call(['/sbin/service', 'httpd', 'restart']) elif os.path.isfile('/usr/sbin/service'): subprocess.call(['/usr/sbin/service','apache2','restart']) else: log.error(_("Could not start the webserver server service.")) if os.path.isfile('/bin/systemctl'): - if os.path.isfile('/etc/debian_version'): - subprocess.call(['/bin/systemctl', 'enable', 'apache2.service']) - else: - subprocess.call(['/bin/systemctl', 'enable', 'httpd.service']) + subprocess.call(['/bin/systemctl', 'enable', httpservice]) elif os.path.isfile('/sbin/chkconfig'): subprocess.call(['/sbin/chkconfig', 'httpd', 'on']) elif os.path.isfile('/usr/sbin/update-rc.d'): subprocess.call(['/usr/sbin/update-rc.d', 'apache2', 'defaults']) else: log.error(_("Could not configure to start on boot, the " + \ "webserver server service."))