Skip to content

Commit d015289

Browse files
authored
Merge pull request #3566 from headlamp-k8s/new-docs
docs: Revamp plugin development docs
2 parents bb0b556 + 977e310 commit d015289

File tree

6 files changed

+778
-351
lines changed

6 files changed

+778
-351
lines changed

docs/development/plugins/building.md

Lines changed: 116 additions & 199 deletions
Original file line numberDiff line numberDiff line change
@@ -3,257 +3,174 @@ title: Building and Shipping Plugins
33
sidebar_label: Building & Shipping
44
---
55

6-
This section explains how to start developing a Headlamp plugin and how
7-
to ship it once finished.
6+
Once you have a plugin ready, you may want to build it for production and
7+
deploy with Headlamp or publish it for other Headlamp users to enjoy.
88

9-
## Creating a new plugin
9+
## Deploying Plugins (General Information)
1010

11-
This is how to start a new plugin:
11+
Once your plugin is built and tested, you need to deploy it to your Headlamp instances. This section covers all deployment scenarios.
1212

13-
```bash
14-
npx --yes @kinvolk/headlamp-plugin create headlamp-myfancy
15-
cd headlamp-myfancy
16-
npm run start
17-
```
18-
19-
There's some basic code inside src/index.tsx.
20-
21-
Now run Headlamp (the desktop app or the
22-
[development version](../index.md#run-the-code)),
23-
and your plugin should be loaded.
24-
25-
Using the above commands means that Headlamp will **automatically reload**
26-
whenever to make a change to the plugin.
27-
28-
ℹ️ This automatic reload does not happen when running in-cluster,
29-
even if the plugins folder is changed. I.e., if you want to serve
30-
updated plugins, you need to restart the server.
31-
32-
## Code Formatting, Linting, and Type Checking
33-
34-
Your plugin has a few tools built in to help make development easier.
35-
36-
#### Format code with prettier
37-
38-
```bash
39-
npm run format
40-
```
41-
42-
#### Find code lint issues with eslint
13+
Let's assume that Headlamp will be run with the `-plugins-dir` option set to
14+
`/headlamp/plugins`, which is the default for in-cluster deployments.
4315

44-
```bash
45-
npm run lint
46-
```
16+
### Plugin Directory Structure
4717

48-
Eslint also allows you to try and automatically fix issues.
18+
Headlamp expects plugins to follow a specific directory structure:
4919

50-
```bash
51-
npm run lint-fix
5220
```
53-
54-
#### Run the type checker
55-
56-
```bash
57-
npm run tsc
21+
my-plugins/ # Plugin root directory
22+
├── MyPlugin1/
23+
│ ├── main.js # Built plugin file
24+
│ └── package.json # Plugin metadata
25+
├── MyPlugin2/
26+
│ ├── main.js
27+
│ └── package.json
28+
└── MyPlugin3/
29+
├── main.js
30+
└── package.json
5831
```
5932

60-
#### Run the tests
33+
### Extracting Built Plugins
6134

62-
```bash
63-
npm run test
64-
```
65-
66-
## Building for production
67-
68-
To build the previous plugin example for production, run the following
69-
command:
35+
To extract a single plugin, you can package it first, then extract the package to the right place:
7036

7137
```bash
72-
cd headlamp-myfancy
7338
npm install
7439
npm run build
75-
```
76-
77-
This will create a file with the bundled plugin in
78-
`headlamp-myfancy/dist/main.js`.
79-
80-
### Building a folder of packages at once
40+
npm run package
8141

82-
For convienience the `headlamp-plugin build` command can build a
83-
package or folder of packages.
84-
85-
```bash
86-
npx @kinvolk/headlamp-plugin build myplugins/headlamp-myfancy
87-
npx @kinvolk/headlamp-plugin build myplugins
42+
# Extract single plugin
43+
tar xvzf my-first-plugin-0.1.0.tar.gz -C /headlamp/plugins
8844
```
8945

90-
## Shipping and Deploying Plugins
46+
If you prefer to export one or more plugins directly, use the `headlamp-plugin` tool. Run `npm run build` first. Then use the `extract` option on a folder with Headlamp plugins.
9147

92-
Once a plugin is ready to be shipped (built for production), it needs to
93-
be placed in a "plugins directory" for Headlamp to load it.
94-
95-
For example, if we have built 3 plugins called MyPlugin1, MyPlugin2, and
96-
MyPlugin3, they should be added to a directory in the following structure:
48+
For a directory like this:
9749

9850
```
99-
.plugins/
100-
MyPlugin1/
101-
main.js
102-
MyPlugin2/
103-
main.js
104-
MyPlugin3/
105-
main.js
51+
# Directory structure
52+
my-plugins/
53+
├── MyPlugin1/
54+
│ ├── dist/
55+
│ │ └── main.js
56+
│ └── package.json
57+
└── MyPlugin2/
58+
├── dist/
59+
│ └── main.js
60+
└── package.json
10661
```
10762

108-
If our plugins are placed in `myplugins`, we can conveniently create that
109-
folder with the following command:
63+
You can extract the plugins into a target directory like this:
11064

11165
```bash
112-
npx @kinvolk/headlamp-plugin extract ./myplugins /path/to/.plugins
66+
npx @kinvolk/headlamp-plugin extract ./my-plugins /headlamp/plugins
11367
```
11468

115-
This also works individually (for each plugin):
69+
## Plugins in Headlamp Desktop
11670

117-
```bash
118-
npx @kinvolk/headlamp-plugin extract ./myplugins/MyPlugin1 /path/to/./plugins
119-
```
71+
Headlamp Desktop has a Plugin Catalog to install plugins easily. It includes plugins from Headlamp developers and the community.
12072

121-
### In-cluster deployment with plugins
73+
By default, only official plugins in the Plugin Catalog are allowed. The catalog confirms which plugin you want to install. It also shows where the plugin will be downloaded from.
12274

123-
For in-cluster Headlamp deployments, when running Headlamp's server,
124-
the `-plugin-dir` option should point to the directory:
75+
:::important
76+
The Plugin Catalog allows users to change the default behavior and instead show all
77+
plugins. It is however extremely important that you only run plugins that you
78+
trust, as plugins run in the same JavaScript context as the main application.
79+
:::
12580

126-
```bash
127-
./headlamp-server -plugins-dir=.plugins
128-
```
81+
To learn how to publish your plugin to make it available in the Plugin Catalog for other users, see the [Publishing Plugins guide](./publishing.md).
12982

130-
### Using plugins on the desktop version
83+
### Manual Installation
13184

132-
The Headlamp desktop app will look for the plugins directory (in the format
133-
mentioned above). This will be either under the user's Headlamp configuration folder
134-
or within the current folder as `.plugins` if the former doesn't exist.
135-
136-
### Bundling plugins with desktop version
137-
138-
To build a Headlamp app with a set of plugins, first extract some plugins
139-
into the .plugins folder in the root of the "headlamp" repo.
85+
First, build and package the plugin in the plugin folder:
14086

14187
```bash
142-
cd plugins/examples/pod-counter
88+
cd my-plugin/
14389
npm install
14490
npm run build
145-
cd ../..
146-
147-
mkdir .plugins
148-
npx @kinvolk/headlamp-plugin extract ./plugins/examples/ ./.plugins
149-
ls -la .plugins
150-
make app-linux
91+
npm run package
15192
```
15293

153-
For more on how to extract files into there see "Shipping and Deploying Plugins" above.
154-
155-
### More on making a headlamp container image including plugins
156-
157-
See the blog post
158-
"[Get up to speed deploying Headlamp with plugins](https://headlamp.dev/blog/2022/10/20/best-practices-for-deploying-headlamp-with-plugins)"
159-
for more information on building a container image with your plugins.
160-
161-
## Writing storybook stories
94+
You can install the plugin in the Headlamp desktop app by exporting the plugin
95+
archive to the plugins directory. E.g.:
16296

163-
What is a storybook story?
164-
165-
From <https://storybook.js.org/docs/web-components/get-started/introduction>
166-
167-
> Storybook is a tool for UI development. It makes development faster and
168-
> easier by isolating components. This allows you to work on one component
169-
> at a time. You can develop entire UIs without needing to start up a
170-
> complex dev stack, force certain data into your database,
171-
> or navigate around your application.
172-
173-
See an example in your browser:
97+
On Linux/macOS:
17498

17599
```bash
176-
$ cd plugins/examples/pod-counter
177-
$ ls src
178-
headlamp-plugin.d.ts index.tsx Message.stories.tsx Message.tsx
179-
$ npm install
180-
$ npm run storybook
100+
mkdir -p ~/.config/Headlamp/plugins/
101+
tar xvf my-first-plugin-0.1.0.tar.gz -C ~/.config/Headlamp/plugins/
181102
```
182103

183-
Your browser should open and show you a Message component with three
184-
different states the component can be in.
185-
186-
Note that there is a Message.stories.tsx to go along with the Message.tsx
187-
which has the `<Message>` component defined within it. See that file for an
188-
example of how to write a story.
104+
These are the default plugin directory locations for the Headlamp desktop app:
189105

190-
### Snapshot testing
106+
| Operating System | Default Plugin Directory |
107+
|------------------|--------------------------|
108+
| **MacOS** | `$HOME/.config/Headlamp/plugins` |
109+
| **Linux** | `$HOME/.config/Headlamp/plugins` |
110+
| **Windows** | `%APPDATA%/Headlamp/Config/plugins` |
191111

192-
Another benefit of writing storybook stories is that they can act as
193-
unit tests for regression testing. Storyshots will save snapshots
194-
of html for the different states that a component can be in. See the
195-
[Snapshot tests](https://storybook.js.org/docs/react/writing-tests/snapshot-testing)
196-
guide in the storybook documentation for more information.
112+
## Plugins in Headlamp Deployments
197113

198-
This is in addition to the benefit of making sure your components can be
199-
manually tested and developed quickly in isolation.
114+
### Using InitContainer with a Plugin Image
200115

201-
See the [storybook documentation](https://storybook.js.org/docs/) for full
202-
details on storybook.
116+
When deploying Headlamp with plugins, it is easier to use a container image with the plugins already installed. Then, use an init container to mount the plugins into the Headlamp container.
203117

204-
## Running tests on a github action
118+
Some plugins already have a published container image. For Headlamp's official plugins, see this [list](https://github.com/orgs/headlamp-k8s/packages?tab=packages&q=headlamp-plugin).
205119

206-
A workflow for testing your plugin on github with actions.
207-
208-
Below is based on the [Building and testing Node.js](https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs) docs from GitHub.
209-
210-
Place this in a file named something like `.github/workflows/headlamp-plugin-github-workflow.yaml` in the root of your repo.
120+
You can thus deploy Headlamp with an init container, such as the [Flux UI plugin image](ghcr.io/headlamp-k8s/headlamp-plugin-flux:v0.3.0):
211121

212122
```yaml
213-
name: Headlamp plugin linting, type checking, and testing
214-
215-
on:
216-
push:
217-
branches: [main]
218-
pull_request:
219-
branches: [main]
220-
221-
jobs:
222-
build:
223-
runs-on: ubuntu-latest
224-
225-
defaults:
226-
run:
227-
working-directory: ./your-folder-of-plugins
228-
229-
strategy:
230-
matrix:
231-
node-version: [18.x]
232-
233-
steps:
234-
- uses: actions/checkout@v4
235-
- name: Use Node.js ${{ matrix.node-version }}
236-
uses: actions/setup-node@v3
237-
with:
238-
node-version: ${{ matrix.node-version }}
239-
- run: npx @kinvolk/headlamp-plugin lint .
240-
- run: npx @kinvolk/headlamp-plugin format --check .
241-
- run: npx @kinvolk/headlamp-plugin tsc .
242-
- run: npx @kinvolk/headlamp-plugin test .
243-
- run: npx @kinvolk/headlamp-plugin build .
244-
```
123+
apiVersion: apps/v1
124+
kind: Deployment
125+
metadata:
126+
name: headlamp-with-flux
127+
labels:
128+
app: headlamp-with-flux
129+
spec:
130+
selector:
131+
matchLabels:
132+
app: headlamp-with-flux
133+
template:
134+
metadata:
135+
labels:
136+
app: headlamp-with-flux
137+
spec:
138+
initContainers:
139+
- name: fetch-plugins
140+
image: ghcr.io/headlamp-k8s/headlamp-plugin-flux:latest
141+
# Copy the plugins
142+
command: ["/bin/sh", "-c"]
143+
args: ["cp -r /plugins/* /headlamp/plugins/ && ls -l /headlamp/plugins"]
144+
volumeMounts:
145+
- name: plugins
146+
mountPath: /headlamp/plugins
147+
containers:
148+
- name: headlamp
149+
image: ghcr.io/headlamp-k8s/headlamp:latest
150+
args: ["-plugins-dir=/headlamp/plugins"]
151+
ports:
152+
- containerPort: 4466
153+
volumeMounts:
154+
- name: plugins
155+
mountPath: /headlamp/plugins
156+
volumes:
157+
- name: plugins
158+
emptyDir: {}
159+
```
160+
161+
## Creating a Plugin Image
162+
163+
The Headlamp official plugins repository has a [Dockerfile](https://github.com/headlamp-k8s/plugins/blob/main/Dockerfile) to generate an image for a plugin. Here is how to use it with the Kompose plugin:
245164
246-
Please see the GitHub documentation for further details on workflows and actions.
247-
248-
## Upgrading package
249-
250-
There's a command that handles much of the upgrading of plugins to the latest headlamp-plugin version. This upgrade command also audits packages, formats code, lints, and type checks.
251-
252-
Additionally, this handles some code changes needed for plugins. For example, it handles running the material-ui 4 to mui 5 'codemod' code changes and creates missing configuration added in different versions of headlamp-plugin.
165+
```bash
166+
# Get the plugins
167+
git clone https://github.com/headlamp-k8s/plugins headlamp-plugins
253168

254-
Testing is necessary after running the upgrade command.
255-
Of course, make sure you have a backup of your plugin folder before running it.
169+
# Move to the plugins directory
170+
cd headlamp-plugins
256171

257-
```bash
258-
npx @kinvolk/headlamp-plugin upgrade --headlamp-plugin-version=latest your-plugin-folder
172+
# Build a container image for the kompose plugin
173+
docker build --build-arg PLUGIN=kompose -t kompose-plugin:latest -f ./Dockerfile .
259174
```
175+
176+
After this step you will have a `kompose-plugin:latest` image that you can use in your deployments, with the actual kompose plugin in its /plugins/kompose directory.

0 commit comments

Comments
 (0)