Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ohemilyy/universe/llms.txt

Use this file to discover all available pages before exploring further.

TemplateStorageProvider is the abstraction for remote template storage backends. The built-in local storage reads templates from the ./templates/ directory on disk. Extensions implement this interface to add backends such as AWS S3, allowing templates to be shared across nodes without manual file transfers. Both interfaces live in extensions/api (gg.scala.universe.template) and are available to all extensions.

TemplateStorageProvider interface

interface TemplateStorageProvider {
    val storageKey: String

    fun downloadTemplate(group: String, name: String): Boolean
    fun uploadTemplate(group: String, name: String): Boolean
    fun listTemplates(group: String): List<String>
}

Properties

storageKey
string
required
Unique identifier for this storage backend. This string is what you put in the "storage" field of a Template reference in a configuration. For example, a provider with storageKey = "s3" is referenced as "storage": "s3".

Methods

downloadTemplate(group, name) Downloads the template zip for <group>/<name> from remote storage and extracts it into the local ./templates/<group>/<name>/ directory. Returns true on success, false on failure. uploadTemplate(group, name) Zips and uploads the local ./templates/<group>/<name>/ directory to remote storage. Returns true on success, false on failure. listTemplates(group) Returns the names of all templates available in the remote storage under group. The local ./templates/<group>/ directory is not consulted.

TemplateStorageRegistry interface

interface TemplateStorageRegistry {
    fun register(provider: TemplateStorageProvider)
    fun get(key: String): TemplateStorageProvider?
    fun unregister(key: String)
    fun getAll(): Map<String, TemplateStorageProvider>
}
Unlike RuntimeRegistry, register takes the provider directly — the key is read from provider.storageKey automatically.
MethodDescription
register(provider)Registers provider under its own storageKey.
get(key)Returns the provider registered under key, or null.
unregister(key)Removes the provider registered under key.
getAll()Returns a snapshot of all registered key → provider mappings.

How the storage key is used

In a Configuration, each Template entry has a storage field:
{
  "templateInstallationConfig": {
    "allOf": [
      { "name": "base", "group": "server", "storage": "s3", "priority": 0 }
    ]
  }
}
When the instance is deployed, the Template Manager calls TemplateStorageRegistry.get("s3") to resolve the provider, then calls downloadTemplate("server", "base") before copying the template files into ./running/<instanceId>/. The built-in storage key is "local", which reads directly from the local filesystem without downloading anything.

Implementing a custom storage backend

class MyStorageProvider : TemplateStorageProvider {
    override val storageKey = "my-backend"

    override fun downloadTemplate(group: String, name: String): Boolean {
        // fetch from remote, extract to ./templates/<group>/<name>/
        return true
    }

    override fun uploadTemplate(group: String, name: String): Boolean {
        // zip ./templates/<group>/<name>/, upload to remote
        return true
    }

    override fun listTemplates(group: String): List<String> {
        // return template names available in the group remotely
        return emptyList()
    }
}

class MyExtension : Extension {
    @Inject lateinit var storageRegistry: TemplateStorageRegistry

    override fun onLoad() {
        storageRegistry.register(MyStorageProvider())
    }
}

Build docs developers (and LLMs) love