Dev docs refactor

This commit is contained in:
kn0wmad
2022-11-03 18:01:31 -06:00
parent b4defd9c40
commit 63a7142eff
22 changed files with 414 additions and 1248 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

View File

@@ -1,34 +0,0 @@
.. _packaging-framework:
=============
1 - Framework
=============
.. contents::
:depth: 2
:local:
What we'll build
----------------
We'll create a web application that produces a hello world page. This web application will be the service we package for the Embassy. During this guide we will:
1. Create a simple hello world web service
2. Create a Dockerfile
3. Create a Package Manifest
4. Create a hosted repository which will contain all the service components
5. Create the packaged service file
You can find the `complete code <https://github.com/Start9Labs/hello-world-wrapper>`_ referenced in this guide on GitHub.
Download required tools
-----------------------
If necessary, download any of the system requirements:
- Docker
- EmbassySDK
- A code editor
- Terminal
For more details and installation steps for these tools, visit the :ref:`environment setup <environment-setup>` page.

View File

@@ -1,80 +0,0 @@
.. _packaging-create-service:
==================
2 - Create Service
==================
For this example, we are going to create a simple Rust project that serves a static web page.
.. code:: bash
mkdir hello-world && cd hello-world
cargo init
touch src/index.html
In ``index.html`` add:
.. code:: html
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
In ``main.rs`` add:
.. code:: rust
use hyper::service::{make_service_fn, service_fn};
use hyper::{body::Bytes, Body, Request, Response, Server};
use std::convert::Infallible;
use std::net::SocketAddr;
async fn handle(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
Ok(Response::new(Body::from(Bytes::from_static(
include_bytes!("index.html"),
))))
}
#[tokio::main]
async fn main() {
// Construct our SocketAddr to listen on...
let addr = SocketAddr::from(([0, 0, 0, 0], 80));
// And a MakeService to handle each connection...
let make_service = make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(handle)) });
// Then bind and serve...
let server = Server::bind(&addr).serve(make_service);
// And run forever...
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
}
Finally, in our ``Cargo.toml``, we need to add some dependencies, which will look like this:
.. code:: toml
[dependencies]
hyper = { version = "0.14.4", features = ["server", "http1", "http2", "tcp", "stream"] }
tokio = { version = "1.4.0", features = ["full"] }
**That's it!** We now have the code for our service.
Let's build and run it!
.. code:: bash
# build the project
cargo build
# start the executable
target/debug/hello-world
Visit `<http://localhost:80>`_ to see your running web page!

View File

@@ -1,39 +0,0 @@
.. _packaging-compile-raspi:
==================
3 - Hardware Build
==================
embassyOS is run on the arm-v8 architecture, specifically the aarch64 state, for the RaspberryPi.
Depending on the programming language or libraries used in a project, you might need to set up an environment to *cross compile* the executable for this runtime environment.
We were able to easily build and run our project locally. However, Rust is one of those programming languages that needs to be cross compiled. This step can be skipped if it does not apply to your project.
Since Start9 uses Rust throughout its service ecosystem, the team has built a helper to cross compile Rust projects for the Embassy.
This Rust cross compiler for aarch64 can be downloaded and build from `GitHub <https://github.com/Start9Labs/rust-musl-cross>`_:
.. code:: bash
git clone https://github.com/Start9Labs/rust-musl-cross.git
cd rust-musl-cross
chmod a+x ./build.sh
./build.sh
This actually builds a Docker container for us to use locally so we can emulate the environment we need to compile our project for aarch64!
Next, we enable cross-arch emulated builds in Docker
.. code:: bash
docker run --privileged --rm linuxkit/binfmt:v0.8
Finally, we run the following command to build the project, replacing `/absolute/path/to` with the output of `pwd` as necessary:
.. code:: bash
docker run --rm -it -v ~/.cargo/registry:/root/.cargo/registry -v "/absolute/path/to"/hello-world:/home/rust/src start9/rust-musl-cross:aarch64-musl cargo build --release
Awesome! We can now see the compiled executable here: `./hello-world/target/aarch64-unknown-linux-musl/release/hello-world`

View File

@@ -1,77 +0,0 @@
.. _packaging-docker-build:
================
4 - Docker Build
================
Now that we have our code properly built/compiled, we can create a Dockerfile. This file defines how to build the Docker image for the service by declaring the environment, building stages, and copying any binaries or assets needed to run the service to the Docker image filesystem.
In other words, the Dockerfile serves as a recipe for creating a Docker image, from which Docker containers are spun up. This is ultimately what runs an instance of your service on the Embassy.
1. Create the necessary Docker files:
.. code:: bash
touch Dockerfile
touch docker_entrypoint.sh
2. We'll start editing the ``Dockerfile`` by importing a base image, in this case Alpine, as recommended.
.. code:: docker
FROM arm64v8/alpine:3.12
3. Next, we issue some commands to setup the filesystem. Here we update repositories and install required system packages.
.. code:: docker
RUN apk update
RUN apk add tini curl
4. Next, we add the cross-compiled binary of ``hello-world`` to ``/usr/local/bin/`` and add the ``docker_entrypoint.sh`` file from the project root. Then, we set permissions for ``docker_entrypoint.sh``.
.. code:: docker
ADD ./hello-world/target/aarch64-unknown-linux-musl/release/hello-world /usr/local/bin/hello-world
ADD ./docker_entrypoint.sh /usr/local/bin/docker_entrypoint.sh
RUN chmod a+x /usr/local/bin/docker_entrypoint.sh
5. Next, we set a working directory, and set the location of the entrypoint. Exposing ports is not necessary for eOS, but its often useful to leave this line for quick reference and clarity.
.. code:: docker
WORKDIR /root
EXPOSE 80
ENTRYPOINT ["/usr/local/bin/docker_entrypoint.sh"]
6. **That's it!** Let's take a look at our final ``Dockerfile``:
.. code:: docker
FROM arm64v8/alpine:3.12
RUN apk update
RUN apk add tini
ADD ./hello-world/target/aarch64-unknown-linux-musl/release/hello-world /usr/local/bin/hello-world
ADD ./docker_entrypoint.sh /usr/local/bin/docker_entrypoint.sh
RUN chmod a+x /usr/local/bin/docker_entrypoint.sh
WORKDIR /root
# not necessary for embassyOS, but often left for quick reference and clarity
EXPOSE 80
ENTRYPOINT ["/usr/local/bin/docker_entrypoint.sh"]
7. Finally, add the following code to the ``docker_entrypoint.sh``:
.. code:: bash
#!/bin/sh
exec tini hello-world
This is a script that defines how the service starts, and often acts as an init system. It will need to complete any environment setup (such as folder substructure), set any environment variables, and execute the run command. It's also PID 1 in the Docker container, so should do all of the signal handling for container exits.

View File

