Coder Social home page Coder Social logo

cli's Introduction

extism CLI

The Extism CLI can be used to generate or execute Extism plugins and manage libextism installations.

Installation

Using curl/sh:

curl https://get.extism.org/cli | sh

See the help output for more options:

curl https://get.extism.org/cli | sh -s -- -h

From source:

go install github.com/extism/cli/extism@latest

Using Nix:

nix-shell -p extism-cli

Manual

You can also download and extract the latest release from https://github.com/extism/cli/releases

Generate a Plugin

To quickly start writing an Extism plugin in any of the supported PDK languages, using extism CLI to generate minimal boilerplate may be helpful:

mkdir js-plugin && cd js-plugin
extism generate plugin 

  Select a PDK language to use for your plugin:  
                                                 
    1. Rust                                      
  > 2. JavaScript                                
    3. Go                                        
    4. Zig                                       
    5. C#                                        
    6. F#                                        
    7. C                                         
    8. Haskell                                   
    9. AssemblyScript                            
# or pass a path to the output via `-o`, see more options running `extism generate -h`

This will output a quickstart plugin project with the necessary configuration and dependencies ready. If no output directory was specified, the current directory will be used.

NOTE:: You may still need to install language tools such as compilers or other system dependencies to compile the plugin to WebAssembly.

To further improve this, we will eventually include a Dockerfile in each generated project, so a build environment can be easily created with all tools necessary. If you're interested in contributing to this effort, please join us on Discord, and check out the PDK template repository of interest, listed in pdk-templates.json

Call a plugin

The following will call the count_vowels function in the count_vowels.wasm module with the input "qwertyuiop":

PLUGIN_URL="https://github.com/extism/plugins/releases/latest/download/count_vowels.wasm"
extism call $PLUGIN_URL count_vowels --input qwertyuiop

Note: The first parameter to call can also be a path to a Wasm file on disk.

See extism call --help for a list of all the flags

Listing libextism versions

To list the available libextism versions:

extism lib versions

To list the available triples for a version:

extism lib versions v0.0.1-alpha

Install libextism

To install the latest version of libextism to /usr/local on macOS and Linux and . on Windows, this will overwrite any existing installation at the same path:

sudo PATH=$PATH env extism lib install

To install to $HOME/.local:

extism lib install --prefix ~/.local

To install the latest build from github:

sudo PATH=$PATH env extism lib install --version git

Uninstall libextism

To uninstall the shared object and header installed in /usr/local:

sudo PATH=$PATH env extism lib uninstall

Or from another prefix:

extism lib uninstall --prefix ~/.local

Check a libextism installation

The lib check command will print the version of the installed libextism library:

extism lib check

cli's People

Contributors

bhelx avatar g4vi avatar hellodword avatar mhmd-azeez avatar nilslice avatar wikiwong avatar zshipko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

cli's Issues

Can't find installation

I installed the cli via pip3, but I can't run it from zsh on Mac.

the bash script also fails on Mac.
~/.local/bin does not exist

Failed Install on MacOS

  • /user/local/bin directory doesn't exist by default on new MacOS installs
  • install fails when attempting to install in that non-existent directory when using defaults
  • final output line from installation script erroneously indicates install was successful
❯ curl https://get.extism.org/cli | sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  3695    0  3695    0     0  41266      0 --:--:-- --:--:-- --:--:-- 41055
Confirm installation:
  Version: v1.5.0
  OS: darwin
  Arch: arm64
  Sudo: /usr/bin/sudo
  Destination: /usr/local/bin/extism
  Build from source: n
Proceed? [y/N]:
y
Extracting release to /usr/local/bin/extism
Password:
sh: /usr/local/bin/extism: No such file or directory
chmod: /usr/local/bin/extism: No such file or directory
extism executable installed to /usr/local/bin/extism

~ took 15s
❯ ls /usr/local/bin/
ls: /usr/local/bin/: No such file or directory

idea: add an extism plug-in system

@bhelx brought up a great feature in the Discord and I'm logging it here for posterity.

Is there a way to load a plugin into the runtime and invoke a function from the command line? I could how it might be a bit too early for that. But it would be useful when testing plugins.

Though maybe a bit limited, it's possible to add functionality here so that someone could run:

extism --load plugin.wasm --input '{"a": true}' call "is_it_true"

# or from stdin

echo '{"a": true}' | extism --load plugin.wasm call "is_it_true"

to test out their plugin in development.

cli installation: better handling of sudo

Currently the installation invoke sudo if the user is not root and $out_prefix is not in $HOME. This heuristic has a lot of false positives, all of the failures I looked at http://matrix.cpantesters.org/?dist=Alien-libextism%20v0.1.1 appear to be the cli install script attempting sudo in a scenario where it shouldn't.

If we insist on installing with sudo, rather that attempting to detect when it's needed, we should try without, and on permission error retry with sudo.

However, instead I think we should make two changes:

  • Don't use sudo at all in the install script. I will use sudo or run it as root myself if I am going to install somewhere that I don't have write access to.

  • Install the cli to a $HOME directory by default. After installing the file on disk, to get it in $PATH, I prefer when it spits out instructions rather than appends to a dot file, as I know best how to handle my own dot files (I append to .profile on my systems for efficiency reasons, though it requires logging out and back in for it to take effect). This removes the need for root/sudo for the default install case. If we wanted to we could add a flag to get a system install that just sets the prefix to /usr/local/bin.

Generating a javascript plugin generates a typescript plugin

Running:

extism generate plugin --lang javascript -o myplug

Creates a typescript plugin. Running:

extism generate plugin --lang typescript -o myplug

