oeDeploy Plugin Development
1. Introduction to oeDeploy Plugins
oeDeploy plugins are components that provide automated deployment capabilities within the oeDeploy tool. They achieve automation by converting complex deployment processes into Ansible playbooks. A plugin may integrate multiple deployment actions (such as installation, uninstallation, and environment cleanup), each corresponding to one or more Ansible playbooks. All configurable parameters should be centralized to reduce both user learning costs and developer maintenance efforts.
2. Plugin Directory Structure
The plugin directory name, i.e., the plugin name, may include a version number (indicating the software version, not the plugin version).
The plugin directory contains the following:
| File/Directory | Type | Description |
|---|---|---|
| config.yaml | YAML | The only configuration file exposed to users. Contains host-related configurations (IP, password, key, port, etc.) and software deployment settings. |
| main.yaml | YAML | Contains plugin information such as name, version, description, and the specific steps for each deployment action (action). Each step corresponds to a script or playbook (relative to the workspace directory). |
| doc | Directory | Carries user documentation and other materials for the plugin. This directory is optional. |
| doc/readme.md | Markdown | User documentation for the plugin. The plugin store reads this file and displays it on the interface, making it the most direct entry for users to obtain plugin information. It is strongly recommended to write this document. |
| workspace | Directory | Carries all files, source code, binaries, scripts, playbooks, etc., used for software installation and deployment. The internal structure is not restricted. |
Naming constraints for plugin_name:
- The deployed software name is
name, and its version isversion. plugin_namemust follow one of these formats:{name}-{version}{name}-{version}-xxx
- Example: For a Kubernetes deployment plugin (version 1.31.1), valid names include
kubernetes-1.31.1,kubernetes-1.31.1-20240101, andkubernetes-1.31.1-offline-20240101.
3. main.yaml
The main.yaml file records key plugin information including: name, version, description, and action.
- When users run the
oedp infocommand,oedpreads and parses this file to display relevant information. - When users run the
oedp run xxxxcommand,oedpexecutes the corresponding automation scripts based on the content in theactionfield.
3.1 Format Description
typeindicates the plugin type, default value isapp. This is a reserved field and currently not effective.localhost_availableindicates whether local deployment is supported. It can betrueas long as it is not a "multi-node group deployment" scenario.- The
actionfield contains one or more operations. - Each operation's key is the operation name, the
descriptionitem is the introduction of the operation, andtaskscarries the specific steps (a list) required to execute the operation. When the operation is triggered by the user, each step will be executed in order. - Each step contains the following fields:
name: Step name, required field.playbook: Indicates usingansible-playbookto execute the corresponding script, the content is the path of the playbook (relative path based on theworkspacedirectory). Required field. Currently only theplaybookmode is supported.vars: The path of the configuration file read when the script is executed (relative path based on theworkspacedirectory). Optional field.scope: Limits the nodes that need to execute this step, i.e., the host group (defined inconfig.yaml). Required field, usually defaults toall.
- When the user executes the command line
oedp run <action>, theoedptool will execute all steps (tasks) under this operation one by one in order. - In
playbookmode, each step is equivalent to the following command line:
ansible-playbook <playbook>.yaml -i config.yaml -e @<vars>.yaml --limit <scope>3.2 Example
name: kubernetes-1.31.1 # Plugin name
version: 1.0.0 # Plugin version
description: install kubernetes 1.31.1 # Plugin description
description_zh: 帮助开发者在本地快速部署kubernetes-1.31.1的oeDeploy插件 # Chinese introduction
description_en: The oeDeploy plugin that helps developers quickly deploy kubernetes-1.31.1 locally. # English introduction
type: app # Reserved field, currently not effective
localhost_available: true # Whether local deployment is supported, can be true as long as it is not "multi-node group deployment"
action:
install: # Operation install
description: install kubernetes # Description of operation install
tasks:
- name: prepare for install # Step 1 of operation install
playbook: set-env.yaml # Playbook file executed in the current step (relative path based on workspace directory)
scope: all # Host group name executing the current step (defined in config.yaml)
- name: install kubernetes # Step 2 of operation install
playbook: init-k8s.yaml # Playbook file executed in the current step (relative path based on workspace directory)
vars: variables.yaml # Configuration file read in the current step (relative path based on workspace directory)
scope: all # Host group name executing the current step (defined in config.yaml)
delete:
description: delete kubernetes
tasks:
- name: delete kubernetes
playbook: delete-k8s.yaml
scope: all
clean:
description: clean cache files
tasks:
- name: clean cache files
playbook: clean-k8s.yaml
scope: all- In this example, when the user executes the
oedp run installcommand, the tool will execute the following commands in order:ansible-playbook set-env.yaml -i config.yaml --limit allansible-playbook init-k8s.yaml -i config.yaml -e @variables.yaml --limit all - Users can trigger corresponding operations via
oedp run install,oedp run delete,oedp run cleancommand lines.
4. config.yaml
The configurable parameters during the deployment script execution are all carried in the same configuration file config.yaml, reducing the learning cost for users and maintenance cost for developers.
config.yamlcontains node information (host groups) of the deployment environment, as well as parameter configurations related to software deployment.config.yamlfollows the configuration rules of Ansible inventory files, and the tool directly passes it as inventory when executing Ansible playbooks.- Note that
config.yamlis the only configuration file exposed to ordinary users. It should be aesthetically pleasing, avoid ambiguity, and retain as detailed comments as possible. Ansible-related parameters should be uniformly placed at the front or back of thevarsfield. - In
playbookmode, when the user triggers a deployment operation, the configuration inconfig.yamlis imported via the following command line:
ansible-playbook <playbook>.yaml -i config.yaml -e @<vars>.yaml --limit <scope>For relatively fixed configuration items that do not require user modification, they can be presented in
<vars>.yamlinstead ofconfig.yaml.
4.1 Example 1: Local Deployment
Except for a few cases that can only be deployed locally,
ansible_connection: localis generally not used.
all:
hosts:
localhost:
ansible_connection: local
vars:
deepseek_version: 8b
ollama_download_url:
amd64: https://repo.oepkgs.net/openEuler/rpm/openEuler-24.03-LTS/contrib/oedp/files/ollama-linux-amd64.tgz
arm64: https://repo.oepkgs.net/openEuler/rpm/openEuler-24.03-LTS/contrib/oedp/files/ollama-linux-arm64.tgz
ollama_download_path: /root/tmp # Target download path
modelfile_download: https://repo.oepkgs.net/openEuler/rpm/openEuler-24.03-LTS/contrib/oedp/files/DeepSeek-R1-Distill-Llama-8B-Q4_K_M.gguf
modelfile_download_path: /root/tmp # Target download path
# Model parameters
parameter:
temperature: 0.7
top_p: 0.7
top_k: 30
num_ctx: 4096
num_thread: 4 # Number of threads, recommended not to exceed CPU cores
num_gpu: 0 # Number of GPUs, 0 for none, -1 for all.
download_checksum: true # Whether to enable sha256sum verification
download_timeout: 600 # Timeout for downloading large files (seconds)
download_retry: 6 # Retry count for downloading large files
ansible_ssh_common_args: '-o StrictHostKeyChecking=no'4.2 Example 2: Single‑Node Deployment
all:
hosts:
host1:
ansible_host: 127.0.0.1 # Remote IP
ansible_port: 22 # Port
ansible_user: root # Username
ansible_password: "" # Password
vars:
ansible_ssh_common_args: '-o StrictHostKeyChecking=no'
kubectl_apply: pytorch-deployment.yaml
namespace: pytorch-namespace
replicas: 1
containers:
http:
name: http-container
image: hub.oepkgs.net/oedeploy/pytorch/pytorch:latest # amd64
workspace_mount: /tmp
service:
port: 8080
target_port: 8080
node_port: 30699
training:
epoch: 2 # Number of training epochs4.3 Example 3: Multi‑Node Deployment
all:
hosts:
host1:
ansible_host: 192.168.1.101
ansible_port: 22
ansible_user: root
ansible_password: ""
architecture: amd64 # e.g. [ amd64, arm64 ]
host2:
ansible_host: 192.168.1.102
ansible_port: 22
ansible_user: root
ansible_password: ""
architecture: amd64 # e.g. [ amd64, arm64 ]
vars:
version: 3.9.0
download_url: https://get.helm.sh/
temp_path: /tmp
install_path: /usr/local/bin
force_install: yes
ansible_ssh_common_args: '-o StrictHostKeyChecking=no'4.4 Example 4: Multi‑Node Group Deployment
all:
children:
masters:
hosts:
HOST1: # e.g. 192.168.10.1
ansible_host: 192.168.10.1 # e.g. 192.168.10.1
ansible_port: 22
ansible_user: root
ansible_password: ""
architecture: amd64 # e.g. [ amd64, arm64 ]
oeversion: 24.03-LTS # e.g. [ 22.03-LTS, 24.03-LTS ]
runtime: docker # e.g. [ docker, containerd ]
workers:
hosts:
HOST2:
ansible_host: 192.168.10.2
ansible_port: 22
ansible_user: root
ansible_password: ""
architecture: amd64
oeversion: 24.03-LTS
runtime: docker
HOST3:
ansible_host: 192.168.10.3
ansible_port: 22
ansible_user: root
ansible_password: ""
architecture: amd64
oeversion: 24.03-LTS
runtime: docker
new-workers: # The new-workers field cannot be deleted
hosts:
vars:
ansible_ssh_common_args: '-o StrictHostKeyChecking=no'
init_cluster_force: "true" # e.g. [ "true", "false" ] Force cluster initialization
remove_master_no_schedule_taints: "true"
service_cidr: 10.96.0.0/16 # Service network segment
pod_cidr: 10.244.0.0/16 # Pod IP network segment
certs_expired: 3650 # Certificate expiration time
# lb_kube_apiserver_ip:
lb_kube_apiserver_port: 8443
has_deployed_containerd: "false" # e.g. [ "true", "false" ] Whether containerd is already deployed
# The following parameters need to be consistent with host.ini during the build process, ignore if not involved
kubernetes_version: 1.31.1
calico_version: 3.28.2
pause_image: "registry.k8s.io/pause:3.10"5. workspace Directory
The workspace directory carries the main content of the deployment scripts, and its structure is not restricted.
- Various files, source code, binaries, scripts, playbooks involved in
main.yamlandconfig.yamlare all carried in theworkspacedirectory, and developers can customize subdirectories within it. - The
workspacedirectory is considered the root directory of the entire plugin execution process.
5.1 Example
Here is an oeDeploy plugin for deploying an nginx service.
main.yaml content:
name: nginx
version: 1.25.3
description: Install and configure nginx web server
action:
install:
description: Install nginx and start service
tasks:
- name: Install nginx via yum
playbook: install.yaml
scope: all
- name: Configure and start nginx
playbook: configure.yaml
scope: allconfig.yaml content:
all:
hosts:
target-host:
ansible_host: 127.0.0.1
ansible_port: 22
ansible_user: root # It is recommended to use the root user or a user with sudo privileges
ansible_password: ""
vars:
nginx_port: 80
ansible_ssh_common_args: "-o StrictHostKeyChecking=no"The workspace directory contains the following files:
install.yaml: Used to install nginx and other dependent softwareconfigure.yaml: Used to configure nginx parameters and start the nginx servicenginx.conf.j2: Serves as a template for configuring nginx parameters. Although not directly reflected inmain.yaml, it will be used inconfigure.yaml.
install.yaml content:
---
- hosts: all
become: yes
tasks:
- name: Install nginx
yum:
name: nginx
state: present
- name: Ensure nginx is running and enabled
service:
name: nginx
state: started
enabled: yesconfigure.yaml content:
---
- hosts: all
become: yes
tasks:
- name: Generate nginx configuration
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
- name: Validate nginx configuration
command: nginx -t
register: nginx_test
changed_when: false
notify: restart nginx
- name: Restart nginx
service:
name: nginx
state: restarted
when: nginx_test.rc == 0nginx.conf.j2 content:
worker_processes auto;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen {{ nginx_port }};
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}6. Plugin Packaging
To publish a plugin for other users, you need to package the plugin into {plugin_name}.tar.gz format. The compressed file name must match the plugin name, and extraction should produce only one directory. For example:
kubernetes-1.31.1.tar.gz
`-- kubernetes-1.31.1
|-- main.yaml
|-- config.yaml
`-- workspace/Usually, you can use the following command line to complete the packaging:
tar zcvf kubernetes-1.31.1.tar.gz kubernetes-1.31.1/7. Plugin Development Tips
- If the Ansible deployment operation requires sudo privileges (e.g., installing software packages), you need to add
become: yesat an appropriate position in the playbook script. If necessary, you can require only the root user password inconfig.yaml. - If the Ansible script involves file copying, modification, deletion, creation, etc., you must install the package
python3-libselinuxon the target node beforehand. Based on experience, this package is almost always necessary. - To avoid deployment interruption due to strict HostKey verification, it is recommended to add the configuration item
ansible_ssh_common_args: '-o StrictHostKeyChecking=no'in thevarsfield ofconfig.yaml. - When printing prompt messages with the
msgmodule, traditional line breaks will output\n, affecting readability. Therefore, you should use a string list form (as shown below).
- name: Print already installed message
debug:
msg:
- "========================================"
- "CANN Toolkit 开发套件包已经安装"
- "======================================="- If the value of a playbook configuration item is a string, be sure to enclose it in quotes. For example, the meanings of these two cases are different:
# config.yaml
vars:
sendfile: on # This may be interpreted as a boolean True
sendfile: "on" # This is the string "on"8. Performance Tuning Tips
- Enable SSH connection reuse to reduce the time delay of each operation, which significantly optimizes performance in environments with high SSH connection latency (generally not required, only used in performance‑sensitive scenarios). Add configuration items similar to the following in the
varsfield ofconfig.yaml:
# SSH connection reuse parameters: ControlMaster=auto enables connection reuse, ControlPersist=60s keeps the connection for 60 seconds, ConnectTimeout=30 sets connection timeout to 30 seconds
ansible_ssh_args: '-o ControlMaster=auto -o ControlPersist=60s -o ConnectTimeout=30'
# Enable Ansible pipelining acceleration to reduce SSH connection count
ansible_pipelining: True
# Enable SSH pipelining acceleration to improve file transfer efficiency
ansible_ssh_pipelining: True
# Set the number of parallel tasks
ansible_forks: 10- Add
gather_facts: falseat an appropriate position in the playbook script to turn off information collection before command execution (generally not recommended to modify, only used in performance‑sensitive scenarios). - Use the
synchronizemodule instead ofcopymodule, which requires pre‑installation of thersyncpackage (can avoid repeated copying, use as needed):
- name: install python3-libselinux and rsync
yum:
name:
- python3-libselinux
- rsync
state: present
- name: Sync prepare.sh to hosts using rsync
synchronize:
src: prepare.sh
dest: "{{ dir_path }}"
rsync_opts: "--chmod=755"