@@ -1,257 +0,0 @@
.. _packaging-create-manifest:
===================
5 - Create Manifest
===================
The Manifest file specifies the details embassyOS needs to operate a service. It is the connection point between your service and embassyOS.
In this file, values and actions exist for:
- Displaying the service in the marketplace
- Specifying the project assets (eg. icon, instructions, license)
- Defining the docker mount points
- Specifying how to configure the service
- Relaying how to run health checks, backups, and other custom actions
- Outlining dependency relationships (if applicable) and configuration rules for dependencies
- Denoting copy to display in EmbassyUI elements, alerts, descriptions
This file can be written in:
- yaml
- toml
- json
Let's create a yaml manifest file for our hello-world project:
.. code:: bash
touch manifest.yaml
And populate it with the following example manifest (see the line comments for a description of each key and view the full :ref:`type specification here <service_manifest>`):
.. code:: yaml
# The package identifier used by the OS
id: hello-world
# A human readable service title
title: "Hello World"
# Service version - accepts up to four digits, where the last confirms to revisions necessary for embassyOS - see documentation: https://github.com/Start9Labs/emver-rs
version: 0.3.0
# Release notes for the update - can be a string, paragraph or URL
release-notes: "Upgrade to embassyOS v0.3.0"
# The type of license for the project. Include the LICENSE in the root of the project directory. A license is required for a Start9 package.
license: mit
# The Start9 wrapper repository URL for the package. This repo contains the manifest file (this), any scripts necessary for configuration, backups, actions, or health checks (more below). This key must exist. But could be embedded into the source repository.
wrapper-repo: "https://github.com/Start9Labs/hello-world-wrapper"
# The original project repository URL. There is no upstream repo in this example
upstream-repo: "https://github.com/Start9Labs/hello-world-wrapper"
# URL to the support site / channel for the project. This key can be omitted if none exists, or it can link to the original project repository issues.
support-site: "https://docs.start9.com/"
# URL to the marketing site for the project. This key can be omitted if none exists, or it can link to the original project repository.
marketing-site: "https://start9.com/"
# The series of commands to build the project into an s9pk for arm64/v8. In this case we are using a Makefile with the simple build command "make".
build: ["make"]
# Minimum required version of embassyOS
min-os-version: "0.3.0"
# Human readable descriptors for the service. These are used throughout the embassyOS user interface, primarily in the marketplace.
description:
# This is the first description visible to the user in the marketplace.
short: Example service
# This description will display with additional details in the service's individual marketplace page
long: |
Hello World is a simple example of a service wrapper that launches a web interface to say hello and nothing more.
# These assets are static files necessary for packaging the service for Start9 (into an s9pk). Each value is a path to the specified asset. If an asset is missing from this list, or otherwise denoted, it will be defaulted to the values denoted below.
assets:
# Default = LICENSE.md
license: LICENSE
# Default = icon.png
icon: icon.png
# Default = INSTRUCTIONS.md
instructions: instructions.md
# Default = image.tar
docker-images: image.tar
# The main action for initializing the service. Currently, the only type of action available is docker.
main:
# Docker is currently the only action implementation
type: docker
# Identifier for the main image volume, which will be used when other actions need to mount to this volume.
image: main
# The executable binary for starting the initialization action. For docker actions, this is typically a "docker_entrypoint.sh" file. See the Dockerfile and the docker_entrypoint.sh in this project for additional details.
entrypoint: "docker_entrypoint.sh"
# Any arguments that should be passed into the entrypoint executable
args: []
# Specifies where to mount the data volume(s), if there are any. Mounts for pointer dependency volumes are also denoted here. These are necessary if data needs to be read from / written to these volumes.
mounts:
# Specifies where on the service's file system its persistence directory should be mounted prior to service startup
main: /root
# Health checks
health-checks:
main:
name: Web Interface
description: Ensures the network interface is accessible via HTTP.
type: docker
image: main
entrypoint: "sh"
args: ["-c", "curl --silent --show-error --fail http://loacalhost:80"]
# When `inject` is true, the health check will use the main image to run the health check. This is faster as there is no need to spin up an additional docker container
# When `inject` is false, the health check will use whatever image is specified. This is useful when using a system image with additional utilities to run a health check. If inject=false, then system must equal true
inject: true
# Optional if false - indicates if an image that is preloaded onto the system will be used
system: false
# Required - valid values are yaml, toml, json
io-format: json
# Specifies how to get and set configuration file values for the service. NOTE: This stanza can be left empty (null) if the service has no configuration options.
config:
# The config action to run to get the specified config file (default is config.yaml)
get:
# The type of implementation to run this action (currently, only Docker is available)
type: docker
# The Docker image to run the action command in. This could be the service's main image, or an image that is preloaded onto the system, like compat (which holds compatible helper functions for default functionality)
image: compat
# Indicates if an image that is preloaded onto the system will be used
system: true
# The initial run command to execute the config get action
entrypoint: compat
# Any arguments that need to be passed into the run command
args:
- config
- get
- /root
- "/mnt/assets/config_spec.yaml"
# The locations at which to mount the specified Docker images
mounts:
compat: /mnt/assets
main: /root
# Required - valid values are yaml, toml, json
io-format: yaml
# The config action to run to set the specified config file (default is config.yaml). Details for the keys below are the same as above.
set:
type: docker
image: compat
system: true
entrypoint: compat
args:
- config
- set
- hello-world
- /root
- "/mnt/assets/config_rules.yaml"
mounts:
compat: /mnt/assets
main: /root
io-format: yaml
# This is a key value map specifying dependent services that this service needs in order to function. The keys are the package id's on which you depend. NOTE: if developing a standalone service, you may leave this stanza as an empty object (the key dependencies is required)
dependencies:
# Key must be the package id of another service that exists in the marketplace
filebrowser:
# The version range that is acceptable for this dependency
version: "^2.14.1.1"
# Describes if the dependency is critical to the service functioning. If the dependency is critical, the service will stop if this dependency is stopped.
critical: false
# Specifies the requirement type of the dependency
requirement:
# "Opt-out" means the dependency will be required according to the default config. "Opt-in" means the dependency may be required if you change the config. And "required" just means it's always required.
type: "opt-out"
# An explanation of how to opt-in or opt-out. This value is optional for type=required
how: Optionally use the selected dependency
# Description of the dependency relationship
description: A dependency that demonstrates the way to configure a dependent service
# This is a list of rules that levies requirements on the configuration of the dependency and suggests ways to remedy any incompatibilities. Documentation of this feature is outside the scope of this example.
config: ~
# This denotes any data, asset, or pointer volumes that should be connected when the "docker run" command is invoked
volumes:
# This is the image where files from the project asset directory will go
main:
type: data
# This is an example of an asset volume
compat:
type: assets
# This specifies how to configure the port mapping for exposing the service over TOR and LAN (if applicable). Many interfaces can be specified depending on the needs of the service. If it can be launched over a Local Area Network connection, specify a `lan-config`. Otherwise, at minimum, a `tor-config` must be specified.
interfaces:
# This key is the internal name that the OS will use to configure the interface
main:
# A human readable name for display in the UI
name: Network Interface
# A descriptive description of what the interface does
description: Specifies the interface to listen on for HTTP connections.
tor-config:
# Port mappings are from the external port to the internal container port
port-mapping:
80: "80"
# Port mappings are from the external port to the internal container port
lan-config:
80:
ssl: false
internal: 80
# Denotes if the service has a user interface to display
ui: true
# Denotes the protocol specifications used by this interface
protocols:
- tcp
- http
# Alerts: omitting these will result in using the default alerts in embassyOS, except for start, which has no default.
alerts:
install-alert: This is an alert that will present before the user installs this service
uninstall-alert: This is an alert that will present before the user uninstalls this service
restore-alert: This is an alert that will present before the user restores this service from Embassy backup
start-alert: This is an alert that will present before the user starts this service
# Specifies how backups should be run for this service. The default embassyOS provided option is to use the duplicity backup library on a system image (compat)
backup:
create:
# Currently, only docker actions are supported.
type: docker
# The docker image to use. In this case, a pre-loaded system image called compat
image: compat
# Required if the action uses a system image. The default value is false.
system: true
# The executable to run the command to begin the backup create process
entrypoint: compat
# Arguments to pass into the entrypoint executable. In this example, the full command run will be: `compat duplicity hello-world /mnt/backup /root/data`
args:
- duplicity
- hello-world
- /mnt/backup
# For duplicity, the backup mount point needs to be something other than `/root`, so we default to `/root/data`
- /root/data
mounts:
# BACKUP is the default volume that is used for backups. This is whatever backup drive is mounted to the device, or a network filesystem.
# The value here donates where the mount point will be. The backup drive is mounted to this location.
BACKUP: "/mnt/backup"
main: "/root"
# The action to execute the backup restore functionality. Details for the keys below are the same as above.
restore:
type: docker
image: compat
system: true
entrypoint: compat
args:
- duplicity
- hello-world
- /root/data
- /mnt/backup
mounts:
BACKUP: "/mnt/backup"
main: "/root"
# Commands that can be issued from the UI. NOTE: if no actions are required, this section can be left as an empty object
actions:
hello-world-action:
name: Hello World Action
description: A description that describes what the action will accomplish.
warning: |
A warning message indicating and potential dangers associated with the action
# Indicates what state the service can be in while executing the action
allowed-statuses:
- running
# Defines how the action is run
implementation:
type: docker
image: main
entrypoint: sh
args: ["-c", "echo 'hello-world'"]
# Same as note on health-checks
inject: true
# Required - valid values are yaml, toml, json
io-format: json
**That's it!** You now have the structure for your service's Manifest.

