Developers Guide


Freedombone consists of a set of bash scripts. There are a lot of them, but they're not very complicated. If you're familiar with the GNU/Linux commandline and can hack a bash script then you can probably add a new app or fix a bug in the system. There are no trendy development frameworks to learn or to get in your way.

Community Statement

This project doesn't require you to take any special pledge of allegiance or subscribe to any guru's list of commandments. It does not care about your gender, race, national flag or political alignment. It is agnostic towards your religion or lack thereof. It doesn't give one hoot as to whether you are young or old, rich or poor, gay, trans, straight or just "other". It does not care if you like your eggs sunny side up or if you are a vegan.

This is an inclusive project which will take patches or pull requests from anyone, in a generous manner along the lines described by the late Pieter Hintjens in his book Social Architecture. Any useful patch is likely to be merged so long as it is submitted under a license compatible with AGPL3. Copyright assignment is not required.

Freedombone is a free system. That's free as in no secret source. For anything. Although there's nothing to stop you from adding proprietary utilities or apps if you wish, any patches containing closed stuff or which create dependencies upon closed systems will be regarded as trash and ignored.

This project also has a no bullshit policy. Anyone trying to cause a ruckus by trolling or engaging in behavior which is disruptive or disrespectful to others will be speedily blocked and ignored. Life's too short, and there's too much to be done.

Adding extra apps

Suppose you have some internet application which you want to add to the system. To do this you need to create an app script which tells the system how to install/remove and also backup/restore. The script should be designed to work with the current stable version of Debian.

On an installed system the app scripts go into the directory:


and within the project repo they appear within the src directory. Your new app script should have the name:


The myappname value should not contain any spaces and will appear in the list of available apps.

An example template for an app script is shown below. Copy this and add whatever variables and configuration you need. Search and replace myappname with your own.

# Copyright (C) Year YourName <YourEmail>
# 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
# GNU Affero General Public License for more details.

# 'full' includes your app in the full installation and you
# can also add other variants, separated by spaces. The
# available variants will be detected automatically from the
# app scripts. In most cases don't change this.

# If you want this to appear on the control panel About screen

# If you want this app to be in the default installation,
# otherwise it will be available but not selected by default


# A directory where the data for this app exists

# List of configuration variables used by the app

function change_password_myappname {
    # Do something to change the password

function reconfigure_myappname {
    echo -n ''
    # Do something to delete existing keys/identity and
    # generate new ones

function upgrade_myappname {
    echo -n ''
    # Do something to upgrade this app.
    # If it's a debian package then it will be maintained by the
    # operating system and you don't need anything here

function backup_local_myappname {
    # If your app has a MariaDB/MySQL database
    backup_database_to_usb myappname

    # To backup a directory
    backup_directory_to_usb $MYAPP_DATA_DIR myappname

    # if you need to backup data within individual user
    # home directories
    for d in /home/*/ ; do
        USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
        if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
            echo $"Backing up myappname config for $USERNAME"
            if [ -d /home/$USERNAME/.config/myappname ]; then
                backup_directory_to_usb \
                    /home/$USERNAME/.config/myappname \

function restore_local_myappname {

    # If your app has a MariaDB/MySQL database
    restore_database myappname

    # Restore some data from a directory
    # Note that we don't restore directly but to a temporary
    # directory and then copy the files. This ensures that if
    # there is a restore failure you don't end up with
    # half-copied or corrupted files
    restore_directory_from_usb $MYAPP_DATA_DIR myappname
    cp -r $temp_restore_dir/$MYAPP_DATA_DIR $MYAPP_DATA_DIR
    rm -rf $temp_restore_dir

    # If you need to restore a configuration directory for each user
    if [ -d $USB_MOUNT/backup/myappname_users ]; then
        for d in $USB_MOUNT/backup/myappname_users/*/ ; do
            USERNAME=$(echo "$d" | awk -F '/' '{print $6}')
            if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
                if [ ! -d /home/$USERNAME ]; then
                    ${PROJECT_NAME}-adduser $USERNAME
                echo $"Restoring Vim config for $USERNAME"
                function_check restore_directory_from_usb
                restore_directory_from_usb $temp_restore_dir \
                cp -r $temp_restore_dir/home/$USERNAME/.config \
                if [ ! "$?" = "0" ]; then
                    rm -rf $temp_restore_dir
                    exit 664
                rm -rf $temp_restore_dir

function backup_remote_myappname {
    # this should be the same as backup_local_myappname,
    # but call the backup functions backup_directory_to_friend
    # and backup_database_to_friend

function restore_remote_vim {
    # this should be the same as restore_local_myappname,
    # but call the restore function restore_directory_from_friend
    # and restore_database_from_friend

function remove_myappname {
    # if it's a debian package then:
    apt-get -y remove --purge [my-app-package-name]

    # If your app has a MariaDB/MySQL database
    drop_database myappname

    # If your app uses an onion address
    remove_onion_service myappname ${MYAPPNAME_ONION_PORT}

function install_myappname {
    # if it's a debian package then:
    apt-get -y install [my-app-package-name]

    # If you need to create a MariaDB/MySQL database for the app
    MYAPPNAME_DB_PASSWORD="$(create_password 20)"
    create_database myappname "$MYAPPNAME_DB_PASSWORD" $MY_USERNAME

    # If you need to create an onion address for the app
    MYAPPNAME_ONION_HOSTNAME=$(add_onion_service myappname \
                               80 ${MYAPPNAME_ONION_PORT})

    # Do any other configuration
    # Here you might use $ONION_ONLY or

    # Mark the app as having installed successfully
    # If this variable isn't set then it will be assumed that
    # the install has failed

function install_interactive_myappname {
    # Interactively obtain some values using dialog, such as
    # domain names. An avatar changing example is:
    data=$(tempfile 2>/dev/null)
    trap "rm -f $data" 0 1 2 5 15
    dialog --title $"Change your avatar" \
           --backtitle $"Freedombone Control Panel" \
           --inputbox $"Enter a URL for an image. It should be " \
                      $"approximately a square image." 8 75 2>$data
    case $sel in
            if [ ${#MY_FUNKY_AVATAR} -gt 3 ]; then

                # do whatever is needed to change the avatar
                # in your app

                dialog --title $"Change your avatar" \
                       --msgbox $"Your avatar has been changed" 6 40

    # install_myappname will be called automatically after this function

# NOTE: deliberately no exit 0

To test your app log into your system, select Exit to command line then gain root powers with:

sudo su

Copy your app script to /usr/share/freedombone/apps/freedombone-app-myappname.

And run the admin control panel:


Select Add/Remove Apps and if all is well then you should see your app listed as installable. Test that installing and removing it works as expected.

Submit your working app to https://github.com/bashrc/freedombone/issues

Customising mesh images

If you want to make your own specially branded version of the mesh images, such as for a particular event, then to change the default desktop backgrounds edit the images within img/backgrounds and to change the available avatars and desktop icons edit the images within img/avatars. Re-create disk images using the instructions shown previously.

If you need particular dconf commands to alter desktop appearance or behavior then see the function mesh_client_startup_applications within src/freedombone-image-customise.

Back to top | E-mail me