Simple program to write static config from config-drive
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

173 lines
6.3 KiB

# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import logging
import os
import subprocess
import sys
log = logging.getLogger("glean-install")
def _find_gleansh_path():
# the "glean.sh" file is installed in /usr/bin/ on Fedora, and
# /usr/local/bin on Ubuntu/Debian thanks to differences in pip and
# where it likes to put scripts.
if os.path.exists("/usr/local/bin/glean.sh"):
return "/usr/local/bin"
if os.path.exists("/usr/bin/glean.sh"):
return "/usr/bin"
log.error("Unable to find glean.sh!")
sys.exit(1)
def install(source_file, target_file, mode='0755', replacements=dict()):
"""Install given SOURCE_FILE to TARGET_FILE with given MODE
REPLACEMENTS is a dictionary where each KEY will result in the
template "%%KEY%%" being replaced with its VALUE in TARGET_FILE
(this is just a sed -i wrapper)
:param source_file: file to be installed
:param target_file: location file is being installed to
:param mode: mode of file being installed
:param replacements: dict of key/value replacements to the file
"""
log.info("Installing %s -> %s" % (source_file, target_file))
script_dir = os.path.join(
os.path.dirname(os.path.realpath(__file__)), 'init')
cmd = ('install -D -g root -o root'
' -m {mode} {source_file} {target_file}').format(
source_file=os.path.join(script_dir, source_file),
target_file=target_file,
mode=mode)
log.info(cmd)
ret = os.system(cmd)
if ret != 0:
log.error("Failed to install %s!" % source_file)
sys.exit(ret)
for k, v in replacements.items():
log.info("Replacing %s -> %s in %s" % (k, v, target_file))
cmd = 'sed -i "s|%%{k}%%|{v}|g" {target_file}'.format(
k=k, v=v, target_file=target_file)
log.info(cmd)
ret = os.system(cmd)
if ret != 0:
log.error("Failed to substitute in %s" % target_file)
sys.exit(ret)
def main():
parser = argparse.ArgumentParser(
description='Install glean init components')
parser.add_argument("-n", "--use-nm", help="Use NetworkManager",
action="store_true")
parser.add_argument("-q", "--quiet", help="Be very quiet",
action="store_true")
args = parser.parse_args()
p = _find_gleansh_path()
if args.quiet:
logging.basicConfig(level=logging.ERROR)
else:
logging.basicConfig(level=logging.INFO)
# needs to go first because gentoo can have systemd along side openrc
if os.path.exists('/etc/gentoo-release'):
log.info('installing openrc services')
install('glean.openrc', '/etc/init.d/glean',
replacements={'GLEANSH_PATH': p})
# Needs to check for the presence of systemd and systemctl
# as apparently some packages may stage systemd init files
# when systemd is not present.
# We also cannot check the path for the init pid as the pid
# may be wrong as install is generally executed in a chroot
# with diskimage-builder.
if (os.path.exists('/usr/lib/systemd/system') and
(os.path.exists('/usr/bin/systemctl') or
os.path.exists('/bin/systemctl'))):
log.info("Installing systemd services")
log.info("glean.sh in %s" % p)
if os.path.exists('/etc/gentoo-release'):
install(
'glean-networkd.service',
'/lib/systemd/system/glean.service',
mode='0644',
replacements={'GLEANSH_PATH': p})
subprocess.call(['systemctl', 'enable', 'glean.service'])
else:
log.info("Installing %s NetworkManager support" %
"with" if args.use_nm else "without")
if args.use_nm:
service_file = 'glean-nm@.service'
else:
service_file = 'glean@.service'
install(
service_file,
'/usr/lib/systemd/system/glean@.service',
mode='0644',
replacements={'GLEANSH_PATH': p})
install(
'glean-udev.rules',
'/etc/udev/rules.d/99-glean.rules',
mode='0644')
if args.use_nm:
# glean handles resolv.conf, so this turns off nm touching
# it
install('nm-no-resolv-handling.conf',
'/etc/NetworkManager/conf.d/nm-no-resolv-handling.conf',
mode='0644')
# NetworkManager has a "after" network-pre, and
# glean@<interface> services have a "before". However, if
# udev has not yet triggered and started the glean
# service, which it seems can be quite common in a slow
# environment like a binary-translated nested-vm, systemd
# may think it is fine to start NetworkManager because
# network-pre has been reached with no blockers. Thus we
# override NetworkManager to wait for udev-settle, which
# should ensure the glean service has started; which will
# block network-pre until it finishes writing out the
# configs.
install(
'nm-udev-settle.override',
'/etc/systemd/system/NetworkManager.service.d/override.conf',
mode='0644')
elif os.path.exists('/etc/init'):
log.info("Installing upstart services")
install('glean.conf', '/etc/init/glean.conf')
elif os.path.exists('/sbin/rc-update'):
subprocess.call(['rc-update', 'add', 'glean', 'boot'])
else:
log.info("Installing sysv services")
install('glean.init', '/etc/init.d/glean')
os.system('update-rc.d glean defaults')
if __name__ == '__main__':
main()