View File

@@ -1,56 +0,0 @@
.. _packaging-create-assets:
=================
6 - Create Assets
=================
.. contents::
:depth: 2
:local:
Each ``s9pk`` package contains a set of assets. They include:
- Instructions
- License
- Icon
Instructions
------------
An instructions file is a convenient way to share any steps users should take to setup or interact with your service. This file gets displayed within an EmbassyUI component and should be written in `Markdown <https://www.markdownguide.org/>`_ language.
Let's add instructions to our hello world project:
.. code:: bash
touch instructions.md
And add the following code to the file:
.. code:: bash
# Instructions for Hello World
Instructions go here. These appear to the user in the UI on the Service page under 'Instructions.'
License
-------
Start9 ensures that the proper license is displayed for all open source software running on an embassyOS platform. Let's make sure to include the full open source license so users can view the distribution permissions of your service, among other licensing details.
The name and location of this file should be specified in the ``assets.license`` section of the Manifest. The default value if not specified is ``LICENSE``, located in the root of the project folder.
.. code:: bash
touch ./hello-world/LICENSE
Icon
----
Icons are displayed throughout the EmbassyUI to reference to your service.
Simply add the icon file to the root of the project directory. The icon file can be named anything, but this must be specified in the ``assets.icon`` section of the Manifest. The default filename the SDk looks for when packaging the service assets is ``icon.png``.
.. code:: bash
mv /local/path/to/icon ./hello-world/icon.png

View File

@@ -1,23 +0,0 @@
.. _packaging-create-s9pk:
==================
7 - Format Package
==================
We now have all of the necessary components to package the service into the format needed for the OS. This format is a custom filetype with an extension of ``.s9pk``, short for Start9 Package.
To package all components into an ``.s9pk``, run the following command from the root of your project directory:
.. code:: bash
embassy-sdk pack
Let's also make sure to verify the validity of the package:
.. code:: bash
embassy-sdk verify s9pk /path/to/hello-world.s9pk
If anything goes wrong, an error message will indicate the missing component or other failure.
**That's it!**

View File

