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

Support installing different content plus config for Kolibri and Endless Key #118

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions config/defaults.ini
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,12 @@ regular_users_can_manage_content = false
# # Kolibri 0.12.2 User Guide for Admins [document]
# 5bb37c1832c8489ab2940f31588305f6

[key]
# Preloaded content or the Endless Key app
# The Endless Key app can be pre-loaded with content from the Kolibri channels
# listed in this setting.
install_channels =

[usb]
size = 16000000000
free_space = 1000
Expand Down
104 changes: 63 additions & 41 deletions hooks/image/60-kolibri-content
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Populate the Kolibri home directory

if [ -z "${EIB_KOLIBRI_INSTALL_CHANNELS}" ]; then
if [ -z "${EIB_KOLIBRI_INSTALL_CHANNELS}" &&
-z "${EIB_KEY_INSTALL_CHANNELS}" ]; then
exit 0
fi

Expand All @@ -15,7 +16,8 @@ export KOLIBRI_STATIC_USE_SYMLINKS=0

import_kolibri_channel()
{
local channel_id=$1
local app_name=$1
local channel_id=$2
local channel_include_node_ids_var="EIB_KOLIBRI_${channel_id^^}_INCLUDE_NODE_IDS"
local channel_exclude_node_ids_var="EIB_KOLIBRI_${channel_id^^}_EXCLUDE_NODE_IDS"
local importcontent_opts=(
Expand Down Expand Up @@ -45,42 +47,62 @@ import_kolibri_channel()
network "${importcontent_network_opts[@]}" "${channel_id}"
}

# Needs to be kept in sync with hooks/image/61-kolibri-content-install
KOLIBRI_CONTENT_DIR="${EIB_CONTENTDIR}/kolibri-content"
# FIXME: For now, we need to remove old content that may exist from previous
# runs to prevent images accidentally getting extra channels that are not in
# their configuration. However, this defeats the purpose of the image builder
# saving the contents of EIB_CONTENTDIR between runs to improve its performance.
# At some point we should revisit this to try to make the caching work properly.
rm -rf "${KOLIBRI_CONTENT_DIR}"
mkdir -p "${KOLIBRI_CONTENT_DIR}"

venv_dir="${EIB_TMPDIR}/kolibri-content-venv"
python3 -m venv ${venv_dir}
source ${venv_dir}/bin/activate

pip install kolibri==${EIB_KOLIBRI_APP_VERSION}
pip install kolibri-app-desktop-xdg-plugin==${EIB_KOLIBRI_APP_DESKTOP_XDG_PLUGIN_VERSION}
pip install kolibri-desktop-auth-plugin==${EIB_KOLIBRI_DESKTOP_AUTH_PLUGIN_VERSION}

export KOLIBRI_HOME="${KOLIBRI_CONTENT_DIR}"

kolibri plugin enable kolibri.plugins.app
kolibri plugin enable kolibri_app_desktop_xdg_plugin
kolibri plugin enable kolibri_desktop_auth_plugin

for channel_id in ${EIB_KOLIBRI_INSTALL_CHANNELS}; do
import_kolibri_channel "${channel_id}"
done

# Sort channels in the same order as in EIB_KOLIBRI_INSTALL_CHANNELS
position=1
for channel_id in ${EIB_KOLIBRI_INSTALL_CHANNELS}; do
kolibri manage setchannelposition ${channel_id} ${position} || true
let position=position+1
done

# Empty the user database, and ensure that each instance of this image has a
# unique Facility ID.
# <https://kolibri.readthedocs.io/en/latest/install/provision.html#prepare-the-kolibri-folder-for-copying>
(echo yes; echo yes) | kolibri manage deprovision
prepare_kolibri_env()
{
local app_name=$1
# Needs to be kept in sync with hooks/image/61-kolibri-content-install
KOLIBRI_CONTENT_DIR="${EIB_CONTENTDIR}/${app_name}-content"
# FIXME: For now, we need to remove old content that may exist from previous
# runs to prevent images accidentally getting extra channels that are not in
# their configuration. However, this defeats the purpose of the image builder
# saving the contents of EIB_CONTENTDIR between runs to improve its performance.
# At some point we should revisit this to try to make the caching work properly.
rm -rf "${KOLIBRI_CONTENT_DIR}"
mkdir -p "${KOLIBRI_CONTENT_DIR}"

venv_dir="${EIB_TMPDIR}/${app_name}-content-venv"
python3 -m venv ${venv_dir}
source ${venv_dir}/bin/activate

pip install kolibri==${EIB_KOLIBRI_APP_VERSION}
pip install kolibri-app-desktop-xdg-plugin==${EIB_KOLIBRI_APP_DESKTOP_XDG_PLUGIN_VERSION}
pip install kolibri-desktop-auth-plugin==${EIB_KOLIBRI_DESKTOP_AUTH_PLUGIN_VERSION}

export KOLIBRI_HOME="${KOLIBRI_CONTENT_DIR}"

kolibri plugin enable kolibri.plugins.app
kolibri plugin enable kolibri_app_desktop_xdg_plugin
kolibri plugin enable kolibri_desktop_auth_plugin

if [ ${app_name} == "kolibri" ]; then
INSTALL_CHANNELS=("${KOLIBRI_INSTALL_CHANNELS[@]}")
elif [ ${app_name} == "endless-key" ]; then
INSTALL_CHANNELS=("${KEY_INSTALL_CHANNELS[@]}")
else
exit 1
fi

for channel_id in ${INSTALL_CHANNELS}; do
import_kolibri_channel "${app_name}" "${channel_id}"
done

# Sort channels in the same order as in INSTALL_CHANNELS
position=1
for channel_id in ${INSTALL_CHANNELS}; do
kolibri manage setchannelposition ${channel_id} ${position} || true
let position=position+1
done

# Empty the user database, and ensure that each instance of this image has a
# unique Facility ID.
# <https://kolibri.readthedocs.io/en/latest/install/provision.html#prepare-the-kolibri-folder-for-copying>
(echo yes; echo yes) | kolibri manage deprovision
}

if [ -n "${EIB_KOLIBRI_INSTALL_CHANNELS}" ]; then
prepare_kolibri_env "kolibri"
fi

if [ -n "${EIB_KEY_INSTALL_CHANNELS}" ]; then
prepare_kolibri_env "endless-key"
fi
30 changes: 25 additions & 5 deletions hooks/image/61-kolibri-content-install
Original file line number Diff line number Diff line change
@@ -1,12 +1,32 @@
# Install the Kolibri home directory to the right location in the image

if [ -z "${EIB_KOLIBRI_INSTALL_CHANNELS}" ]; then
if [ -z "${EIB_KOLIBRI_INSTALL_CHANNELS}" &&
-z "${EIB_KEY_INSTALL_CHANNELS}" ]; then
exit 0
fi

# Needs to be kept in sync with hooks/image/60-kolibri-content
KOLIBRI_CONTENT_DIR="${EIB_CONTENTDIR}/kolibri-content"
install_content()
{
local app_name=$1
mkdir -p "${OSTREE_VAR}"/lib/kolibri

mkdir -p "${OSTREE_VAR}"/lib/kolibri
if [ ${app_name} == "kolibri" ]; then
TARGET="${OSTREE_VAR}"/lib/kolibri/data
elif [ ${app_name} == "endless-key" ]; then
TARGET="${OSTREE_VAR}"/lib/kolibri/endless-key-data
else
exit 1
fi

cp -rl "${KOLIBRI_CONTENT_DIR}" "${OSTREE_VAR}"/lib/kolibri/data
# Needs to be kept in sync with hooks/image/60-kolibri-content
KOLIBRI_CONTENT_DIR="${EIB_CONTENTDIR}/${app_name}-content"
cp -rl "${KOLIBRI_CONTENT_DIR}" "${TARGET}"
}

if [ -n "${EIB_KOLIBRI_INSTALL_CHANNELS}" ]; then
install_content "kolibri"
fi

if [ -n "${EIB_KEY_INSTALL_CHANNELS}" ]; then
install_content "endless-key"
fi
17 changes: 13 additions & 4 deletions hooks/image/62-kolibri-automatic-provision
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
# Configure Kolibri automatic provisioning if enabled

if [ "${EIB_KOLIBRI_AUTOMATIC_PROVISION}" != "true" ]; then
if [ "${EIB_KOLIBRI_AUTOMATIC_PROVISION}" != "true" &&
"${EIB_KEY_AUTOMATIC_PROVISION}" != "true" ]; then
exit 0
fi

mkdir -p "${OSTREE_VAR}"/lib/kolibri/data

cat <<EOF > "${OSTREE_VAR}"/lib/kolibri/data/automatic_provision.json
cat <<EOF > "${EIB_TMPDIR}"/automatic_provision.json
{
"facility_name": "${EIB_KOLIBRI_AUTOMATIC_PROVISION_FACILITY_NAME}",
"superuser": {
Expand All @@ -27,3 +26,13 @@ cat <<EOF > "${OSTREE_VAR}"/lib/kolibri/data/automatic_provision.json
}
}
EOF

if [ "${EIB_KOLIBRI_AUTOMATIC_PROVISION}" == "true" ]; then
mkdir -p "${OSTREE_VAR}"/lib/kolibri/data
cp "${EIB_TMPDIR}"/automatic_provision.json "${OSTREE_VAR}"/lib/kolibri/data
fi

if [ "${EIB_KEY_AUTOMATIC_PROVISION}" == "true" ]; then
mkdir -p "${OSTREE_VAR}"/lib/kolibri/endless-key-data
cp "${EIB_TMPDIR}"/automatic_provision.json "${OSTREE_VAR}"/lib/kolibri/endless-key-data
fi
21 changes: 16 additions & 5 deletions hooks/image/62-kolibri-options
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@
import configparser
import functools
import os
import shutil
from pathlib import Path

OSTREE_VAR = Path(os.environ.get("OSTREE_VAR"))
KOLIBRI_HOME = Path(OSTREE_VAR, "lib/kolibri/data")
OPTIONS_FILE_PATH = Path(KOLIBRI_HOME, "options.ini")

EIB_KOLIBRI_REGULAR_USERS_CAN_MANAGE_CONTENT = os.environ.get(
"EIB_KOLIBRI_REGULAR_USERS_CAN_MANAGE_CONTENT"
)
Expand All @@ -32,6 +29,20 @@ config_count = functools.reduce(
lambda total, section: total + len(section), config.values(), 0
)

EIB_TMPDIR = Path(os.environ.get("EIB_TMPDIR"))
TMP_OPTIONS_FILE_PATH = Path(EIB_TMPDIR, "options.ini")
if config_count > 0:
with open(OPTIONS_FILE_PATH, "w") as options_file:
with open(TMP_OPTIONS_FILE_PATH, "w") as options_file:
config.write(options_file)

# TODO: Check if the key is not in os.environ or is mapped to an empty string
if "EIB_KOLIBRI_INSTALL_CHANNELS" in os.environ:
OSTREE_VAR = Path(os.environ.get("OSTREE_VAR"))
KOLIBRI_HOME = Path(OSTREE_VAR, "lib/kolibri/data")
shutil.copy(TMP_OPTIONS_FILE_PATH, KOLIBRI_HOME)

# TODO: Check if the key is not in os.environ or is mapped to an empty string
if "EIB_KEY_INSTALL_CHANNELS" in os.environ:
OSTREE_VAR = Path(os.environ.get("OSTREE_VAR"))
KOLIBRI_HOME = Path(OSTREE_VAR, "lib/kolibri/endless-key-data")
shutil.copy(TMP_OPTIONS_FILE_PATH, KOLIBRI_HOME)
Loading