ttrss: Add backup support

- Use backup hooks to dump and restore database.
- Add functional test for backup and restore.

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
James Valleroy 2019-02-17 10:26:59 -05:00 committed by Sunil Mohan Adapa
parent 8a60581f3d
commit 1eed7d581d
No known key found for this signature in database
GPG Key ID: 43EA1CFF0AA7C5F2
6 changed files with 123 additions and 2 deletions

View File

@ -22,6 +22,7 @@ Configuration helper for Tiny Tiny RSS.
import argparse
import augeas
import os
import subprocess
from plinth import action_utils
@ -29,6 +30,7 @@ from plinth import action_utils
CONFIG_FILE = '/etc/tt-rss/config.php'
DEFAULT_FILE = '/etc/default/tt-rss'
DATABASE_FILE = '/etc/tt-rss/database.php'
DB_BACKUP_FILE = '/var/lib/plinth/backups-data/ttrss-database.sql'
def parse_arguments():
@ -40,6 +42,9 @@ def parse_arguments():
subparsers.add_parser('setup', help='Setup Tiny Tiny RSS configuration')
subparsers.add_parser('enable', help='Enable Tiny Tiny RSS site')
subparsers.add_parser('disable', help='Disable Tiny Tiny RSS site')
subparsers.add_parser('dump-database', help='Dump database to file')
subparsers.add_parser('restore-database',
help='Restore database from file')
subparsers.required = True
return parser.parse_args()
@ -120,6 +125,27 @@ def subcommand_disable(_):
action_utils.service_disable('tt-rss')
def subcommand_dump_database(_):
"""Dump database to file."""
os.makedirs(os.path.dirname(DB_BACKUP_FILE), exist_ok=True)
with open(DB_BACKUP_FILE, 'w') as db_backup_file:
_run_as_postgres(['pg_dump', 'ttrss'], stdout=db_backup_file)
def subcommand_restore_database(_):
"""Restore database from file."""
_run_as_postgres(['dropdb', 'ttrss'])
_run_as_postgres(['createdb', 'ttrss'])
with open(DB_BACKUP_FILE, 'r') as db_restore_file:
_run_as_postgres(['psql', '--dbname', 'ttrss'], stdin=db_restore_file)
def _run_as_postgres(command, stdin=None, stdout=None):
"""Run a command as postgres user."""
command = ['sudo', '--user', 'postgres'] + command
subprocess.run(command, stdin=stdin, stdout=stdout, check=True)
def load_augeas():
"""Initialize Augeas."""
aug = augeas.Augeas(flags=augeas.Augeas.NO_LOAD +

View File

@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
@apps @ttrss @sso
@apps @ttrss @sso @backups
Feature: TT-RSS News Feed Reader
Run TT-RSS News Feed Reader.
@ -28,6 +28,15 @@ Scenario: Enable ttrss application
When I enable the ttrss application
Then the ttrss service should be running
Scenario: Backup and restore ttrss
Given the ttrss application is enabled
And I subscribe to a feed
When I create a backup of the ttrss app data
And I unsubscribe from the feed
And I restore the ttrss app data backup
Then the ttrss service should be running
And I should be subscribed to the feed
Scenario: Disable ttrss application
Given the ttrss application is enabled
When I disable the ttrss application

View File

@ -240,3 +240,18 @@ def syncthing_assert_folder_present(browser, folder_name):
@then(parsers.parse('syncthing folder {folder_name:w} should not be present'))
def syncthing_assert_folder_not_present(browser, folder_name):
assert not site.syncthing_folder_is_present(browser, folder_name)
@given('I subscribe to a feed')
def ttrss_subscribe(browser):
site.ttrss_subscribe(browser)
@when('I unsubscribe from the feed')
def ttrss_unsubscribe(browser):
site.ttrss_unsubscribe(browser)
@then('I should be subscribed to the feed')
def ttrss_assert_subscribed(browser):
assert site.ttrss_is_subscribed(browser)

View File

@ -578,3 +578,53 @@ def syncthing_remove_folder(browser, folder_name):
remove_folder_dialog.find_by_xpath(remove_button_xpath).first.click()
eventually(lambda: not folder_dialog.visible)
def _ttrss_load_main_interface(browser):
"""Load the TT-RSS interface."""
access_url(browser, 'tt-rss')
overlay = browser.find_by_id('overlay')
eventually(lambda: not overlay.visible)
def _ttrss_is_feed_shown(browser, invert=False):
return browser.is_text_present('Planet Debian') != invert
def ttrss_subscribe(browser):
"""Subscribe to a feed in TT-RSS."""
_ttrss_load_main_interface(browser)
browser.find_by_text('Actions...').click()
browser.find_by_text('Subscribe to feed...').click()
browser.find_by_id(
'feedDlg_feedUrl').fill('https://planet.debian.org/atom.xml')
browser.find_by_text('Subscribe').click()
if browser.is_text_present('You are already subscribed to this feed.'):
browser.find_by_text('Cancel').click()
expand = browser.find_by_css('span.dijitTreeExpandoClosed')
if expand:
expand.first.click()
assert eventually(_ttrss_is_feed_shown, [browser])
def ttrss_unsubscribe(browser):
"""Unsubscribe from a feed in TT-RSS."""
_ttrss_load_main_interface(browser)
expand = browser.find_by_css('span.dijitTreeExpandoClosed')
if expand:
expand.first.click()
browser.find_by_text('Planet Debian').click()
browser.execute_script("quickMenuGo('qmcRemoveFeed')")
prompt = browser.get_alert()
prompt.accept()
assert eventually(_ttrss_is_feed_shown, [browser, True])
def ttrss_is_subscribed(browser):
"""Return whether subscribed to a feed in TT-RSS."""
_ttrss_load_main_interface(browser)
return browser.is_text_present('Planet Debian')

View File

@ -27,7 +27,7 @@ from plinth.menu import main_menu
from plinth.modules.users import register_group
from plinth.utils import format_lazy
from .manifest import clients
from .manifest import backup, clients
version = 3
@ -132,3 +132,13 @@ def diagnose():
check_certificate=False))
return results
def backup_pre(packet):
"""Save database contents."""
actions.superuser_run('ttrss', ['dump-database'])
def restore_post(packet):
"""Restore database contents."""
actions.superuser_run('ttrss', ['restore-database'])

View File

@ -17,6 +17,7 @@
from django.utils.translation import ugettext_lazy as _
from plinth.modules.backups.api import validate as validate_backup
from plinth.clients import store_url, validate
clients = validate([{
@ -41,3 +42,13 @@ clients = validate([{
'url': '/tt-rss'
}]
}])
backup = validate_backup({
'data': {
'files': ['/var/lib/plinth/backups-data/ttrss-database.sql']
},
'secrets': {
'files': ['/etc/tt-rss/database.php']
},
'services': ['tt-rss']
})