@@ -1,92 +0,0 @@
.. _packaging-makefile:
===================
8 - Create Makefile
===================
For convenience and repeatability, let's combine all of these commands into a Makefile. Then, we can use `make <https://www.gnu.org/software/make/>`_ to rebuild our project quickly.
.. code:: bash
touch Makefile
1. Add the build rule with the target executable as the key, including a list of dependencies needed to build the target file. In this case, the ``hello-world`` binary compiled for aarch is the target, and the dependencies are the hello-world source files needed to compile this binary:
.. code:: bash
HELLO_WORLD_SRC := $(shell find ./hello-world/src) hello-world/Cargo.toml hello-world/Cargo.lock
hello-world/target/aarch64-unknown-linux-musl/release/hello-world: $(HELLO_WORLD_SRC)
docker run --rm -it -v ~/.cargo/registry:/root/.cargo/registry -v "$(shell pwd)"/hello-world:/home/rust/src start9/rust-musl-cross:aarch64-musl cargo build --release
2. Add the step to build the Docker image. Here, the target is the Docker `image.tar` artifact, and the dependencies are the Dockerfile, docker_entrypoint.sh, and the aarch64 compiled hello-world executable:
.. code:: bash
image.tar: Dockerfile docker_entrypoint.sh hello-world/target/aarch64-unknown-linux-musl/release/hello-world
DOCKER_CLI_EXPERIMENTAL=enabled docker buildx build --tag start9/hello-world/main:$(VERSION) --platform=linux/arm64 -o type=docker,dest=image.tar .
3. Next, add the step for building the ``s9pk`` package, with the ``hello-world.s9pk`` as the target, and all the component files as the dependencies:
.. code:: bash
ASSETS := $(shell yq e '.assets.[].src' manifest.yaml)
hello-world.s9pk: manifest.yaml assets/compat/config_spec.yaml assets/compat/config_rules.yaml image.tar instructions.md $(ASSET_PATHS)
embassy-sdk pack
4. Then, add the step to verify the package:
.. code:: bash
S9PK_PATH=$(shell find . -name hello-world.s9pk -print)
verify: hello-world.s9pk $(S9PK_PATH)
embassy-sdk verify s9pk $(S9PK_PATH)
5. Add steps to clean up the Makefile build artifacts when you want to build from a fresh slate:
.. code:: bash
clean:
rm -f image.tar
rm -f hello-world.s9pk
6. Finally, add the ``all`` make target.
.. code:: bash
all: verify
This serves as the entrypoint to build multiple targets, which we have in this case. When the ``make`` command is invoked here, it looks for the "verify" target. Since the "verify" target depends on the "hello-world.s9pk" target, make then runs this target. It continues down this graph until the first target and its dependencies are satisfied, then works its way back up. The final output of this Makefile is the ``image.tar`` and ``hello-world.s9pk`` files.
**That's it!** Our completed Makefile looks like this:
.. code:: make
ASSETS := $(shell yq e '.assets.[].src' manifest.yaml)
ASSET_PATHS := $(addprefix assets/,$(ASSETS))
VERSION := $(shell yq e ".version" manifest.yaml)
HELLO_WORLD_SRC := $(shell find ./hello-world/src) hello-world/Cargo.toml hello-world/Cargo.lock
S9PK_PATH=$(shell find . -name hello-world.s9pk -print)
# delete the target of a rule if it has changed and its recipe exits with a nonzero exit status
.DELETE_ON_ERROR:
all: verify
verify: hello-world.s9pk $(S9PK_PATH)
embassy-sdk verify s9pk $(S9PK_PATH)
clean:
rm -f image.tar
rm -f hello-world.s9pk
hello-world.s9pk: manifest.yaml assets/compat/config_spec.yaml assets/compat/config_rules.yaml image.tar instructions.md $(ASSET_PATHS)
embassy-sdk pack
image.tar: Dockerfile docker_entrypoint.sh hello-world/target/aarch64-unknown-linux-musl/release/hello-world
DOCKER_CLI_EXPERIMENTAL=enabled docker buildx build --tag start9/hello-world/main:$(VERSION) --platform=linux/arm64 -o type=docker,dest=image.tar .
hello-world/target/aarch64-unknown-linux-musl/release/hello-world: $(HELLO_WORLD_SRC)
docker run --rm -it -v ~/.cargo/registry:/root/.cargo/registry -v "$(shell pwd)"/hello-world:/home/rust/src start9/rust-musl-cross:aarch64-musl cargo build --release

View File

@@ -1,65 +0,0 @@
.. _packaging-create-wrapper:
==================
9 - Create Wrapper
==================
In order for the Start9 team to review your package for submission to the Start9 Marketplace, we ask that you create a wrapper repository for the project and its components. This repo should contain everything you need to build the service.
Let's do that for our hello-world service.
For a quick start convenience, Start9 has made the finalized version of the `hello-world-wrapper <https://github.com/Start9Labs/hello-world-wrapper>`_ available as a *GitHub template*. Clicking "Use this template" in that repository will clone the entire contents to a specified location. Each file will still have to be manually edited to reflect the changes necessary for your service.
If you want to proceed from scratch, follow these steps:
1. In GitHub, create a new public repository with the name "hello-world-wrapper" under your user profile. Go ahead and select the options to include a README file and a .gitignore file. You can always add these files later too.
2. Once the hosted repository is created, select the "Code" dropdown to copy the https or ssh URL for the repository. If you do not have git setup locally, follow the :ref:`setup steps <environment-setup-git>` first.
.. code:: bash
git clone https://github.com/<username>/hello-world-wrapper.git
cd hello-world-wrapper
3. Include the ``hello-world`` project in the wrapper repo. It can either be included directly, or it can be hosted separately. If it is hosted separately, it should be included as a `git submodule <https://git-scm.com/book/en/v2/Git-Tools-Submodules>`_ within the wrapper repository:
.. code:: bash
git submodule add <link_to_source_project>
4. Edit the ``.gitignore`` file to include the ``.s9pk`` file and ``image.tar`` bundle. This will exclude these files from being published remotely, as they can be large or binary representations.
.. code:: bash
hello-world.s9pk
image.tar
5. Move the ``Dockerfile``, ``docker_entrypoint.sh``, ``LICENSE``, ``icon``, and ``Manifest`` to the root of the wrapper repository. At the end, your project structure should look similar to this:
.. code:: bash
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── assets
│ └── compat
│ ├── config_rules.yaml
│ └── config_spec.yaml
├── docker_entrypoint.sh
├── hello-world
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── src
│ │ ├── index.html
│ │ └── main.rs
│ └── target
│ ├── aarch64-unknown-linux-musl
│ ├── debug
│ └── release
├── hello-world.s9pk
├── icon.png
├── image.tar
├── instructions.md
└── manifest.yaml

View File

@@ -1,65 +0,0 @@
.. _packaging-install:
============
10 - Install
============
Now that we have a process for iterating on producing a valid package for embassyOS, let's load it onto an Embassy!
1. First, generate an ssh key for the Embassy:
.. code:: bash
ssh-keygen -t ed25519
# Press Enter to leave filename as default
# Press Enter to leave password empty
# Press Enter to confirm password is empty
# Copy file contents to clipboard. This is your ssh pubkey.
pbcopy .ssh/id_ed25519.pub
2. On an Embassy device, enter the ssh pubkey into your SSH settings:
1. Click on Embassy in the menu
2. Click on SSH under SETTINGS
3. Click on + Add new key
4. Paste pubkey from clipboard
3. Copy the ``hello-world.s9pk`` to the Embassy device:
.. code:: bash
# Confirm you can ssh into your Embassy
ssh start9@<lan-url>
# Log out of Embassy SSH session
exit
scp <package-id>.s9pk ssh start9@<lan-url>:/working/directory/path
eg. scp hello-world.s9pk ssh start9@embassy-12345678.local:~
4. Finally, install the package on an Embassy device:
.. code:: bash
ssh start9@<lan-url>
# log in to the command line interface using the Embassy password
embassy-cli auth login
embassy-cli package install hello-world.s9pk
**Congratulations!** You have successfully created and installed a package you created onto embassyOS. The package should now be viewable in the "Services" tab in EmbassyUI.
From here, you can play with viewing the results of your Manifest file settings, such as config, actions, interfaces, health checks, etc. You can also view the logs of your service right in the UI!
In order to verify your service is functioning as expected:
- Ensure your service is in "Running" state
- Make sure there are no apparent errors or warnings in the logs
- Ensure each UI component renders as expected:
- Instructions
- Config
- Properties
- Actions
- Interfaces
- Marketplace listing
- Donation
- Launch or use your service in the intended way and make sure all aspects function

View File

