mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-05-20 10:34:30 +00:00
pagekite: Merge all the configuration retrieval actions
- Merge actions is-disabled, get-frontend, get-kite and get-services into get-config. This improves the initial startup time for FreedomBox service and also the page load time for pagekite app. This also significantly simplifies the code. - Only use the pagekite service enabled status determine if pagekite is enabled. Don't use the configuration setting. - For custom services, provide additional data such as display URL from get-config action. This removes the need for additional processing prepare_service_for_display() and template tag create_pagekite_service_url. - Also reduce the number of times configuration is retrieved to 1 when loading the app view page and during startup of FreedomBox service. - Ensure that all keys of the configuration always present and use that to simplify some code. - Remove ContextMixin from view DeleteServiceView that does not need it. Use AppView and drop ContextMixin. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: Veiko Aasa <veiko17@disroot.org>
This commit is contained in:
parent
ca907abb3d
commit
4247a0bd5d
@ -5,11 +5,12 @@ Configuration helper for PageKite interface.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import augeas
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import augeas
|
||||||
|
|
||||||
from plinth import action_utils
|
from plinth import action_utils
|
||||||
from plinth.modules.pagekite import utils
|
from plinth.modules.pagekite import utils
|
||||||
|
|
||||||
@ -40,19 +41,16 @@ def parse_arguments():
|
|||||||
subparsers.add_parser('start-and-enable', help='Enable PageKite service')
|
subparsers.add_parser('start-and-enable', help='Enable PageKite service')
|
||||||
subparsers.add_parser('stop-and-disable', help='Disable PageKite service')
|
subparsers.add_parser('stop-and-disable', help='Disable PageKite service')
|
||||||
subparsers.add_parser('restart', help='Restart PageKite service')
|
subparsers.add_parser('restart', help='Restart PageKite service')
|
||||||
subparsers.add_parser(
|
|
||||||
'is-disabled', help=('Whether PageKite is disabled in the file '
|
# Configuration
|
||||||
'/etc/pagekite.d/10_accounts.rc'))
|
subparsers.add_parser('get-config', help='Return current configuration')
|
||||||
|
|
||||||
# Frontend
|
# Frontend
|
||||||
subparsers.add_parser('get-frontend', help='Get pagekite frontend')
|
|
||||||
set_frontend = subparsers.add_parser('set-frontend',
|
set_frontend = subparsers.add_parser('set-frontend',
|
||||||
help='Set pagekite frontend')
|
help='Set pagekite frontend')
|
||||||
set_frontend.add_argument('url', help='frontend url')
|
set_frontend.add_argument('url', help='frontend url')
|
||||||
|
|
||||||
# Kite details (name + secret)
|
# Kite details (name + secret)
|
||||||
subparsers.add_parser('get-kite',
|
|
||||||
help='Get configured kite name and secret')
|
|
||||||
set_kite = subparsers.add_parser(
|
set_kite = subparsers.add_parser(
|
||||||
'set-kite',
|
'set-kite',
|
||||||
help='Configure kite name and its secret. Secret is read from stdin.')
|
help='Configure kite name and its secret. Secret is read from stdin.')
|
||||||
@ -60,7 +58,6 @@ def parse_arguments():
|
|||||||
help='Name of the kite (eg: mybox.pagekite.me)')
|
help='Name of the kite (eg: mybox.pagekite.me)')
|
||||||
|
|
||||||
# Add/remove pagekite services (service_on entries)
|
# Add/remove pagekite services (service_on entries)
|
||||||
subparsers.add_parser('get-services', help='Get list of enabled services')
|
|
||||||
add_service = subparsers.add_parser('add-service',
|
add_service = subparsers.add_parser('add-service',
|
||||||
help='Add a pagekite service')
|
help='Add a pagekite service')
|
||||||
add_service.add_argument('--service', help='json service dictionary')
|
add_service.add_argument('--service', help='json service dictionary')
|
||||||
@ -78,13 +75,6 @@ def subcommand_restart(_):
|
|||||||
print('restarted')
|
print('restarted')
|
||||||
|
|
||||||
|
|
||||||
def subcommand_is_disabled(_):
|
|
||||||
if aug.match(PATHS['abort_not_configured']):
|
|
||||||
print('true')
|
|
||||||
else:
|
|
||||||
print('false')
|
|
||||||
|
|
||||||
|
|
||||||
def subcommand_start_and_enable(_):
|
def subcommand_start_and_enable(_):
|
||||||
aug.remove(PATHS['abort_not_configured'])
|
aug.remove(PATHS['abort_not_configured'])
|
||||||
aug.save()
|
aug.save()
|
||||||
@ -100,13 +90,58 @@ def subcommand_stop_and_disable(_):
|
|||||||
print('disabled')
|
print('disabled')
|
||||||
|
|
||||||
|
|
||||||
def subcommand_get_frontend(_):
|
def subcommand_get_config(_):
|
||||||
"""Get pagekite frontend url"""
|
"""Print the current configuration as JSON dictionary."""
|
||||||
if aug.match(PATHS['defaults']):
|
if aug.match(PATHS['defaults']):
|
||||||
print("pagekite.net")
|
frontend = 'pagekite.net'
|
||||||
else:
|
else:
|
||||||
url = aug.get(PATHS['frontend'])
|
frontend = aug.get(PATHS['frontend']) or ''
|
||||||
print(url or '')
|
|
||||||
|
frontend = frontend.split(':')
|
||||||
|
server_domain = frontend[0]
|
||||||
|
server_port = frontend[1] if len(frontend) >= 2 else '80'
|
||||||
|
|
||||||
|
status = {
|
||||||
|
'is_enabled': action_utils.service_is_enabled('pagekite'),
|
||||||
|
'kite_name': aug.get(PATHS['kitename']),
|
||||||
|
'kite_secret': aug.get(PATHS['kitesecret']),
|
||||||
|
'server_domain': server_domain,
|
||||||
|
'server_port': server_port,
|
||||||
|
'predefined_services': {
|
||||||
|
proto: False
|
||||||
|
for proto in utils.PREDEFINED_SERVICES
|
||||||
|
},
|
||||||
|
'custom_services': [],
|
||||||
|
}
|
||||||
|
|
||||||
|
# 1. predefined_services: {'http': False, 'ssh': True, 'https': True}
|
||||||
|
# 2. custom_services: [{'protocol': 'http', 'secret' 'nono', ..}, [..]}
|
||||||
|
for match in aug.match(PATHS['service_on']):
|
||||||
|
service = dict([(param, aug.get(os.path.join(match, param)))
|
||||||
|
for param in utils.SERVICE_PARAMS])
|
||||||
|
for name, predefined_service in utils.PREDEFINED_SERVICES.items():
|
||||||
|
if service == predefined_service['params']:
|
||||||
|
status['predefined_services'][name] = True
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
status['custom_services'].append(service)
|
||||||
|
if '/' in service['protocol']:
|
||||||
|
service['protocol'], service['frontend_port'] = service[
|
||||||
|
'protocol'].split('/')
|
||||||
|
|
||||||
|
service['subdomains'] = service['kitename'].startswith('*.')
|
||||||
|
kite_name = status['kite_name']
|
||||||
|
protocol = service['protocol']
|
||||||
|
if service['subdomains']:
|
||||||
|
kite_name = f'*.{kite_name}'
|
||||||
|
|
||||||
|
url = f'{protocol}://{kite_name}'
|
||||||
|
if 'frontend_port' in service and service['frontend_port']:
|
||||||
|
url = "%s:%s" % (url, service['frontend_port'])
|
||||||
|
|
||||||
|
service['url'] = url
|
||||||
|
|
||||||
|
print(json.dumps(status))
|
||||||
|
|
||||||
|
|
||||||
def subcommand_set_frontend(arguments):
|
def subcommand_set_frontend(arguments):
|
||||||
@ -131,14 +166,6 @@ def enable_pagekitenet_frontend():
|
|||||||
print("enabled")
|
print("enabled")
|
||||||
|
|
||||||
|
|
||||||
def subcommand_get_services(arguments):
|
|
||||||
""" lists all available (enabled) services """
|
|
||||||
for match in aug.match(PATHS['service_on']):
|
|
||||||
service = dict([(param, aug.get(os.path.join(match, param)))
|
|
||||||
for param in utils.SERVICE_PARAMS])
|
|
||||||
print(json.dumps(service))
|
|
||||||
|
|
||||||
|
|
||||||
def subcommand_remove_service(arguments):
|
def subcommand_remove_service(arguments):
|
||||||
"""Searches and removes the service(s) that match all given parameters"""
|
"""Searches and removes the service(s) that match all given parameters"""
|
||||||
service = utils.load_service(arguments.service)
|
service = utils.load_service(arguments.service)
|
||||||
@ -213,14 +240,6 @@ def get_new_service_path(protocol):
|
|||||||
return os.path.join(root, str(new_index))
|
return os.path.join(root, str(new_index))
|
||||||
|
|
||||||
|
|
||||||
def subcommand_get_kite(_):
|
|
||||||
"""Print details of the currently configured kite"""
|
|
||||||
kitename = aug.get(PATHS['kitename'])
|
|
||||||
kitesecret = aug.get(PATHS['kitesecret'])
|
|
||||||
print(kitename or '')
|
|
||||||
print(kitesecret or '')
|
|
||||||
|
|
||||||
|
|
||||||
def subcommand_set_kite(arguments):
|
def subcommand_set_kite(arguments):
|
||||||
"""Set details of the kite"""
|
"""Set details of the kite"""
|
||||||
aug.set(PATHS['kitename'], arguments.kite_name)
|
aug.set(PATHS['kitename'], arguments.kite_name)
|
||||||
|
|||||||
@ -6,7 +6,6 @@
|
|||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load pagekite_extras %}
|
|
||||||
|
|
||||||
{% block page_head %}
|
{% block page_head %}
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
@ -43,14 +42,13 @@
|
|||||||
|
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
{% for service in custom_services %}
|
{% for service in custom_services %}
|
||||||
{% create_pagekite_service_url service kite_name as service_url %}
|
|
||||||
<div class="list-group-item clearfix">
|
<div class="list-group-item clearfix">
|
||||||
<span class="service">
|
<span class="service">
|
||||||
<span title="Connects {{ service_url }} to {{ service.backend_host }}:{{ service.backend_port }}">
|
<span title="Connects {{ service.url }} to {{ service.backend_host }}:{{ service.backend_port }}">
|
||||||
{% if service_url|slice:":4" == "http" %}
|
{% if service.url|slice:":4" == "http" %}
|
||||||
<a href="{{ service_url }}">{{ service_url }}</a>
|
<a href="{{ service.url }}">{{ service.url }}</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
{{ service_url }}
|
{{ service.url }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<br>
|
<br>
|
||||||
{% blocktrans trimmed with backend_host=service.backend_host backend_port=service.backend_port %}
|
{% blocktrans trimmed with backend_host=service.backend_host backend_port=service.backend_port %}
|
||||||
@ -62,7 +60,7 @@
|
|||||||
action="{% url 'pagekite:delete-custom-service' %}">
|
action="{% url 'pagekite:delete-custom-service' %}">
|
||||||
<div style='display:none'>
|
<div style='display:none'>
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ service.form.as_p }}
|
{{ service.delete_form.as_p }}
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-default"
|
<button type="submit" class="btn btn-default"
|
||||||
title="{% trans "Delete this service" %}">
|
title="{% trans "Delete this service" %}">
|
||||||
|
|||||||
@ -1,29 +0,0 @@
|
|||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
||||||
|
|
||||||
from django import template
|
|
||||||
from plinth.modules.pagekite import utils
|
|
||||||
|
|
||||||
register = template.Library()
|
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag
|
|
||||||
def create_pagekite_service_url(service, kite_name):
|
|
||||||
"""Create a URL out of a pagekite service
|
|
||||||
|
|
||||||
Parameters: - service: the service params dictionary
|
|
||||||
- kite_name: kite name from the pagekite configuration, not
|
|
||||||
from the service params
|
|
||||||
"""
|
|
||||||
# add extra information if it's missing
|
|
||||||
if 'subdomains' not in service:
|
|
||||||
service = utils.prepare_service_for_display(service)
|
|
||||||
|
|
||||||
urlparams = {'protocol': service['protocol']}
|
|
||||||
if service['subdomains']:
|
|
||||||
urlparams['kite_name'] = "*.%s" % kite_name
|
|
||||||
else:
|
|
||||||
urlparams['kite_name'] = kite_name
|
|
||||||
url = "{protocol}://{kite_name}".format(**urlparams)
|
|
||||||
if 'frontend_port' in service and service['frontend_port']:
|
|
||||||
url = "%s:%s" % (url, service['frontend_port'])
|
|
||||||
return url
|
|
||||||
@ -6,7 +6,7 @@ import os
|
|||||||
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from plinth import action_utils, actions
|
from plinth import actions
|
||||||
from plinth.signals import domain_added, domain_removed
|
from plinth.signals import domain_added, domain_removed
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
LOGGER = logging.getLogger(__name__)
|
||||||
@ -76,84 +76,9 @@ PREDEFINED_SERVICES = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_kite_details():
|
def get_config():
|
||||||
output = run(['get-kite'])
|
"""Return the current PageKite configuration."""
|
||||||
kite_details = output.split()
|
return json.loads(run(['get-config']))
|
||||||
return {'kite_name': kite_details[0], 'kite_secret': kite_details[1]}
|
|
||||||
|
|
||||||
|
|
||||||
def get_pagekite_config():
|
|
||||||
"""
|
|
||||||
Return the current PageKite configuration by executing various actions.
|
|
||||||
"""
|
|
||||||
status = {}
|
|
||||||
|
|
||||||
# PageKite service enabled/disabled
|
|
||||||
# To enable PageKite two things are necessary:
|
|
||||||
# 1) pagekite not being disabled in /etc/pagekite.d/10_account.rc
|
|
||||||
# 2) the pagekite service running
|
|
||||||
is_disabled = (run(['is-disabled']).strip() == 'true')
|
|
||||||
service_running = action_utils.service_is_running('pagekite')
|
|
||||||
status['is_enabled'] = service_running and not is_disabled
|
|
||||||
|
|
||||||
# PageKite kite details
|
|
||||||
status.update(get_kite_details())
|
|
||||||
|
|
||||||
# PageKite frontend server
|
|
||||||
server = run(['get-frontend']).strip()
|
|
||||||
|
|
||||||
# Frontend entries are only considered valid if there's a ':' in
|
|
||||||
# them otherwise, pagekite refuses to work, and we only set values
|
|
||||||
# with ':'.
|
|
||||||
if ':' in server:
|
|
||||||
server_domain, server_port = server.split(':')
|
|
||||||
status['server_domain'] = server_domain
|
|
||||||
status['server_port'] = int(server_port)
|
|
||||||
else:
|
|
||||||
status['server_domain'] = server
|
|
||||||
# No valid entry exists, default to port 80. Hack: Return
|
|
||||||
# string instead of int to force setting port on save
|
|
||||||
status['server_port'] = '80'
|
|
||||||
|
|
||||||
return status
|
|
||||||
|
|
||||||
|
|
||||||
def get_pagekite_services():
|
|
||||||
"""Get enabled services. Returns two values:
|
|
||||||
|
|
||||||
1. predefined services: {'http': False, 'ssh': True, 'https': True}
|
|
||||||
2. custom services: [{'protocol': 'http', 'secret' 'nono', ..}, [..]}
|
|
||||||
"""
|
|
||||||
custom = []
|
|
||||||
predefined = {}
|
|
||||||
# set all predefined services to 'disabled' by default
|
|
||||||
[predefined.update({proto: False}) for proto in PREDEFINED_SERVICES.keys()]
|
|
||||||
# now, search for the enabled ones
|
|
||||||
for serviceline in run(['get-services']).split('\n'):
|
|
||||||
if not serviceline: # skip empty lines
|
|
||||||
continue
|
|
||||||
|
|
||||||
service = json.loads(serviceline)
|
|
||||||
for name, predefined_service in PREDEFINED_SERVICES.items():
|
|
||||||
if service == predefined_service['params']:
|
|
||||||
predefined[name] = True
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
custom.append(service)
|
|
||||||
return predefined, custom
|
|
||||||
|
|
||||||
|
|
||||||
def prepare_service_for_display(service):
|
|
||||||
""" Add extra information that is used when displaying a service
|
|
||||||
|
|
||||||
- protocol is split into 'protocol' and 'frontend_port'
|
|
||||||
- detect whether 'subdomains' are supported (as boolean)
|
|
||||||
"""
|
|
||||||
protocol = service['protocol']
|
|
||||||
if '/' in protocol:
|
|
||||||
service['protocol'], service['frontend_port'] = protocol.split('/')
|
|
||||||
service['subdomains'] = service['kitename'].startswith('*.')
|
|
||||||
return service
|
|
||||||
|
|
||||||
|
|
||||||
def run(arguments, superuser=True, input=None):
|
def run(arguments, superuser=True, input=None):
|
||||||
@ -247,27 +172,18 @@ def update_names_module(initial_registration=False, enabled=None,
|
|||||||
"""
|
"""
|
||||||
domain_removed.send_robust(sender='pagekite',
|
domain_removed.send_robust(sender='pagekite',
|
||||||
domain_type='domain-type-pagekite')
|
domain_type='domain-type-pagekite')
|
||||||
|
config = get_config()
|
||||||
if enabled is None:
|
if enabled is None:
|
||||||
try:
|
enabled = config.get('is_enabled', False)
|
||||||
enabled = get_pagekite_config()['is_enabled']
|
|
||||||
except IndexError:
|
|
||||||
enabled = False
|
|
||||||
|
|
||||||
|
enabled_services = None
|
||||||
|
kite_name = None
|
||||||
if enabled:
|
if enabled:
|
||||||
# Get enabled services and kite name
|
kite_name = config['kite_name']
|
||||||
services = get_pagekite_services()[0]
|
services = config['predefined_services']
|
||||||
enabled_services = [
|
enabled_services = [
|
||||||
service for service in services if services[service]
|
service for service, value in services.items() if value
|
||||||
]
|
]
|
||||||
if kite_name is None:
|
|
||||||
try:
|
|
||||||
kite_name = get_kite_details()['kite_name']
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
enabled_services = None
|
|
||||||
kite_name = None
|
|
||||||
|
|
||||||
if initial_registration or (enabled and kite_name):
|
if initial_registration or (enabled and kite_name):
|
||||||
domain_added.send_robust(sender='pagekite',
|
domain_added.send_robust(sender='pagekite',
|
||||||
|
|||||||
@ -6,31 +6,14 @@ from django.utils.translation import ugettext as _
|
|||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
from django.views.generic.edit import FormView
|
from django.views.generic.edit import FormView
|
||||||
|
|
||||||
from plinth.modules import pagekite
|
from plinth.views import AppView
|
||||||
|
|
||||||
from . import utils
|
from . import utils
|
||||||
from .forms import (AddCustomServiceForm, ConfigurationForm,
|
from .forms import (AddCustomServiceForm, ConfigurationForm,
|
||||||
DeleteCustomServiceForm)
|
DeleteCustomServiceForm)
|
||||||
|
|
||||||
|
|
||||||
class ContextMixin(object):
|
class DeleteServiceView(View):
|
||||||
"""Mixin to add 'subsubmenu' and 'title' to the context.
|
|
||||||
|
|
||||||
Also adds the requirement of all necessary packages to be installed
|
|
||||||
"""
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
"""Use self.title and the module-level subsubmenu"""
|
|
||||||
context = super(ContextMixin, self).get_context_data(**kwargs)
|
|
||||||
context['app_info'] = pagekite.app.info
|
|
||||||
context['title'] = pagekite.app.info.name
|
|
||||||
context['is_enabled'] = pagekite.app.is_enabled()
|
|
||||||
return context
|
|
||||||
|
|
||||||
def dispatch(self, *args, **kwargs):
|
|
||||||
return super(ContextMixin, self).dispatch(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class DeleteServiceView(ContextMixin, View):
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
form = DeleteCustomServiceForm(request.POST)
|
form = DeleteCustomServiceForm(request.POST)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
@ -56,27 +39,25 @@ class AddCustomServiceView(FormView):
|
|||||||
return super().form_valid(form)
|
return super().form_valid(form)
|
||||||
|
|
||||||
|
|
||||||
class ConfigurationView(ContextMixin, FormView):
|
class ConfigurationView(AppView):
|
||||||
|
app_id = 'pagekite'
|
||||||
template_name = 'pagekite_configure.html'
|
template_name = 'pagekite_configure.html'
|
||||||
form_class = ConfigurationForm
|
form_class = ConfigurationForm
|
||||||
prefix = 'pagekite'
|
prefix = 'pagekite'
|
||||||
success_url = reverse_lazy('pagekite:index')
|
success_url = reverse_lazy('pagekite:index')
|
||||||
|
|
||||||
def get_context_data(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
context = super(ConfigurationView,
|
"""Load and store the current configuration."""
|
||||||
self).get_context_data(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
unused, custom_services = utils.get_pagekite_services()
|
self.config = utils.get_config()
|
||||||
for service in custom_services:
|
self.initial = self.config
|
||||||
service['form'] = AddCustomServiceForm(initial=service)
|
|
||||||
context['custom_services'] = [
|
|
||||||
utils.prepare_service_for_display(service)
|
|
||||||
for service in custom_services
|
|
||||||
]
|
|
||||||
context.update(utils.get_kite_details())
|
|
||||||
return context
|
|
||||||
|
|
||||||
def get_initial(self):
|
def get_context_data(self, *args, **kwargs):
|
||||||
return utils.get_pagekite_config()
|
context = super().get_context_data(*args, **kwargs)
|
||||||
|
for service in self.config['custom_services']:
|
||||||
|
service['delete_form'] = DeleteCustomServiceForm(initial=service)
|
||||||
|
context.update(self.config)
|
||||||
|
return context
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
form.save(self.request)
|
form.save(self.request)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user