Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More options for App handling #33

Merged
merged 12 commits into from
Nov 12, 2019
38 changes: 33 additions & 5 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,47 @@ nextcloud_urls:
# You would normally need only one. If you specify more than one, the first one
# will be as the "main" one, for pretty urls, etc.

nextcloud_remove_unknown_apps: false
# Setting to choose whether to remove or keep external apps which have not been
# installed through this role, but manually or via the Nextcloud admin interface

nextcloud_apps: []
# The ansible apps to install and enable
# Nextcloud apps to be installed, removed, enabled or disabled
# It is a list of hashes. Eg
#
# nextcloud_apps:
# - name: calendar
# version: 1.5.7
# state: enabled
#
# The action can be defined using the app's state, the following states are
# supported:
# - present: The app will be installed, the enabled status will not be changed
# - absent: The app will be removed. Only available for external apps.
# - enabled: The app will be installed if not available yet, and will be
# enabled
# - disabled: The app will be installed if not available yet, and will be
# disabled
#
# If 'version' is not given, then the latest version available for the installed
# nextcloud version will be installed.
# Installation and removal is only supported for external apps, apps shipped
# with Nextcloud can only be enabled or disabled. By default, only apps with
# the explicit state `absent` are removed, to remove all apps missing from the
# list, set `nextcloud_remove_unknown_apps: true`.
# Currently, always the latest version available from the App Store is
# installed.

nextcloud_config: {}
# A yaml array with settings of nextcloud apps. For instance:
# A yaml array with settings of nextcloud apps.
#
# Nextcloud organizes its configuration in two categories:
# - system: this category contains all basic configuration parameters for the
# framework to operate. Its keys are stored in the `config.php` file
# of the instance installation's `config` directory.
# - apps: this category contains settings for the individual apps as well as
# for some core components of the framework (in `core`). These settings
# are stored in the database directly and require a correctly
# configured system to be accessed.
#
# For instance:
# ```
# nextcloud_config:
# apps:
Expand Down
243 changes: 109 additions & 134 deletions tasks/core/apps.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
---

- name: Read builtin apps
command: ./occ app:list --shipped=SHIPPED --output=json
# Read all apps shipped by Nextcloud itself
- name: Read shipped apps
command: ./occ app:list --shipped=true --output=json
args:
chdir: "{{ nextcloud_installation_dir }}"
register: nextcloud_shipped_apps
become: true
become_user: "{{ nextcloud_file_owner }}"
register: nextcloud_shipped_apps
changed_when: false

# There might be a notice for required updates. This notice will break json
# parsing.
- name: Remove non-json text from command output
set_fact:
nextcloud_shipped_apps: >-
Expand All @@ -20,8 +19,9 @@
]
}}

- name: Read all installed apps
command: ./occ app:list --output=json
# Read all external apps which have been installed by in addition
- name: Read installed external apps
command: ./occ app:list --shipped=false --output=json
args:
chdir: "{{ nextcloud_installation_dir }}"
become: true
Expand All @@ -38,143 +38,118 @@
]
}}

- name: Install external apps
block:
- name: Find full nextcloud version
command: ./occ status --output=json
args:
chdir: "{{ nextcloud_installation_dir }}"
become: true
become_user: "{{ nextcloud_file_owner }}"
register: _result
changed_when: false

- name: Remove non-json text from command output
set_fact:
nextcloud_full_version:
"{{ (_result.stdout | from_json)['versionstring'] }}"

- name: Create app json file url
set_fact:
nextcloud_app_store_json_url: >-
https://apps.nextcloud.com/api/v1/platform/{{
nextcloud_full_version
}}/apps.json
changed_when: false
# Remove all apps from the list of external apps which are not in the
# configured list of apps, if nextcloud_remove_unknown_apps is set to true
- name: Remove unknown external apps
command: php occ app:remove "{{ item }}"
with_items: "{{ (nextcloud_installed_apps.enabled |
combine(nextcloud_installed_apps.disabled)) }}"
become: true
become_user: "{{ nextcloud_file_owner }}"
args:
chdir: "{{ nextcloud_installation_dir }}"
register: result
failed_when: result.stdout is not search('removed') or result is failed
changed_when: result is not failed
when:
- nextcloud_remove_unknown_apps
- not (nextcloud_apps | selectattr('name', 'search', item) | list)

- name: Download the app json file
get_url:
url: "{{ nextcloud_app_store_json_url }}"
dest: /tmp
register: result
until: result is success
# Remove all apps which have their state set to "absent"
- name: Remove external apps
command: php occ app:remove "{{ item.name }}"
with_items: "{{ nextcloud_apps }}"
become: true
become_user: "{{ nextcloud_file_owner }}"
nkakouros marked this conversation as resolved.
Show resolved Hide resolved
args:
chdir: "{{ nextcloud_installation_dir }}"
register: result
failed_when: result.stdout is not search('removed') or result is failed
changed_when: result is not failed
when:
- item.name in (nextcloud_installed_apps.enabled
| combine(nextcloud_installed_apps.disabled))
- item.state | default('enabled') == 'absent'

