Skip to content

An Ansible playbook to easily populate a SD card for the Analogue Pocket with selected/custom content.

License

Notifications You must be signed in to change notification settings

4ch1m/ansible-analogue-pocket

Repository files navigation

┌─────────────────────────────────────────────────────────────────────────────┐
│ ANSIBLE                                                                     │
│     _                _                        ____            _        _    │
│    / \   _ __   __ _| | ___   __ _ _   _  ___|  _ \ ___   ___| | _____| |_  │
│   / _ \ | ._ \ / _` | |/ _ \ / _` | | | |/ _ \ |_) / _ \ / __| |/ / _ \ __| │
│  / ___ \| | | | (_| | | (_) | (_| | |_| |  __/  __/ (_) | (__|   <  __/ |_  │
│ /_/   \_\_| |_|\__,_|_|\___/ \__, |\__,_|\___|_|   \___/ \___|_|\_\___|\__| │
│                              |___/                                          │
└─────────────────────────────────────────────────────────────────────────────┘
    \   ^__^
     \  (oo)\_______
        (__)\       )\/\
            ||----w |
            ||     ||

An Ansible playbook to easily populate a SD card for the Analogue Pocket with selected/custom content.

📑 Table of Contents

✋ Disclaimer

This project is (obviously) inspired by Matt Pannella's excellent Analogue Pocket Updater Utility.

It does not claim to be simpler, faster, or better in any way.

So, why even bother?
And why Ansible???

  • For a task like this I personally prefer a more "scripted" approach; meaning no (pre-)built/native binaries.
  • More transparency about what is actually going on is also nice. (Ansible is very verbose/talkative per se.)
  • I'm aware that the original purpose of Ansible is software provisioning, configuration management, and application deployment (of remote machines). However, Ansible is also perfect for simple "file handling" and IT automation in general; so we can use it locally on a workstation as well.
  • Ansible playbooks are easy to read/understand and have a relatively simple execution flow.
  • The Ansible script code might be easier to fiddle with for someone who has no programming background.
  • I just ❤️ Ansible... and enjoy using it. 😄

📂 Concept / Structure

Instead of directly working on a SD card and downloading/modifying content in place, I prefer to start with a "clean slate" every time I run the script/playbook; making sure there are no "leftovers" from previous downloads/installations.

So the playbook (which includes several modularized "roles") will clean the actual target directory (located on my PC's HDD/SDD) with every run and freshly compile all content from several sources.

┌─────────────────────────────────────────┐
│       analogue-pocket-playbook          │
├─────────────────────────────────────────┤
│ Roles:                                  │
│   - latest_firmware                     │
│   - openfpga_cores                      │
│   - retrodriven_assets                  │
│   - megazxretro_platform_art            │
│   - spiritualized1997_library_image_set │
│   - ...                                 │
└────────────────────┬────────────────────┘
                     │
                  download
                     │
        .────────────▼──────────────.
        │ content/.cached_downloads │
        `────────────┬──────────────`
                     │
                    copy
                     │
        .─ ─ ─ ─ ─ ─ ▼ ─ ─ ─ ─ ─ ─ ─.   .────────────────.
        │ content/.staged_downloads │   │ content/custom │
        `─ ─ ─ ─ ─ ─ ┬ ─ ─ ─ ─ ─ ─ ─`   `────────┬───────`
                     │                           │
                     └─────────────┬─────────────┘
                                   │
                               merge/copy
                                   │
                           .─ ─ ─ ─▼─ ─ ─ ─ .
                           │ content/sdcard │
                           `─ ─ ─ ─ ─ ─ ─ ─ `

These are the general execution steps:

  1. The playbook will ask (interactively) which roles should be included/executed.
  2. The folders .staged_downloads and sdcard will be DELETED.
  3. The up-to-date content downloaded by roles will be put into the .cached_downloads folder first, before being copied to the .staged_downloads folder; upon re-runs, existing cached content will be used instead of pulling it again from the net.
  4. The custom folder (which will always remain UNTOUCHED by the script) will - together with the .staged_downloads folder - get merged into the sdcard folder.
  5. (MANUAL TASK: use any synchronization method of your choice to synchronize the sdcard folder with your actual SD card.)

NOTE

The custom folder is the place where you will have to put your own games, roms, firmwares, etc.

The directory structure must match the Pocket's original SD card structure!

.
├── .cached_downloads
├── .staged_downloads
├── custom
│   ├── Assets
│   │   ├── nes
│   │   │   └── common
│   │   │       ├── mario.nes
│   │   │       └── zelda.nes
│   │   ├── genesis
│   │   │   └── common
│   │   │       └── sonic.bin
│   .   .
├── sdcard
.

🎁 Features

All main features are implemented in dedicated roles:

Role Description
latest_firmware download firmware files from the official Analogue support site
openfpga_cores download cores from the official openFPGA Cores inventory
retrodriven_assets download curated assets from RetroDriven's repository
megazxretro_platform_art download custom platform artwork images from MegaZXretro
spiritualized1997_library_image_set download custom library image set from spiritualized1997

🧰 Requirements

You should have Python 3 installed.

This project probably runs best on *nix based systems. (Windows not tested.)

📦 Installation

Simply clone this repo:

git clone https://github.com/4ch1m/ansible-analogue-pocket.git

🚀 Usage

Execute analogue-pocket-playbook.sh:

./analogue-pocket-playbook.sh

This will automatically create a virtual environment (venv) via Python and install Ansible via pip.
After that the actual playbook will be executed.

Once the playbook finished successfully you should find the final compiled content in this directory:

./content/sdcard

I usually use rsync to synchronize this folder with my actual mounted SD card, as a final/manual step:

rsync \
  --verbose \
  --recursive \
  --times \
  --whole-file \
  --delete \
  --delete-before \
  --progress \
  --stats \
  --temp-dir=$(mktemp --directory --suffix "_aap") \
  --exclude '/GB*Studio' \
  --exclude '/Memories' \
  --exclude '/Saves' \
  --exclude '/Settings' \
  --exclude '/System/*_cache.bin' \
  --exclude '/Analogue_Pocket.json' \
  ./content/sdcard/ \
  <path-to-your-actual-sdcard>

(Note: Some directories and cache-files should be ignored. The /Analogue_Pocket.json file is also excluded from the sync.)

🪛 Configuration

The playbook/roles have certain settings which can be customized.
This can be done by creating a file called custom.yml in the vars directory.
(This file is excluded from version control; see .gitignore)

# add 'identifier' of cores you want to exclude
# (check: https://openfpga-cores-inventory.github.io/analogue-pocket/api/v2/cores.json)
custom_openfpga_core_excludes:
  - core-identifier-1
  - core-identifier-2

# additional excludes when synchronizing from '.staged_downloads' to 'sdcard' directory
custom_rsync_excludes:
  - '--exclude=LICENSE'

# use US platform artwork, instead of PAL-EU
custom_megazxretro_platform_art_region_filename: USA.ZIP

# remove 'JTBETA' cores (default = 'false')
remove_jt_beta_cores: true

# automatically rename 'jt' cores (using metadata from 'pocket-platform-images' by dyreschlock); e.g. 'jtbubl' -> 'Bubble Bobble' (default = 'false')
rename_jt_cores: true

# custom core naming (which will be applied as a final step)
custom_core_names:
  jtaliens: Aliens
  jtkiwi: The NewZealand Story
  jtsimson: The Simpsons
  jttmnt: Teenage Mutant Ninja Turtles

⭐ Credits

Thanks to ...

⚖️ License

see LICENSE file

About

An Ansible playbook to easily populate a SD card for the Analogue Pocket with selected/custom content.

Topics

Resources

License

Stars

Watchers

Forks