@@ -1,122 +0,0 @@
.. _build-package-example:
===============
Build a Package
===============
This guide will take you through the fundamentals of packaging a service for embassyOS by creating a real service. Let's get started!
.. raw:: html
<div class="topics-grid grid-container full">
<div class="grid-x grid-margin-x">
.. topic-box::
:title: Step 1
:link: 01_setup
:class: large-4
:anchor: View
Context and environment setup
.. topic-box::
:title: Step 2
:link: 02_create-service
:class: large-4
:anchor: View
Create a service
.. topic-box::
:title: Step 3
:link: 03_hardware-compile
:class: large-4
:anchor: View
Compile for Embassy hardware
.. topic-box::
:title: Step 4
:link: 04_docker-build
:class: large-4
:anchor: View
Build service with Docker
.. topic-box::
:title: Step 5
:link: 05_create-manifest
:class: large-4
:anchor: View
Create Manifest file
.. topic-box::
:title: Step 6
:link: 06_create-assets
:class: large-4
:anchor: View
Create package assets
.. topic-box::
:title: Step 7
:link: 07_create-s9pk
:class: large-4
:anchor: View
Package service components together
.. topic-box::
:title: Step 8
:link: 08_create-makefile
:class: large-4
:anchor: View
Create Makefile with build steps (optional)
.. topic-box::
:title: Step 9
:link: 09_create-wrapper
:class: large-4
:anchor: View
Create wrapper repository to host code for review
.. topic-box::
:title: Step 10
:link: 10_install-package
:class: large-4
:anchor: View
Install packaged service on embassyOS
.. topic-box::
:title: Resources
:link: resources
:class: large-4
:anchor: View
Get help, learn how to submit your package to a marketplace, and example references
.. raw:: html
</div></div>
.. This is for the side navigation display
.. toctree::
:maxdepth: 1
:hidden:
01_setup
02_create-service
03_hardware-compile
04_docker-build
05_create-manifest
06_create-assets
07_create-s9pk
08_create-makefile
09_create-wrapper
10_install-package
resources

View File

@@ -1,35 +0,0 @@
.. _packaging-resources:
=========
Resources
=========
.. contents::
:depth: 2
:local:
Get help
--------
If you get stuck or are having issues debugging why your service is not packaging or running as expected, reach out to our community `dev chat <https://matrix.to/#/#community-dev:matrix.start9labs.com>`_ with questions.
Submission Process
------------------
When you have built and tested your project for embassyOS, please send Start9 a submission to dev@start9.com with a link to the wrapper repository. After being reviewed for security and compatibility, the service will be deployed to the Start9 Marketplace and available for all embassyOS users to download.
If you are deploying to an alternative marketplace, please shout it out in our community channels!
References
----------
Below are links to working examples of more advanced configurations for current Embassy services. They might serve as a starting point or reference during your development process:
- Detailed ``docker_entrypoint.sh`` - `Filebrowser <https://github.com/Start9Labs/filebrowser-wrapper/blob/master/docker_entrypoint.sh>`_
- Optional dependencies - `BTCPay Server <https://github.com/Start9Labs/btcpayserver-wrapper/blob/master/assets/compat/dependencies.yaml>`__
- Config spec - `BTCPay Server <https://github.com/Start9Labs/btcpayserver-wrapper/blob/master/assets/compat/config_spec.yaml>`__
- Config rules - `BTC RPC Proxy <https://github.com/Start9Labs/btc-rpc-proxy-wrapper/blob/master/assets/compat/config_rules.yaml>`__
- Multiple dependencies - `BTCPay Server <https://github.com/Start9Labs/btcpayserver-wrapper/blob/master/manifest.yaml#L172-L187>`__
- Actions - `BTCPay Server <https://github.com/Start9Labs/btcpayserver-wrapper/blob/master/actions/btcpay-admin.sh>`__
- Health checks - `BTCPay Server <https://github.com/Start9Labs/btcpayserver-wrapper/blob/master/assets/utils/health_check.sh>`__
- Alerts - `BTCPay Server <https://github.com/Start9Labs/btcpayserver-wrapper/blob/master/manifest.yaml#L207-L218>`__

View File

@@ -1,97 +0,0 @@
.. _environment-setup:
=================
Environment Setup
=================
.. contents::
:depth: 2
:local:
To get started packaging a service for embassyOS, some basic knowledge of software development is required. Don't worry if you are inexperienced, we will provide enough context to get you started, and you can always reach out with questions.
If you are already an experienced developer, :ref:`jump ahead <environment-quick-start>`.
The only system requirements are `Docker <https://docs.docker.com/get-docker>`_ and `Cargo <https://doc.rust-lang.org/cargo/>`_ (Rust package manager).
Of course, there are additional recommendations that would streamline your development experience, but they are not required.
Code Editor
-----------
A code editor is recommended since you will, after all, be writing code! We are fans of `Visual Studio Code <https://code.visualstudio.com/>`_ . Visual Studio Code is a free, batteries-included text editor made by Microsoft.
Terminal / CLI
--------------
We recommend using your computer's built-in terminal as a command line interface (CLI) for your operating system. For Windows users, we recommend the built-in command line (cmd) *Command Prompt* or the Powershell CLI, running in Administrator mode. For macOS and Linux, the native *Terminal* is recommended, but virtually any terminal will work.
If you are new to the command line, Ionic has published this awesome `guide <https://ionicframework.com/blog/new-to-the-command-line/>`_ to get you started.
.. _environment-setup-git:
Git
---
Although not required, the version control system Git is highly recommended.
Git is often accompanied by a Git Host, such as `GitHub <https://github.com/>`_, in which case additional setup is required. Follow the tutorial from the GitHub `here <https://docs.github.com/en/get-started/quickstart/set-up-git>`_ to set up your environment.
To verify the installation, open a new terminal window and run:
.. code:: bash
git --version
Docker
------
`Docker <https://docs.docker.com/get-docker>`_ must be installed on your computer. It is needed to build an image for your package, which will be used to create the running instance of your package on embassyOS. In essence, it declares the necessary environment and building stages for your package to run.
We also recommend installing and using `Docker buildx <https://docs.docker.com/buildx/working-with-buildx/>`_, as this adds desirable new features to the Docker build experience. It is included by default with Docker Desktop for Windows and macOS.
Cargo
-----
Cargo is the package management solution for the Rust programming language. It will install Rust to your system, and provide the required environment to build the Embassy SDK for packaging your service into the required format needed by embassyOS.
Installation instructions for Cargo can be found `here <https://doc.rust-lang.org/cargo/getting-started/installation.html>`__.
To verify the installation, open a terminal window and run:
.. code:: bash
cargo --version
SDK
---
embassyOS provides a :ref:`software development kit <sdk>` embedded in its environment. You do not need a running instance of embassyOS to use this component, it can be installed on any computer platform.
To install the SDK:
.. code:: bash
git clone --recursive https://github.com/Start9Labs/embassy-os.git && cd embassy-os/backend && ./install-sdk.sh
To verify the installation, open a terminal window and run:
.. code:: bash
embassy-sdk --version
embassyOS
---------
While not strictly necessary, having a running instance of embassyOS is recommended to test installing, running, configuring, and using your package. Without this component, you will have to coordinate with Start9's internal development team to test.
.. _environment-quick-start:
Quick Start Environment Setup
-----------------------------
- `Docker <https://docs.docker.com/get-docker>`_
- `Docker buildx <https://docs.docker.com/buildx/working-with-buildx/>`_
- `Cargo <https://doc.rust-lang.org/cargo/getting-started/installation.html>`__
- `embassyOS <https://github.com/Start9Labs/embassy-os>`_
- `Embassy SDK <https://github.com/Start9Labs/embassy-os/blob/master/backend/install-sdk.sh>`_

