Skip to content

SIP: Add spin plugin#682

Closed
karthik2804 wants to merge 6 commits into
spinframework:mainfrom
karthik2804:SIP/spin-plugins
Closed

SIP: Add spin plugin#682
karthik2804 wants to merge 6 commits into
spinframework:mainfrom
karthik2804:SIP/spin-plugins

Conversation

@karthik2804

Copy link
Copy Markdown
Contributor

SIP to add plugins to spin.

rendered

Signed-off-by: karthik Ganeshram karthik.ganeshram@fermyon.com

Signed-off-by: karthik Ganeshram <karthik.ganeshram@fermyon.com>
@karthik2804 karthik2804 added the sip Improvement proposal: a design or architecture proposal for discussion and consensus label Aug 10, 2022

@kate-goldenring kate-goldenring left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for putting this together! This is an exciting addition. Added some comments/questions/thoughts.

- `install`
- `uninstall`

### Types of plugins

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be great to include examples of each of these categories

Comment thread docs/content/sips/xxx-spin-plugins.md Outdated

Spin dependant plugins can be distinguished from standalone binary plugins based on the name of the plugin. The Spin Dependant Plugins must follow the additional naming constraints.

- The name of the plugin must be `spin-$plugin` where `$plugin` must be `<type_of_plugin>-<name_of_plugin>`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is <type-of-plugin> one of the names from the Plugin Types section? That seems fairly verbose. We should potentially come up with one-word descriptors and limit the total number of options

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or it seems that "type of plugin" may be an overloaded term. Maybe clarify <type_of_dependent_plugin> here (even though it is implied by the section name) and potentially add another branch to the tree of plugin types. It also may be good to say that a trigger is a primary near future example adn it's dependent plugin "keyword" is trigger; however, some other ones could be ... Loaders etc and their keywords will be defined at the future point of use?

Spin dependant plugins will be categorized based on the setup/functionality sharing required from the spin binary. Based on this, they will be grouped into `<type_of_plguin>`. Some of the possible types are

- Host components
- Loaders

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate on Loaders and Config providers or give examples?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, loaders allow us to convert local configuration files or one pulled from bindle to spin configurations. In the future, we may potentially have multiple other sources from which the application configurations can be pulled depending on requirements.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like Loaders is an established Spin concept, and bindle is the only one we currently have support for. Thanks for explaining it to me! So what is the difference between a loader and configuration provider? One hosts the config and the other loads it into spin?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Configuration is about runtime configuration like what you might expect to get from environment variables, Vault (secrets), etc.


## Proposed implementation of `spin plugin`

### The `install` subcommand

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can a section be added on how to do updates. With spin templates the flow is spin templates install --update. To create a similar experience, it could be spin plugin install $plugin --update which will update it if it exists otherwise install latest

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this sounds like a good idea. I will work on it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be very nice (perhaps in a second iteration) to have something equivalent to spin plugin update --all. I think the expected behavior differs from templates in that you pretty much always want the latest version of a plugin.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Should an update do a check to see if an update is needed or always overwrite, even if it is bringing down the same version? I am not sure what the best way to do a version check would be, unless we save the current plugin manifest in the directory of the plugin and query the version there and upstream to see if there is a newer version.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think this would require storing information about anything installed via spin plugin install somewhere locally. I would probably lean towards a e.g. plugins.json in the same parent directory of plugins/

Comment thread docs/content/sips/xxx-spin-plugins.md Outdated
- It will contain information about the plugins such as location of binary release for the various operating system, version and checksum along with potentially other details such as author details and a description.
- Creators of new plugins can submit PRs with the required information to add it to the plugins index repository.

The structure of data stored for every plugin is a json file with the following structure

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will we support multiple versions of a plugin? Should the file be named $plugin_name-$version.json and by default spin will pull the highest versioned (following SemVer)? and install could also take in a --version $version flag?