Does nothing. I think we should throw an exception if the language isn't supported. Furthermore it might make sense to change the language name to typescript, or we can support both javascript and typescript as options.

explore routing stdout from shell

It appears that extism shell sub commands once run from within the shell swallow the log output. I took a cursory look through the shell source and it's not clear how we can combine the outputs.

Add Observe SDK support

Add observe SDK support to the CLI. It could just output the raw events to stdout or a file for now. We could perhaps look at deeper integration in the future. I left this task unrefined so feel free to imagine what this integration should look like.

`ash: extism: not found` on alpine linux

Working with a Discord user and it seems the install script is not working on alpine linux. They are on alpine x86, but i confirmed it doesn't seem to work on aarch64 either.

It downloads the extism binary and puts it in /usr/local/bin but it's not executable. Perhaps it's pulling down a binary for the libc linux platform?

Docker images broken

The docker images only provide the binary of the extism CLI, but that is not a standalone binary, it requires e.g. libc.

running ldd /extism on the linux/arm64 variant returns

        /lib/ld-linux-aarch64.so.1 (0x7ffffff5d000)
        libdl.so.2 => /lib/ld-linux-aarch64.so.1 (0x7ffffff5d000)
        libc.so.6 => /lib/ld-linux-aarch64.so.1 (0x7ffffff5d000)
        libpthread.so.0 => /lib/ld-linux-aarch64.so.1 (0x7ffffff5d000)

Any attempt to use the image will give the error message

exec /extism: no such file or directory

make git optional

Using git during the generate process assumes certain prerequisites, like having git installed and setting global user.name and user.email. However, I prefer not to set global git user.name and user.email, opting instead to set them per project, which results in an error during generation:

cli/generate.go

Line 145 in 0a713d1

if err := runCmdInDir(dir, "git", "commit", "-am", "init: extism"); err != nil {

Furthermore, based on the code, git is primarily used for cloning, which is not essential.

There's a submodule in https://github.com/extism/c-pdk-template

How about using go-git?

I'm trying to develop an extension system with this project. I aim to assume that the users creating extensions have as few relevant skills as possible, which is one reason why untrusted code is an issue, isn't it?

root@f616081b980c:/tmp# mkdir proj1
root@f616081b980c:/tmp# cd proj1/
root@f616081b980c:/tmp/proj1# git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint: 	git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint: 	git branch -m <name>
Initialized empty Git repository in /tmp/proj1/.git/
root@f616081b980c:/tmp/proj1# git config user.name "Your Name"
root@f616081b980c:/tmp/proj1# git config user.email "[email protected]"
root@f616081b980c:/tmp/proj1# git config -l
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
user.name=Your Name
[email protected]


root@f616081b980c:/tmp/proj1# extism -v gen plugin -l Go -o plugin
Cloning into 'plugin'...
remote: Enumerating objects: 9, done.
remote: Counting objects: 100% (9/9), done.
remote: Compressing objects: 100% (8/8), done.
Receiving objects: 100% (9/9), done.
remote: Total 9 (delta 0), reused 5 (delta 0), pack-reused 0
Switched to a new branch 'extism-init'
Author identity unknown

*** Please tell me who you are.

Run

  git config --global user.email "[email protected]"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got 'root@f616081b980c.(none)')
Error: exit status 128

Consider adding strict mode for the `call` subcommand

When calling a function with input arguments that does not expect any arguments, the function still executes. Would it be possible to add a strict mode that, when enabled, would panic instead of executing the plugin function?

Consider changing `--version` to be more specific

$ extism --version
extism version 1.0.0

I understand why it says this because the program itself is called extism but it might make more sense to override this and change it to something like extism-cli version 1.0.0. Because it could be confused that this is the lib version but they are in fact different things.

$  extism lib check
1.0.0

Error when running `extism call`

Hello, I get an error when I run:

extism call ./simple.wasm \
  say_hello --input "Bob" \
  --wasi

Error:

Traceback (most recent call last):
  File "/home/k33g/.local/bin/extism", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/k33g/.local/lib/python3.11/site-packages/extism_cli/__init__.py", line 598, in main
    plugin = libextism.Plugin(manifest, wasi=args.wasi, config=config)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/k33g/.local/lib/python3.11/site-packages/extism/extism.py", line 210, in __init__
    self.plugin = _lib.extism_plugin_new(
                  ^^^^^^^^^^^^^^^^^^^^^^^
TypeError: initializer for ctype 'ExtismContext *' must be a cdata pointer, not bytes

Traceback (most recent call last):
  File "/home/k33g/.local/bin/extism", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/home/k33g/.local/lib/python3.11/site-packages/extism_cli/__init__.py", line 598, in main
    plugin = libextism.Plugin(manifest, wasi=args.wasi, config=config)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/k33g/.local/lib/python3.11/site-packages/extism/extism.py", line 210, in __init__
    self.plugin = _lib.extism_plugin_new(
                  ^^^^^^^^^^^^^^^^^^^^^^^
TypeError: initializer for ctype 'ExtismContext *' must be a cdata pointer, not bytes

My plugin is very simple:

package main

import (
	"github.com/extism/go-pdk"
)

//export say_hello
func say_hello() int32 {

	input := pdk.Input()
	output := "👋 (From Go) Hello " + string(input)
	mem := pdk.AllocateString(output)
	pdk.OutputMemory(mem)
	return 0
}

func main() {}

Extism info:

Prefix  /usr/local
Version v0.5.0

Release new version

I recently fixed a bug in the go-sdk (extism/go-sdk#22) that prevents vars being persisted across multiple calls, so it would be great if we can release a new version of the CLI

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.