View File

@@ -1,62 +0,0 @@
.. _packaging-getting-started:
===============
Getting Started
===============
Select an option below to get started with packing a service for embassyOS.
.. raw:: html
<div class="topics-grid grid-container full">
<div class="grid-x grid-margin-x">
.. topic-box::
:title: Environment Setup
:link: environment-setup
:icon: scylla-icon scylla-icon--integrations
:class: large-4
:anchor: View
Get your environment setup to optimize service packaging
.. topic-box::
:title: Build your first Package
:link: build-package-example/index
:icon: scylla-icon scylla-icon--open-source
:class: large-4
:anchor: Begin
Follow along to learn packaging fundamentals with an example
.. topic-box::
:title: SDK
:link: sdk
:icon: scylla-icon scylla-icon--apps
:class: large-4
:anchor: View
Discover details about Start9's Software Development Kit
.. topic-box::
:title: Checklist
:link: checklist
:icon: scylla-icon scylla-icon--roadmap
:class: large-4
:anchor: Begin
Quickly get started with concise steps
.. raw:: html
</div></div>
.. This is for the side navigation display
.. toctree::
:maxdepth: 1
:hidden:
environment-setup
sdk
checklist

View File

@@ -1,97 +0,0 @@
.. _sdk:
===========
Embassy SDK
===========
Embassy SDK, or Software Development Kit, is a CLI (Command Line Interface) tool that aids in building and packaging services you wish to deploy to the Embassy.
It mainly helps you validate that the necessary components of your package exist, and package all of those components into a special file type that is understood by embassyOS.
To install, checkout the SDK step in :ref:`setting up your environment <environment-setup>`.
Commands
========
To see a list of all available commands provided, run the following from an terminal window:
.. code:: bash
embassy-sdk --help
embassy-sdk init
----------------
Initialize the developer key for interacting with the SDK.
By default, this creates the developer key at `$HOME/embassy`. You might need to change ownership of this folder depending on your system permissions.
.. code:: bash
chown <user> /etc/embassy
Alternatively, you can write a config file with your desired developer key location, it simply needs the following format:
.. code:: yaml
developer-key-path: /desired/path/to/key
And load it by running:
.. code:: bash
embassy-sdk -c /path/to/config init
embassy-sdk pack
----------------
This command takes the necessary package components and assembles them into the `s9pk` file format needed to install a service on embassyOS. It expects the following files to exist:
- Manifest
- Instructions
- License
- Icon
If this command fails, the error response will indicate which component is missing.
embassy-sdk verify
-------------------
This command verifies aspects about the components assembled into the `s9pk`, such as:
- Ensures that all mounts are real volumes in the manifest
- Ensures all cert volumes point to real interfaces in the manifest
- Ensures all actions refer to real images in the manifest
- Ensures all images are tagged correctly in the manifest
- Ensures the icon is less than 100KB
It should be run _after_ `embassy-sdk pack` in order to verify the validity of each component.
If this command fails, the error message will indicate the mismatched details.
embassy-sdk git-info
--------------------
This command outputs the git commit hash of the SDK version installed on your platform.
embassy-sdk inspect
-------------------
This command contains several utilities for reading components once packaged into the `s9pk`. In development, it can be helpful to determine if each component is successfully included in the `s9pk` package.
It contains the following subcommands, and requires the path to the `<pacakge-id>.s9pk` file as the last argument:
- docker-images
- hash
- icon
- instructions
- license
- manifest
For example:
.. code:: bash
embassy-sdk inspect instructions /path/to/<package-id>.s9pk

View File

@@ -4,15 +4,7 @@
Developer Docs
==============
Welcome to Service Packaging for embassyOS!
If you are here, you are interested in becoming part of the mission to change the future of personal computing.
The guides below provide the fundamentals that will take you through the process of packing a service for embassyOS. Services are any open source project (application) that can be run on a self-hosted platform, independent of third parties.
By configuring and packaging a project according to these guides, it can be installed on embassyOS so that users can interact with the service without needing any technical expertise.
Let's get started!
Welcome to the Service Packaging documentation for embassyOS. If you are here, you have heard the call to help empower users with sovereign computing!
.. raw:: html
@@ -21,56 +13,29 @@ Developer Docs
<div class="grid-x grid-margin-x">
.. topic-box::
:title: Getting Started
:link: getting-started
:icon: scylla-icon scylla-icon--nsql-guides
:title: Service Packaging
:link: packaging
:icon: scylla-icon scylla-icon--resource-center
:class: large-4
:anchor: View
:anchor: Build
Set up your environment and follow along with an example
.. topic-box::
:title: Build your first Package
:link: build-package-example
:icon: scylla-icon scylla-icon--open-source
:class: large-4
:anchor: Begin
Follow along to learn packaging fundamentals with an example
.. topic-box::
:title: SDK
:link: getting-started/sdk
:icon: scylla-icon scylla-icon--apps
:class: large-4
:anchor: View
Discover details about the Start9 Software Development Kit
A concise guide to Service Packaging
.. topic-box::
:title: Full Specification
:link: specification
:icon: scylla-icon scylla-icon--glossary
:class: large-4
:anchor: View
:anchor: Read
Detailed service packaging specification and advanced features
.. topic-box::
:title: Packaging Checklist
:link: getting-started/checklist
:icon: scylla-icon scylla-icon--roadmap
:class: large-4
:anchor: Begin
A quick way to check your work
.. topic-box::
:title: Advanced Guides
:link: advanced
:icon: scylla-icon scylla-icon--integrations
:class: large-4
:anchor: View
:anchor: Tinker
Guides for implementing advanced service configurations
@@ -83,7 +48,6 @@ Developer Docs
:maxdepth: 1
:hidden:
getting-started/index
build-package-example/index
packaging
specification/index
advanced/index

View File