@karthik2804 karthik2804 Aug 11, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is possible to support multiple versions of the plugins but the current idea is to provide only the latest release of every major release version but a discussion around this would be needed.

Comment thread docs/content/sips/xxx-spin-plugins.md Outdated

## Future Considerations

- Updates with breaking changes.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate here? Is this addressing the need to handle how we do updates when there are breaking changes? is a prerequisite of this supporting updates?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There has been some discussion on this although more discussion is required on this. One of the potential solutions is for the plugins to specify the compatibility with various versions of spin and use that to verify before installing.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add these thoughts to the SIP itself?

Comment thread docs/content/sips/xxx-spin-plugins.md Outdated

### Types of plugins

![Classification of types of plugins](https://i.imgur.com/Fo7EGPQ.png)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wonder if instead of linking an image here it would be better to represent via text since it is a short chart. Also would be easier to track changes. maybe like this:

Spin Plugins
├── Spin Dependant Plugins
│   ├── Internal Spin Plugins
│   └── Spin Dependent User Plugins
└── Standalone Binary Plugins

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense, I will make the changes.

Comment thread docs/content/sips/xxx-spin-plugins.md Outdated

![Classification of types of plugins](https://i.imgur.com/Fo7EGPQ.png)

- Standalone Binary Plugins (external subcommands) - These work to add features to spin and do not need any use of the spin binary.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if both Internal Spin Plugins and Spin Dependent User Plugins fall under the "Spin Dependent" category, then maybe they should both be prefixed by "Spin Dependent". IE Internal Spin Plugins => Spin Dependent Internal Plugin

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will make the changes.

Comment thread docs/content/sips/xxx-spin-plugins.md Outdated

### Spin dependant binary

For each `<type_of_plguin>`, a new spin execution path will be created sharing the required features/functionality before calling the spin plugin.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit spelling: "plugin". I find this Code Spell Checker VSCode extension to be a lifesaver as i always am mixing around letters

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

@itowlson itowlson left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very cool - I'm excited at the possibilities you imply. However it would be really useful to have examples of the different kinds of plugin and a bit more detail - even if only illustrative - of how Spin executes them. I'd also really really like to see a bit more detail on versioning, which I know is unglamorous but is going to bite people if we don't provide some control. But a great start - thanks for working through this!

Comment thread docs/content/sips/xxx-spin-plugins.md Outdated

#### Update of plugins

The system will use a rolling updates system where the latest plugin will be installed.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify this - are you saying that Spin will poll for new versions of plugins and automatically update? This is potentially a bit scary unless the user has a way to pin to a 'known good' version. What do you mean by "rolling" update here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, Spin does not poll for new versions of plugins. By rolling release, I mean whenever the user tries to install a plugin, they will be grabbing the latest version of the plugin.

"name": "test",
"description": "Some description.",
"homepage": "www.example.com",
"version": "1.0",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a document per version, or do new versions completely replace old ones?

@karthik2804 karthik2804 Aug 11, 2022

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is to replace the old ones completely with the new ones. The exception is major version changes. There will exist a document for every latest major version of the plugin. So if a plugin as has 2 versions. Then 2 documents will exist in the names $plugin.json (latest version) and $plugin@1.json.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may have missed it if it is already in here, but can you add this approach for major changes to the SIP?

A plugin can be installed using the following command.

```bash
$ spin plugin install <name_of_plugin>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There will need to be an option to install from local file (for testing) or from custom repo (for non-blessed plugins).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also an option to install a specific version (particularly important for plguins that may run in a CI or production environment).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The plugins can be directly placed in the install location for testing but a flag can be added to give these options.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Place it directly in the install location" isn't going to be great for a production environment though. An operator is going to want to be able to script creation of the environment, and have confidence that the script is repeatable.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. Adding an option to install from a local file makes sense.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be simply pointing to a local plugin-manifest.json rather than grabbing from remote, right? spin plugin install some-plugin -f /path/to/some-plugin.json. Installing a specific version could work similarly, where they always pass in the plugin-manifest with the version they want.

@lann lann Aug 11, 2022

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two different things you could do here:

  • pointing to a local manifest, which will lead to the actual binary being downloaded from one of the URLs in the manifest
  • pointing to a local binary, where you just want to copy/symlink that binary into the plugins directory

Not sure which of these would be better for production install I guess you probably want the former for production installs - the URLs can always be updated to point somewhere local if that's what the operator wants.

Comment thread docs/content/sips/xxx-spin-plugins.md Outdated
- **Standalone Binary Plugin**
- Once the plugin is invoked using `spin $plugin <args_to_plugin>`, the external subcommand is invoked as `spin-$plugin <args>`.
- **Spin Dependant User Plugins**
- Spin first provides all the functionality available in it required by the plugin and then proceeds to call the plugin along with the required parameters.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not quite getting the distinction here. Are you saying that Spin will have special knowledge of certain plugins and will have code to detect if one of these is being invoked and execute it in a special way?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will try to make it clearer with some made-up example plugins.

Standalone Binary Plugin - These are just basic binaries that can add functionality to spin (eg) spin routes just displays the HTTP routes for a given application from spin.toml.

Spin-based User Plugins - A made-up example of this would be spin deploy where the user invokes the command but as a plugin, it would require some functionality from spin. Therefore deploy is a type of command and it could have multiple plugins each of which deploys to different services.

Spin-based Internal Plugins - An example of this would be triggered, where the user does not directly call for the triggers but uses them by specifying them in the application manifest. Loaders would be another example of this.

And yes, Spin will be able to distinguish between the types of plugins from the name of the plugin.

Both Categories of Spin-based plugins will have keywords signifying types and all the types will be known ahead of time as each type of plugin follows a different execution path. The categories will be split into internal and user plugins.

An example of this would be a time trigger plugin called spin-trigger-time where the type of plugin is trigger which will be contained in a list of internal plugins.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are great examples - thanks!

So for both categories of "dependent plugin", the behaviour is:

  • Spin looks at the name of the plugin binary (e.g. spin-foo-bar and extracts the second component. This identifies a type of plugin and must be a well known string. [Or is the type derived in some other way, e.g. from the Spin command being issued, and the name of the plugin inferred from that.]
  • Based on that type, Spin knows the contract for calling that type of plugin, e.g. what files must be placed where, what environment variables must be set, what command line flags must be provided, etc.
  • Spin performs that type-based preparation.
  • Spin invokes the plugin.

Is that right? If so, it would be super useful (to me at least) to capture that flow.

User and internal DPs, then, have the exact same flow at the technical level, but differ in how Spin decides to launch them. E.g. a hypothetical AWS deployment plugin would be chosen explicitly by the command line user issuing spin deploy aws - Spin knows how to call deploy plugins but just blindly calls them by name. But trigger plugins are called implicitly based on the content of spin.toml, and that's what makes them internal. Is that right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, This is exactly the flow.

The type of plugin is inferred from the second component of the plugin name and it is a well-known string.

Comment thread docs/content/sips/xxx-spin-plugins.md Outdated
- Spin first provides all the functionality available in it required by the plugin and then proceeds to call the plugin along with the required parameters.

- **Spin Dependant Internal Plugins**
- These plugins cannot be directly invoked by the user as it is used by spin internally. Therefore, only spin invokes these.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what 'internal' means in this context? Are they built into the Spin binary? But then in what sense are they plugins? I'd find some clarification of the precise differences between the three execution models really useful - sorry if I'm being slow!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main point here for me is that we can extract e.g. the redis trigger into a separate spin-trigger-redis plugin and apart from needing to install that plugin nothing else changes.

Comment thread docs/content/sips/xxx-spin-plugins.md Outdated

## Future Considerations

- Updates with breaking changes.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure deferring this to "future considerations" is a wise move - would be good to have at least some sort of plan for it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There has been some discussion on this although more discussion is required on this. One of the potential solutions is for the plugins to specify the compatibility with various versions of spin and use that to verify before installing.


- Host components
- Loaders
- Config providers

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These examples are "internal plugins" right? This is a super useful list - it would be good to have this up top where you define the three categories.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, these are examples of spin-based internal plugins.

Signed-off-by: karthik Ganeshram <karthik.ganeshram@fermyon.com>
Signed-off-by: karthik Ganeshram <karthik.ganeshram@fermyon.com>
Comment thread docs/content/sips/xxx-spin-plugins.md Outdated

**Dealing with Breaking changes**

This is a section that still needs discussion. One of the solutions is for the plugin manifest to list the versions of spin that it is compatible with and use that to make an informed update of plugins avoiding updates to incompatible versions.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I worry about synchronicity issues here. When a new version of spin is released, then all plugins will need to update their compat lists. This means the plugin owner will have to stay fairly involved in the plugins repository. I wonder what other package managers do. I know SPEC files allow for requires syntax but it doesnt always have to give version and sometimes it can be an equality operator (requires: python >= 1.3): http://ftp.rpm.org/api/4.4.2.2/dependencies.html

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The semver crate supports version constraints: https://docs.rs/semver/1.0.13/semver/struct.VersionReq.html


```
{
"name": "test",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

according to above explaination on naming conventions, shouldnt this be prefixed with "spin" so spin-test

Comment thread docs/content/sips/xxx-spin-plugins.md Outdated

## Background

As the functionality fo spin gets extended, there will be a point where every feature will not be required/used by every user. An example of this would be different triggers for spin along with possible subcommands to add more functionality to spin. Therefore it would make sense to be able to add features as plugins allowing for addition of only the required features without modifying the spin binary.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: "of"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please capitalise Spin (and other proper nouns)?

Comment thread docs/content/sips/xxx-spin-plugins.md Outdated
│ └── Spin-Dependent User Plugins
└── Standalone Binary Plugins
```
**Standalone Binary Plugin** - These are just basic binaries that can add functionality to spin (eg) spin routes just displays the HTTP routes for a given application from spin.toml.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the word "basic" here necessary?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for the word "just".

Comment thread docs/content/sips/xxx-spin-plugins.md Outdated

**Spin-based User Plugins** - A made-up example of this would be spin deploy where the user invokes the command but as a plugin, it would require some functionality from spin. Therefore deploy is a type of command and it could have multiple plugins each of which deploys to different services.

**Spin-based Internal Plugins** - An example of this would be triggered, where the user does not directly call for the triggers but uses them by specifying them in the application manifest. Loaders would be another example of this.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"triggered"?

Signed-off-by: karthik Ganeshram <karthik.ganeshram@fermyon.com>

@fibonacci1729 fibonacci1729 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work Karthik! This is shaping up nicely and i'm looking forward to this feature!


For each `<type>`, a new Spin execution path will be created sharing the required features/functionality before calling the Spin plugin.

So once the Spin plugin is invoked using `spin $plugin`, the Spin binary does all the functions defined for that specific `<type>` before calling `spin-$plugin` with all the required environment variables set.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not quite clear to me what "the Spin binary does all the functions defined for that specific <type>" means here. I am correct to read this as: Spin will initialize a new execution environment implied by the plugin type and execute the plugin binary by invoking spin $plugin?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, That is correct.

kate-goldenring and others added 2 commits August 15, 2022 09:37
Signed-off-by: Kate Goldenring <kate.goldenring@fermyon.com>
Add JSON schema to spin plugins SIP
@kate-goldenring

Copy link
Copy Markdown
Contributor

Closing for revised version in #712

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

sip Improvement proposal: a design or architecture proposal for discussion and consensus

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants