FreedomBox/actions/pagekite-configure
2014-03-23 19:09:24 +05:30

303 lines
9.4 KiB
Python
Executable File

#!/usr/bin/python
# -*- mode: python -*-
#
# This file is part of Plinth.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
Configuration helper for Plint PageKite inteface
TODO: Use augeas for manipulating /etc/pagekite.d/* files
"""
# Disable warning about invalid module name # pylint: disable-msg=C0103
import argparse
import os
import re
import subprocess
CONFIG_DIR = '/etc/pagekite.d'
SERVICE_FILE_MAP = {
'http': {
'file': '80_httpd.rc',
'match': 'http:',
'line': 'service_on = http:@kitename : localhost:80 : @kitesecret'},
'ssh': {
'file': '80_sshd.rc',
'match': 'raw/22:',
'line': 'service_on = raw/22:@kitename : localhost:22 : @kitesecret'}}
def parse_arguments():
"""Return parsed command line arguments as dictionary"""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subcommand', help='Sub command')
# Get installed status
subparsers.add_parser('get-installed',
help='Get whether PakeKite is installed')
# Start PageKite
subparsers.add_parser('start', help='Start PageKite service')
# Stop PageKite
subparsers.add_parser('stop', help='Stop PageKite service')
# Get status
subparsers.add_parser('get-status', help='Get whether PakeKite is enabled')
# Set status
set_status = subparsers.add_parser('set-status',
help='Enable/disable PageKite')
set_status.add_argument('enable', choices=['enable', 'disable'])
# Get kite details
subparsers.add_parser('get-kite',
help='Get configured kite name and secret')
# Set kite details
set_kite = subparsers.add_parser('set-kite',
help='Configure kite name and its secret')
set_kite.add_argument('--kite-name',
help='Name of the kite (eg: mybox.pagekite.me)')
set_kite.add_argument('--kite-secret', help='Secret for the kite')
# Get service status
get_service = subparsers.add_parser('get-service-status',
help='Get whether service is enabled')
get_service.add_argument('service', choices=['http', 'ssh'])
# Set service status
set_service = subparsers.add_parser('set-service-status',
help='Enable/disable a service')
set_service.add_argument('service', choices=['http', 'ssh'])
set_service.add_argument('enable', choices=['enable', 'disable'])
return parser.parse_args()
def subcommand_get_installed(_):
"""Print whether PageKite is installed"""
with open('/dev/null', 'w') as file_handle:
status = subprocess.call(['which', 'pagekite'], stdout=file_handle)
print 'installed' if not status else 'not installed'
def subcommand_start(_):
"""Start PageKite service"""
status = subprocess.call(['service', 'pagekite', 'start'])
if status:
raise Exception('Unable to start PageKite server')
def subcommand_stop(_):
"""Stop PageKite service"""
status = subprocess.call(['service', 'pagekite', 'stop'])
if status:
raise Exception('Unable to stop PageKite server')
def subcommand_get_status(_):
"""Print status of the pagekite service"""
is_enabled = is_pagekite_enabled()
print 'enabled' if is_enabled else 'disabled'
def is_pagekite_enabled():
"""Return if pagekite is enabled"""
service_file_path = os.path.join(CONFIG_DIR, '10_account.rc')
try:
with open(service_file_path, 'r') as file_object:
for line in file_object:
regex = r'^[ \t]*abort_not_configured'
if re.match(regex, line):
return False
except Exception:
return True
return True
def subcommand_set_status(arguments):
"""Enable/disable the pagekite service"""
enable = arguments.enable == 'enable'
is_enabled = is_pagekite_enabled()
if enable and is_enabled:
print 'already enabled'
return
if not enable and not is_enabled:
print 'already disabled'
return
if enable:
pagekite_enable()
print 'enabled'
else:
pagekite_disable()
print 'disabled'
def pagekite_enable():
"""Enable the pagekite daemon"""
file_path = os.path.join(CONFIG_DIR, '10_account.rc')
file_path_new = os.path.join(CONFIG_DIR, '10_account.rc.new')
with open(file_path, 'r') as read_file_object, \
open(file_path_new, 'w') as write_file_object:
for line in read_file_object:
if not re.match('^[ \t]*abort_not_configured', line):
write_file_object.write(line)
os.rename(file_path_new, file_path)
def pagekite_disable():
"""Disable the pagekite daemon"""
file_path = os.path.join(CONFIG_DIR, '10_account.rc')
with open(file_path, 'a') as file_object:
file_object.write('abort_not_configured\n')
def subcommand_get_kite(_):
"""Print details of the currently configure kite"""
kite_name = ''
kite_secret = ''
file_path = os.path.join(CONFIG_DIR, '10_account.rc')
with open(file_path, 'r') as file_object:
for line in file_object:
match = re.match(r'[ \t]*kitename[ \t]*=[ \t]*(.*)', line)
if match:
kite_name = match.group(1)
continue
match = re.match(r'[ \t]*kitesecret[ \t]*=[ \t]*(.*)', line)
if match:
kite_secret = match.group(1)
continue
print kite_name
print kite_secret
def subcommand_set_kite(arguments):
"""Set details of the kite"""
kite_name = arguments.kite_name
kite_secret = arguments.kite_secret
file_path = os.path.join(CONFIG_DIR, '10_account.rc')
file_path_new = os.path.join(CONFIG_DIR, '10_account.rc.new')
with open(file_path, 'r') as read_file_object, \
os.fdopen(os.open(file_path_new, os.O_WRONLY | os.O_CREAT,
0400), 'w') as write_file_object:
for line in read_file_object:
if re.match(r'[ \t]*kitename[ \t]*=.*', line):
write_file_object.write(
'kitename = {kite_name}\n'.format(kite_name=kite_name))
continue
if re.match(r'[ \t]*kitesecret[ \t]*=.*', line):
write_file_object.write('kitesecret = {kite_secret}\n'
.format(kite_secret=kite_secret))
continue
write_file_object.write(line)
os.rename(file_path_new, file_path)
def subcommand_get_service_status(arguments):
"""Print status of the pagekite service"""
is_enabled = is_service_enabled(arguments.service)
print 'enabled' if is_enabled else 'disabled'
def is_service_enabled(service):
"""Return if a service is enabled"""
service = SERVICE_FILE_MAP[service]
service_file_path = os.path.join(CONFIG_DIR, service['file'])
if not os.path.isfile(service_file_path):
return False
try:
with open(service_file_path, 'r') as file_object:
for line in file_object:
regex = '[ \t]*service_on[ \t]*=[ \t]*{match}'
regex = regex.format(match=service['match'])
if re.match(regex, line):
return True
except Exception:
return False
return False
def subcommand_set_service_status(arguments):
"""Enable/disable a pagekite service"""
enable = arguments.enable == 'enable'
is_enabled = is_service_enabled(arguments.service)
if enable and is_enabled:
print 'already enabled'
return
if not enable and not is_enabled:
print 'already disabled'
return
if enable:
service_enable(arguments.service)
print 'enabled'
else:
service_disable(arguments.service)
print 'disabled'
def service_enable(service_name):
"""Enable a service"""
service = SERVICE_FILE_MAP[service_name]
service_file_path = os.path.join(CONFIG_DIR, service['file'])
with open(service_file_path, 'w') as file_object:
file_object.write('''
# Expose the local {service_name} daemon
# File auto-generated by Plinth
{line}
'''.format(service_name=service_name, line=service['line']))
def service_disable(service_name):
"""Disable a service"""
service = SERVICE_FILE_MAP[service_name]
service_file_path = os.path.join(CONFIG_DIR, service['file'])
service_file_path_new = os.path.join(CONFIG_DIR,
service['file'] + '.plinthbak')
os.rename(service_file_path, service_file_path_new)
def main():
"""Parse arguments and perform all duties"""
arguments = parse_arguments()
subcommand = arguments.subcommand.replace('-', '_')
subcommand_method = globals()['subcommand_' + subcommand]
subcommand_method(arguments)
if __name__ == "__main__":
main()