@@ -0,0 +1,402 @@
.. _service-packaging:
=================
Service Packaging
=================
.. contents::
:depth: 2
:local:
Welcome! Thank you for your interest in contributing to the growing ecosystem of open software. We call the software applications that run on `embassyOS <https://github.com/start9labs/embassy-os>`_ "services." This distinction is made to differentiate from "applications" (apps), which are generally run on a client, and used to access server-side software (services). To run services on embassyOS, a package of file components needs to be composed. This guide will dive into the basic structure of how to compose this package.
Check out the :ref:`glossary <glossary>` to get acquainted with unfamiliar terms. The bottom of this guide also includes :ref:`support <packaging-support>` links, including a master checklist.
Let's get started!
Steps
-----
#. :ref:`Choose software to package <choosing-software>`
#. :ref:`Set up the development environment <development-environment>`
#. :ref:`Try out the hello-world demo project <hello-world-example>`
#. :ref:`Package the service <package-the-service>`
#. :ref:`Build a Dockerfile <build-a-dockerfile>`
#. :ref:`Create the file structure <create-file-structure>`
#. :ref:`Format the package <format-package>`
#. :ref:`Test the service on embassyOS <testing>`
#. :ref:`Submit and/or distribute <submission-and-distribution>`
.. _choosing-software:
Choosing Software
=================
Almost any type of open source software can be run on embassyOS. No matter what programming language, framework, database or interface the service has, it can be adapted for embassyOS. This is made possible by the power of Docker containers (don't worry, we'll get to this). We do have a few recommendations for choosing a service that will perform optimally across platforms:
#. It either has a web user interface (it can be interacted with in a web browser), or is server software that external applications or internal services can connect to. Please keep in mind that embassyOS users are not expected to have SSH and/or CLI access.
- The interfaces supported are: HTTP, TCP, and REST APIs
#. It can be compiled for ARM (``arm64v8``)
#. It can be served over TOR
#. It creates a container image that is optimized for size (under 1GB) to save device space and expedite installation time
.. _development-environment:
Development Environment
=======================
A basic development and testing environment includes:
#. An Embassy One or Pro with latest `embassyOS <https://github.com/start9labs/embassy-os/releases>`_
- Use your own hardware to `DIY <https://start9.com/latest/diy>`_
- Purchase a device from the `Start9 Store <https://store.start9.com>`_
- x86/VM support coming soon
#. A development machine
- Linux is highly recommended, and this walkthrough will assume a Debian-based (Ubuntu) distribution
Dependencies - Recommended
..........................
These tools may or may not be necessary, depending on your environment and the package you are building.
- Code Editor (IDE) - We recommend `Visual Studio Code <https://code.visualstudio.com/>`_
- Build essentials (Ubuntu) - Common build tools and encryption libraries.
.. code-block::
sudo apt-get install -y build-essential openssl libssl-dev libc6-dev clang libclang-dev ca-certificates
- Git - This is a version control system that is used widely in Open Source development.
.. code-block::
sudo apt install git
Use the following verify installation:
.. code-block::
git --version
.. note:: Anytime you use a ``git clone`` command in this guide, it will create a new directory with code in it, so make sure you are executing this command from a directory that you want to store code in, such as your ``home`` folder.
- yq - A lightweight and portable command-line YAML, JSON and XML processor.
.. code-block::
sudo snap install yq
Dependencies - Required
.......................
- `Docker <https://docs.docker.com/get-docker/>`_ - Docker is currently the only supported containerization method for embassyOS. This declares the necessary environment and building stages for your package to run. Install the desktop GUI or via the command line:
.. code-block::
curl -fsSL https://get.docker.com -o- | bash
sudo usermod -aG docker "$USER"
exec sudo su -l $USER
We need to enable cross-arch emulated builds in Docker (unless you are building on an ARM machine, such as an M1 Mac - in which case, skip this step).
.. code-block::
docker run --privileged --rm linuxkit/binfmt:v0.8
- `Buildx <https://docs.docker.com/buildx/working-with-buildx/>`_ - This adds desirable new features to the Docker build experience. It is included by default with Docker Desktop GUI. If Docker was installed via command line, additionally run:
.. code-block::
docker buildx install
docker buildx create --use
- Rust & Cargo - Cargo is the package management solution for the Rust programming language. It is needed to build the Embassy SDK. The following will install both Rust and Cargo:
.. code-block::
curl https://sh.rustup.rs -sSf | sh
source $HOME/.cargo/env
Verify install:
.. code-block::
cargo --version
- Embassy SDK - embassyOS has an embedded Software Development Kit (SDK). You can install this component on any system, without needing to run embassyOS.
.. code-block::
git clone -b latest --recursive https://github.com/Start9Labs/embassy-os.git && cd embassy-os/backend && ./install-sdk.sh
Initialize sdk & verify install
.. code-block::
embassy-sdk init
embassy-sdk --version
- Deno (an optional component for more advanced SDK features) - A simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust. It is used to enable the scripting API portion of the SDK.
.. code-block::
sudo snap install deno
.. _hello-world-example:
Demo with Hello World
=====================
Check your environment setup by building a demo project and installing it to embassyOS.
#. Get Hello World
.. code-block::
git clone https://github.com/Start9Labs/hello-world-wrapper.git
cd hello-world-wrapper
#. Build to create ``hello-world.s9pk``
.. code-block::
make
#. Sideload & Run
- In the embassyOS web UI menu, navigate to `Embassy -> Settings -> Sideload Service`
- Drag and drop or select the ``hello-world.s9pk`` from your filesystem to install
- Once the service has installed, navigate to `Services -> Hello World` and click "Start"
- Once the Health Check is successful, click "Launch UI" and verify you see the Hello World page
.. _package-the-service:
Package the service
===================
The package file produced by this process has a ``s9pk`` extension. This file is what is installed to run a service on embassyOS.
.. _build-a-dockerfile:
Build a Dockerfile
..................
A Dockerfile defines the recipe for building the environment to run a service. Currently, embassyOS only supports one Dockerfile per project (i.e. no Docker compose), so it should include any necessary database configurations. There are several methods to build a Dockerfile for your service.
First, check to see if the upstream project has already built one. This is usually your best source for finding Docker images that are compatible with ARM. Next, you can:
- Download an image from [Docker Hub](https://hub.docker.com/)
- Make a new Dockerfile, and pull in an image the upstream project hosted on Docker Hub as the base
- Make a new Dockerfile, and pull in a small distribution base (eg. alpine) and compile the build environment yourself using the upstream project source code
After coding the build steps, build the Docker image using ``docker buildx``, replacing the placeholder variables:
.. code-block::
docker buildx build --tag start9/$(PKG_ID)/main:$(PKG_VERSION) --platform=linux/arm64 -o type=docker,dest=image.tar .
The resulting ``image.tar`` artifact is the Docker image that needs to be included in the ``s9pk`` package.
.. _create-file-structure:
Create File Structure
.....................
Once we have a Docker image, we can create the service wrapper. A service wrapper is a repository of a new git committed project that "wraps" an existing project (i.e. the upstream project). It contains the set of metadata files needed to build a ``s9pk``, define information displayed in the user interface, and establish the data structure of your package. This repository can exist on any hosted git server - it does not need to be a part of the Start9 GitHub ecosystem.
The following files should be included in the service wrapper repository:
- ``manifest.yaml``, which defines:
- The package id - a unique lowercase and hyphenated package identifier (eg. hello-world)
- Essential initialization details, such as version
- Where you are persisting your data on the filesystem (i.e. mounts and volumes)
- Port mappings (i.e. interfaces)
- Check out the `Hello World example <https://github.com/Start9Labs/hello-world-wrapper/blob/master/manifest.yaml>`_ to see line-by-line details
- ``instructions.md``
- Instructions for the user
- Appears as a menu item in the service page UI
- ``LICENSE``
- The Open Source License for your wrapper
- ``icon.png``
- The image that will be associated with the service throughout the UI, including in a marketplace
- ``MAKEFILE``
- Build instructions to create the s9pk
- `Example <https://github.com/Start9Labs/hello-world-wrapper/blob/f44899be8523b784861aac92e43fe60f0bf219eb/Makefile#L1-L28>`_
- ``Dockerfile``
- A recipe for service creation
- Add here any prerequisite environment variables, files, or permissions
- Examples:
- `Using an existing docker image <https://github.com/kn0wmad/robosats-wrapper/blob/d4a0bd609ce18036dfd7ee57e88d437e54d8efb9/Dockerfile#L1>`_
- `Implementing a database <https://github.com/Start9Labs/photoview-wrapper/blob/ba399208ebfaabeafe9bea0829f494aafeaa9422/Dockerfile#L3-L9>`_
- `Using a submodule <https://github.com/Start9Labs/ride-the-lightning-wrapper/blob/3dfe28b13a3886ae2f685d10ef1ae79fc4617207/Dockerfile#L9-L28>`_
- ``docker_entrypoint.sh``
- Starts and governs the operation of a service container
- Gracefully handles container errors and user preferences, i.e. username/password, SIGTERMs
- Examples:
- `Robosats <https://github.com/kn0wmad/robosats-wrapper/blob/master/docker_entrypoint.sh>`_
- `Photoview <https://github.com/Start9Labs/photoview-wrapper/blob/master/docker_entrypoint.sh>`_
- `RTL <https://github.com/Start9Labs/ride-the-lightning-wrapper/blob/master/docker_entrypoint.sh>`_
.. _format-package:
Format Package
..............
Building the final ``s9pk`` artifact depends on the existence of the files listed above, and the execution of the following steps (which should be added to the Makefile):
- Package the ``s9pk``:
.. code-block::
embassy-sdk pack
- Verify the ``s9pk`` (replace PKG_ID with your package identifier):
.. code-block::
embassy-sdk verify s9pk PKG_ID.s9pk
The verification step will provide details about missing files, or fields in the service manifest file.
That's it! You now have a package!
.. _testing:
Testing
=======
#. Run the ``make`` command from the root folder of your wrapper repository to execute the build instructions defined in the ``MAKEFILE``
#. Install the package, via either:
#. Drag and drop:
- In the embassyOS web UI menu, navigate to `Embassy -> Settings -> Sideload Service`
- Drag and drop or select the ``<package>.s9pk`` from your filesystem to install
#. Use the CLI:
- Create a config file with the IP address of the device running embassyOS:
.. code-block::
touch /etc/embassy/config.yaml
echo "host: <IP_ADDRESS_REPLACE_ME>" > /etc/embassy/config.yaml
- Login with master password
.. code-block::
embassy-cli auth login
embassy-cli package install <PACKAGE_ID_REPLACE_ME>.s9pk
.. figure:: /_static/images/dev/nc-install.png
:width: 60%
:alt: Installing a service
#. Once the service has installed, navigate to `Services -> <Service Name>` and click "Start"
#. Check that the service operations function as expected by either launching the UI, or querying if a server application
#. Check that each UI element on the service's page displays the proper information and is accurately formatted
#. Ensure the service can be stopped, restarted, and upgraded (if applicable)
.. figure:: /_static/images/dev/nc-service.png
:scale: 40%
:alt: An eOS service page
.. _submission-and-distribution:
Submission and Distribution
===========================
The ``s9pk`` file can be uploaded for distribution to any website, repository, or marketplace. You can also submit your package for publication consideration on a Start9 Marketplace by emailing us at submissions@start9labs.com or by contacting us in one of our [community channels](https://start9.com/latest/about/contact). Please include a link to the wrapper repository with a detailed README in the submission.
Advanced configuration
======================
Scripting on embassyOS
......................
Start9 has developed a highly extensible scripting API for developers to create the best possible user experience. This is your toolkit for creating the most powerful service possible by enabling features such as:
- Configuration
- Version migration
- Dependencies
- Health checks
- Properties
Use is optional. To experiment, simply use the existing skeleton from the Hello World wrapper `example <https://github.com/Start9Labs/hello-world-wrapper/tree/master/scripts>`_, changing only the package version in the `migration file <https://github.com/Start9Labs/hello-world-wrapper/blob/f44899be8523b784861aac92e43fe60f0bf219eb/scripts/procedures/migrations.ts#L4>`_.
Check out the specification `here <https://start9.com/latest/developer-docs/specification/js-procedure>`_.
.. _packaging-support:
Support
=======
Have a question? Need a hand? Please jump into our `Community <https://community.start9.com>`_, or our `Matrix Community Dev Channel <https://matrix.to/#/#community-dev:matrix.start9labs.com>`_. You can also check out our full list of :ref:`Community Channels <contact>`.
Need more details? Check out the :ref:`Service Packaging Specification <service-packaging-spec>`
You may like to use this handy :ref:`Checklist <packaging-checklist>` to be sure you have everything covered.
.. _glossary:
Glossary
========
`service` - open software applications that run on embassyOS
`package` - the composed set of a Docker image, a service manifest, and service instructions, icon, and license, that are formatted into a file with the `s9pk` extension using `embassy-sdk`
`wrapper` - the project repository that "wraps" the upstream project, and includes additionally necessary files for building and packaging a service for eOS
`scripts` - a set of developer APIs that enable advanced configuration options for services
`embassy-sdk` - the Software Development Toolkit used to package and verify services for embassyOS
`open source software` - computer software that is released under a license in which the copyright holder grants users the rights to use, study, change, and distribute the software and its source code to anyone and for any purpose
`upstream project` - the original, source project code that is used as the base for a service
`embassyOS` - a browser-based, graphical operating system for a personal server
`eOS` - shorthand for embassyOS
`s9pk` - the file extension for the packaged service artifact needed to install and run a service on embassyOS
:ref:`Back to Top <service-packaging>`

View File

@@ -1,4 +1,4 @@
.. _packaging-quick-start:
.. _packaging-checklist:
=========
Checklist

View File

@@ -120,3 +120,4 @@ The following guides provide an in depth overview of the full capabilities avail
js-procedure
submission
compat/index
checklist

View File

@@ -62,7 +62,7 @@
:class: large-4
:anchor: View
Package a service for the Embassy Marketplace
Package a service for the Marketplace
.. raw:: html