- name: Read the app json file
command: cat /tmp/apps.json
register: nextcloud_app_store_json
changed_when: false
# Install all apps from the configured list which
# - are external apps (not in the shipped apps list) and
# - are not yet installed (not in the installed apps list) and
# - have their state not set to "absent"
- name: Install external apps
command: php occ app:install "{{ item.name }}"
with_items: "{{ nextcloud_apps }}"
become: true
become_user: "{{ nextcloud_file_owner }}"
args:
chdir: "{{ nextcloud_installation_dir }}"
register: result
failed_when: result.stdout is not search('installed') or result is failed
changed_when: result is not failed
when:
- item.name not in (nextcloud_shipped_apps.enabled
| combine(nextcloud_shipped_apps.disabled))
- item.name not in (nextcloud_installed_apps.enabled
| combine(nextcloud_installed_apps.disabled))
- item.state | default('enabled') != 'absent'

- name: Parse the app json file
set_fact:
nextcloud_app_store_json:
"{{ nextcloud_app_store_json.stdout | from_json }}"
changed_when: false
# Update list of available apps after installation and removal:
- name: Re-read installed external apps
command: ./occ app:list --shipped=false --output=json
args:
chdir: "{{ nextcloud_installation_dir }}"
become: true
become_user: "{{ nextcloud_file_owner }}"
register: nextcloud_installed_apps
changed_when: false

- name: Download apps
unarchive:
src: >-
{%- set tmp=(
nextcloud_app_store_json
| selectattr('id', 'equalto', item.name)
| map(attribute='releases')
| first
| list
) -%}
{% if 'version' in item %}
{% set tmp=(
tmp
| selectattr('version', 'equalto', item.version)
| list)
%}
{% endif %}
{{ (tmp | first).download }}
dest: "{{ nextcloud_installation_dir }}/apps"
remote_src: true
mode: u=rwX,g=rX,o=rX
with_items: "{{ nextcloud_apps }}"
notify:
- set app files permissions
when: download_app | bool
vars:
download_app: >-
{#- There are three checks here: -#}
{#- 1. The app does not exist in the nextcloud installation -#}
{#- 2. The version for an app is different to the one installed -#}
{#- 3. The app was specified without a version, meaning the latest
version available should be downloaded. So, the version from
the appstore is checked against the local version -#}
{{
(
item.name not in
nextcloud_shipped_apps.enabled
| combine(nextcloud_shipped_apps.disabled)
| combine(nextcloud_shipped_apps.enabled)
| combine(nextcloud_shipped_apps.disabled)
)
or
(
item.name in
nextcloud_installed_apps.enabled
| combine(nextcloud_installed_apps.disabled)
and
'version' in item
and
item.version | default('unset') !=
(
nextcloud_installed_apps.enabled
| combine(nextcloud_installed_apps.disabled)
)[item.name]
)
or
(
(
nextcloud_app_store_json
| selectattr('id', 'equalto', item.name)
| map(attribute='releases')
| first
| list
)[0].version
!=
(
(
nextcloud_installed_apps.enabled
| combine(nextcloud_installed_apps.disabled)
) [item.name]
)
)
}}
- name: Remove non-json text from command output
set_fact:
nextcloud_installed_apps: >-
{{
nextcloud_installed_apps.stdout[
(nextcloud_installed_apps.stdout.find('{')):
]
}}

# Is this really useful? If occ supports app:update, then it makes sense
# - name: Install external apps
# command: php occ app:install "{{ item.name }}"
# with_items: "{{ nextcloud_apps }}"
# become_user: "{{ nextcloud_file_owner }}"
# args:
# chdir: "{{ nextcloud_installation_dir }}"
# register: result
# failed_when: not (result.stdout
# | search('already installed') or result.rc == 0)
# changed_when: result.rc == 0
# when: >-
# nextcloud_version >= 13 and
# item.name not in (nextcloud_installed_apps.enabled
# | combine(nextcloud_installed_apps.disabled))
# Check and update all external apps
- name: Update external apps
command: php occ app:update "{{ item }}"
with_items: "{{ (nextcloud_installed_apps.enabled
| combine(nextcloud_installed_apps.disabled)) }}"
become: true
become_user: "{{ nextcloud_file_owner }}"
args:
chdir: "{{ nextcloud_installation_dir }}"
register: result
failed_when: result.stdout is search('not installed') or result is failed
changed_when: result.stdout is search('updated') and result is not failed

# Enable all apps from the configured list which
# - are not yet enabled and
# - have their state set to "enabled"
- name: Enable apps
command: ./occ app:enable "{{ item.name }}"
args:
chdir: "{{ nextcloud_installation_dir }}"
become: true
become_user: "{{ nextcloud_file_owner }}"
with_items: "{{ nextcloud_apps }}"
when: item.name not in nextcloud_installed_apps.enabled
when:
- (item.state | default('enabled')) == 'enabled'
- item.name not in (nextcloud_installed_apps.enabled
| combine(nextcloud_shipped_apps.enabled))

# Disable all apps from the configured list which
# - are not yet disabled and
# - have their state set to "disabled"
- name: Disable apps
command: ./occ app:disable "{{ item.name }}"
args:
chdir: "{{ nextcloud_installation_dir }}"
become: true
become_user: "{{ nextcloud_file_owner }}"
with_items: "{{ nextcloud_apps }}"
when:
- (item.state | default('enabled')) == 'disabled'
- item.name not in (nextcloud_installed_apps.disabled
| combine(nextcloud_shipped_apps.disabled))