Ajenti¶
Ajenti is a highly extensible platform. The core of the platform provides HTTP server, Socket engine and Plugin container. The extensibility is implemented via a system of extension plugins.
The backend is written in Python (Ajenti Core). The frontend is written in Angular application hosted in the core plugin shell.
For more information about the architecture see the Architecture and how it works.
Feature Overview¶
HTTP Server¶
- HTTP 1.1 Support.
- Websockets with fallback to XHR polling.
- Fast event-loop based processing.
- Flexible routing.
- Session sandboxing.
- SSL with client certificate authentication.
Performance¶
- >1000 requests per second.
- 30 MB RAM footprint + 5 MB per session.
API¶
- Highly modular Python API. Everything is a module and can be removed or replaced.
- Builtin webserver API supports routing, file downloads, GZIP, websockets and more.
- Transparent SSL client authorization.
- Plugin architecture
- Dependency injection
- Server-side push and socket APIs.
Security¶
- Pluggable authentication and authorization.
- Stock authenticators: UNIX account, password, SSL client certificate and Mozilla Persona E-mail authentication.
- Unprivileged sessions isolated in separate processes.
- Fail2ban rule
Frontend¶
- Clean, modern and responsive UI. Single-page, no reloads.
- Live data updates and streaming with Socket.IO support.
- Full mobile and tablet support.
- LESS support.
- Numerous stock directives.
- Angular framework
Platforms¶
- Debian 9 or later
- Ubuntu Bionic or later
- RHEL 8 or later
- Can be run on other Linux or BSD systems with minimal modifications.
- Supports Python 3.5+.
Installing¶
Caution
Supported operating systems:
- Debian 9 or later
- Ubuntu Bionic or later
- RHEL 8 or later
Other Linux-based systems might work, but you’ll have to use manual installation method.
Automatic Installation¶
curl https://raw.githubusercontent.com/ajenti/ajenti/master/scripts/install.sh | sudo bash -s -
Automatic Installation in virtual environment¶
Caution
Please note that this install method is still under tests. Ajenti starts successfully on the previously mentioned supported operating systems, but all functionalities were not tested. Be kind to report any problem with this install method as issue here : https://github.com/ajenti/ajenti/issues
curl https://raw.githubusercontent.com/ajenti/ajenti/master/scripts/install-venv.sh | sudo bash -s -
Manual Installation¶
Native dependencies: Debian/Ubuntu¶
Enable Universe repository (Ubuntu only):
sudo add-apt-repository universe
sudo apt-get install build-essential python3-pip python3-dev python3-lxml libssl-dev python3-dbus python3-augeas python3-apt ntpdate
Native dependencies: RHEL¶
Enable EPEL repository:
sudo dnf install epel-release
sudo dnf install -y gcc python3-devel python3-pip python3-pillow python3-augeas python3-dbus chrony openssl-devel redhat-lsb-core
Install Ajenti 2¶
Upgrade PIP:
sudo pip3 install setuptools pip wheel -U
Minimal install:
sudo pip3 install ajenti-panel ajenti.plugin.core ajenti.plugin.dashboard ajenti.plugin.settings ajenti.plugin.plugins
With all plugins:
sudo pip3 install ajenti-panel ajenti.plugin.ace ajenti.plugin.augeas ajenti.plugin.auth-users ajenti.plugin.core ajenti.plugin.dashboard ajenti.plugin.datetime ajenti.plugin.filemanager ajenti.plugin.filesystem ajenti.plugin.network ajenti.plugin.notepad ajenti.plugin.packages ajenti.plugin.passwd ajenti.plugin.plugins ajenti.plugin.power ajenti.plugin.services ajenti.plugin.settings ajenti.plugin.terminal
Uninstall Ajenti 2¶
Ajenti is a collection of Python modules installed with pip, delivered with an init script ( systemd or sysvinit ). So it’s necessary to remove the init script, then the Python librairies, and the configurations files.
Systemd¶
sudo systemctl stop ajenti.service
sudo systemctl disable ajenti.service
sudo systemctl daemon-reload
sudo rm -f /lib/systemd/system/ajenti.service
SysVinit¶
/etc/init.d/ajenti stop
rm -f /etc/init/ajenti.conf
Python3 modules¶
List all modules from Ajenti:
sudo pip3 list | grep aj
The result should be something like ( eventually more or less plugins ):
aj 2.1.43
ajenti-panel 2.1.43
ajenti.plugin.ace 0.30
ajenti.plugin.auth-users 0.31
ajenti.plugin.core 0.99
ajenti.plugin.dashboard 0.39
ajenti.plugin.filesystem 0.47
ajenti.plugin.passwd 0.24
ajenti.plugin.plugins 0.47
ajenti.plugin.session-list 0.4
ajenti.plugin.settings 0.30
Then simply remove all these modules:
sudo pip3 uninstall -y aj ajenti-panel ajenti.plugin.ace ajenti.plugin.auth-users ajenti.plugin.core ajenti.plugin.dashboard ajenti.plugin.filesystem ajenti.plugin.passwd ajenti.plugin.plugins ajenti.plugin.session-list ajenti.plugin.settings
Configuration files¶
If you don’t need it for later, just delete the directory /etc/ajenti/:
sudo rm -rf /etc/ajenti/
Running Ajenti¶
Starting service¶
The automatic install script provides binary ajenti-panel and initscript/job/unit ajenti. You can ensure the service is running:
service ajenti restart
or:
/etc/init.d/ajenti restart
or:
systemctl restart ajenti
The panel will be available on HTTPS port 8000 by default. The default username is root, and the password is your system’s root password.
Ajenti can also be run in a verbose debug mode:
ajenti-panel -v
Commandline options¶
-c
,--config <file>
- Use given config file instead of default-v
- Debug/verbose logging--log <level>
- Fix log level : debug, info, warning or error--dev
- Enables automatic resources build on each request-d, --daemon
- Run in background (daemon mode)--stock-plugins
- Run with provided plugins (default if option--plugins
is not used)--plugins <dir>
- Run with additional plugins--autologin
- Will automatically log in the user under which the panel runs. This is a security issue if your system is public.
Debugging¶
If Ajenti does not start as intended, there are various ways to debug this, but it is good to know that the problem can have an origin in Python code or in Javascript code.
Debug Python problems¶
First of all, have a look at:
/var/log/ajenti/ajenti.log
It may contain some running errors which could be useful to understand the problem.
The traceback of a total crash would be stored in:
/var/log/ajenti/crash-DATE.log
If this log files do not provide enough informations, you can manually start Ajenti in debug mode as root:
systemctl stop ajenti
/usr/local/bin/ajenti-panel -v
This will increase the verbosity of Ajenti in /var/log/ajenti/ajenti.log
, but you can also directly follow the progress of Ajenti start with:
systemctl stop ajenti
/usr/local/bin/ajenti-panel --dev
and then stop it as usual with Ctrl + C. Don’t forget after this to restart the Ajenti process if necessary:
systemctl start ajenti
Debug Javascript problems¶
The best way to do it is to launch the developer tools in your browser, usually with F12, and to look if some errors are shown.
Submit the errors¶
The best way to help the development of Ajenti is then to submit the errors at https://github.com/ajenti/ajenti/issues/new with all informations ( traceback, OS, Python version, … ).
Configuration files¶
All the configuration files are store in /etc/ajenti
:
- config.yml: the main configuration file with all important parameters,
- smtp.yml: credentials to an email server relay, if you want to use some mail notifications or reset password functionality,
- users.yml: the default file which contains user account for the user authentication provider.
All configuration files use the yaml format
config.yml in details¶
Ajenti will use the following parameters :
auth block¶
auth:
allow_sudo: true
emails: {}
provider: os
users_file: /etc/ajenti/users.yml
Explanations:
- allow_sudo: true or false (allow users in the sudo group to elevate)
- emails: {} (not currently used)
- provider: authentication method to use, os (users from the os) or users
- users_file: if the users authentication provider is used, path to the users file (default /etc/ajenti/users.yml)
The parameter user_config was used to specified where the user configuration was stored, but is now deprecated, since it’s bound to the provider (os or users) to avoid duplicates entries.
bind block¶
bind:
host: 0.0.0.0
mode: tcp
port: 8000
Explanations:
- host: ip on which to listen (default 0.0.0.0)
- mode: type of socket, tcp or unix
- port: port on which to listen, default 8000
ssl block¶
ssl:
enable: true
certificate: /etc/ajenti/mycert.pem
fqdn_certificate: /etc/letsencrypt/ajenti.pem
force: false
client_auth:
enable: true
force: true
certificates:
digest: 15:E8:5E:E5:D2:E8:75:0D:53:FF:22:A8:79:28:E5:BE:33:E0:37:07:FB:31:47:4D:61:69:AB:43:F8:5B:23:78
name: C=NA,ST=NA,O=sajenti.mydomain.com,CN=root@ajenti.mydomain.com
serial: 352674123960898230347891590646542168839110009016
user: root
Explanations:
- enable: true or false to provide support for https. It’s highly recommended to set it to true
- certificate: full path to default global certificate, used to generate client certificates, and fot the https protocol, if the parameter
fqdn_certificate
is not set. The PEM file should contains the certificate itself, and the private key.- fqdn_certificate: full path certificate for your FQDN (e.g.
/etc/ajenti/mycert.pem
). The PEM file should contains the certificate itself, and the private key.- force: spawn a small listener on port 80 to enable a redirect from
http://hostname
tohttps://hostname:port
.
- client_auth:
- enable: true or false to enable client authentication via certificates
- force: if true, only allows login with client certificate. If false, also permit authentication with password
- certificates: this entry contains all client certifcates for an automatic login. It will be filled through the settings in Ajenti with the following structure:
- digest: digest of the certificate
- name: name of the certificate
- serial: serial of the certificate
- user: username
email block¶
email:
enable: true
templates:
reset_email : /etc/ajenti/email/mytemplate_for_reset_password.html
Explanations:
- enable: true or false, if you want to enable the password reset function. But for this you need to set the smtp credentials in
/etc/ajenti/smtp.yml
- templates: * reset_email: full path to template email for reset password functionality
The default template used to reset email password is located here. The variables are automatically filled with jinja2.
Other global parameters¶
color: blue
language: en
logo: /srv/dev/ajenti/ajenti-panel/aj/static/images/Logo.png
max_sessions: 10
name: ajenti.mydomain.com
restricted_user: nobody
session_max_time: 1200
Explanations:
- color: secundary color of the CSS theme (possibles values are default, bluegrey, red, deeporange, orange, green, teal, blue and purple)
- language: language prefence for all users, default en
- logo: full path to your own logo, default is the one from Ajenti
- max_sessions: max number of simultaneously sessions, default is 99. If the max is reached, the older inactive session will be deactivated
- name: your domain name
- restricted_user: user to use for the restricted functionalities, like for the login page. It’s an important security parameter in order to limit the actions in restricted environments : all actions in restricted environments will be done with this user’s privileges. Default is nobody.
- session_max_time: max validity time in seconds before automatic logout. Default is 3600 (one hour).
- trusted_domains ( Ajenti >= 2.2.1 ) : comma separated list of trusted domains under which it’s possible to reach your Ajenti server. When the HTTP headers are tested, a valid origin will be considered as one of the domains listed. It’s necessary to specify the protocol. It’s mean that an entry should look like http://my.domain.com.
- trusted_proxies ( Ajenti >= 2.2.1 ) : comma separated list of trusted proxies. This is actually used in order to get the real ip of the client.
smtp.yml in details¶
This file contains all the credentials of an email server which can be used as email relay to send some notifications, like an email to reset a forgotten password.
smtp:
password: MyVeryStrongStrongPassword
port: starttls
server: mail.mydomain.com
user: mail@mydomain.com
Explanations:
- port: starttls (will use 587) or ssl (will use 465)
- server: server hostname, like
mail.mydomain.com
- user: user to authenticate
- password: password of the mail user
users.yml in details¶
Ajenti gives the possibility to use two authentication methods : os or users. If users is used, all user informations are stored in users_file. It’s automatically filled with the user plugin.
The default path for the users_file is /etc/ajenti/users.yml
with following structure:
users:
arnaud:
email: arnaud@mydomain.com
fs_root: /home/arnaud
password: 73637279707.....
permissions:
packages:install: false
sidebar:view:/view/cron: false
uid: 1002
Explanations:
- password: hash of the password
- permissions: list of permissions of the user
- uid: related os uid to run the worker on
- fs_root: root directory
- email: email to use for password reset.
Securing¶
Fail2ban¶
Failed login attempts are logged in /var/log/ajenti/ajenti.log. A basic filter for Fail2ban is available here : https://raw.githubusercontent.com/ajenti/ajenti/master/scripts/ajenti.conf
You can enable it by copying it in /etc/fail2ban/filter.d/ajenti.conf and with the following lines in /etc/fail2ban/jail.d/ajenti :
[ajenti]
enabled = true
port = 8000
bantime = 120
maxretry = 3
findtime = 60
logpath = /var/log/ajenti/ajenti.log
filter = ajenti
This is only an example : after 3 failed attempts ( maxretry ) the last 60 seconds ( findtime ), the found ip will be banned 2 minutes ( bantime ). You can naturally set other values related to your configuration.
Contributing to Ajenti¶
Translations¶
All translations are stored by Crowdin, and any help is welcome. It’s possible to translate directly all strings in the great interface of Crowdin and then we can include and compile it into the next release:
Testing¶
It’s always good to have some users feedback, because we may oversee some problems. If you find an issue, please post it on GitHub with a complete description of the problem, and we will try to solve it and improve Ajenti.
Developping¶
- There’s two main axes to develop Ajenti :
- Extension plugins: like e.g. a plugin to manage the fstab file,
- Core: improve Ajenti on server side.
Plugin check_certificates¶
You can see with one look if your SSL certificates are still valid or not.

The list view let you see the hostname,the port, the issuer of the certificate, the end of the certificate, and the status of the connection.
It’s pretty easy to add or to remove an hostname. By default, a test will be done on port 443, the standart one for HTTPS
.
But you can naturally specify something else, like 8000 or 587.
If the port 587 is specified, Ajenti
will try to open a STARTTLS
connection, e.g. for email server.

Plugin core¶
The main plugin of Ajenti
is the core plugin.

This plugin manages:
- the authentication process,
- user environment setup,
- session management,
- the way the resources are delivered (CSS, JS, etc … ),
- the main template and the main style of
Ajenti
,- the entries in the sidebar,
- error handling,
- password reset,
- configurations (
Ajenti
, user config).

It delivers a lot of tools, services, components for the other plugins too:
- hotkeys,
- tasks,
- pushs,
- dialogs,
- progress spinner,
- navbox,
- messagebox,
- smartprogerss,
- customization,
- translations with gettext,
- notifications,
- socketio.
Plugin cron¶
This plugin allows to handle all entries in a personal cron
file.

This is quite equivalent as running crontab -l -u USER
to manage your own cronjobs.
With this plugin, you can:
- add jobs,
- remove jobs,
- edit jobs,
- edit special entries ( @yearly, etc … ),
- set environment variables,
- add comments.

Plugin dashboard¶
This is the default landing page after successfully authenticate.

It’s possible to display the widgets of your choice, and to order them as you want with a simple drag&drop.
You can also add other tabs, and rename them the way you want.
The list of actual available widgets:
- Check certificates,
- CPU Usage,
- Disk space (you can choose the mount point),
- Hostname,
- Load average,
- Memory usage,
- Power state,
- Script (run your own command),
- Service (status of a service in systemd or sysv init),
- Sessions (logged in users),
- Traffic,
- Uptime.
Plugin datetime¶
This plugin displays the current time zone used, and time and date set on the server.

It’s possible to:
- change the time zone used,
- set the time on the server,
- synchronize time using
NTP
(packagentpdate
is for this necessary).
Plugin docker¶
This plugin allows to show all running containers and images from a locally docker instance.

The default tab shows all containers, with their names and id, and you can:
- start/stop a container,
- remove a container,
- see memory usage, cpu usage and network I/O
On the second tab, you will see the stored images with their sizes.
You can easily choose which one you want to delete.

Plugin filemanager¶
This plugin let you navigate on the server filesystem and perform all common operations on files and directories.

Currently, it’s possible to:
- create new files, new directories,
- upload a file through drag&drop,
- navigate in many tabs,
- cut, copy, delete files and directories (you must first select at least one object),
- display the properties of an object,
- easily navigate between directory with the breadcrumb.

In the properties view you will see all common informations (permissions, last change date, owner, etc … the same as the command stat
).
If the file is plain text, a button Edit in Notepad
will appear and let you modify the file.
You can also change the permissions of the file:

Plugin fstab¶
The first tab shows the output of the mount
command with some util informations like:
- filesystem type,
- mountpoint,
- used space,
- total size.
The button on the right let you unmount the desired device, but you should use it with caution (don’t try to unmount the root fs!).

The second tab lists all entries in /etc/fstab
and let you add/modify or delete the entries.
But you should also be careful here with what you are doing.

Plugin network¶
This plugin contains the utilities to show the most important informations about your network interfaces.

Tab network¶
You will see all network interfaces, their IP and status. It’s possible to bring an interface up or down and change some of their properties (not yet implemented for systems running with netplan
).
It’s also possible to update the hostname name.
Tab DNS¶
This tab enable DNS management (add or delete DNS server).
Tab Hosts¶
Lists all entries in the file /etc/hosts
, and modify or delete any single of them.
Plugin notepad¶
Based on the ACE editor, you can:
- edit all plain text files,
- create a new file,
- save an existing file in another location,
- manage all of these files with tabs.
Hotkey:
- Ctrl + O : open file
- Ctrl + N : new file
- Ctrl + S : save file

Plugin packages¶
In order to manage the packages installed on your server, the plugin packages
provides a quick search to filter the packages matching the search query.
Actually, the supported package engines are APT
and PIP
.
It’s necessary to enter at least 3 chars in the search to automatically get a packages list, and then perform usual operations:
- see if a package is installed,
- see the version,
- see if a newer version is available,
- install/update a package,
- remove a package.

Plugin plugins¶
Ajenti
is pretty flexible and allow anyone to write its own plugin (backend Python
and frontend AngularJS
).
In order to manage all plugins and their versions, the plugin plugins
lists all available plugins, shows if they are installed, or if an update if published.
The main plugin core
can not be uninstalled, because Ajenti
can not run without it, but you can check whenever a new version is available.
Updating or removing a plugin is this way pretty easy.

Plugin power¶
Basically handle all around power management on your server.
Uptime appears, and you can also reboot or shutdown the server if needed.

Plugin services¶
The plugin services
shows the status of services in systemd
or in system V init
.

For the systemd
unit services, you can:
- start/stop/restart the service,
- enable/disable the service, if not static.
For the system V init
services, you can:
- start/stop/restart the service,
- kill a running service.
Plugin settings¶
This page gives access to the settings stored in /etc/ajenti/config.yml
and /etc/ajenti/smtp.yml
.
For a full description of the configuration files, please see Configuration files.
After changing the settings, it’s necessary to restart the panel.
Tab General¶

This tab contains the binding settings, language, hostname set in Ajenti
et color style.
Tab Security¶

You can choose:
- the authentication provider (OS or USERS),
- allow sudo elevation or not,
- set the timeout of a session,
- configure SSL and certificates,
- configure SSL and certificates for client authentication.
Plugin terminal¶
It would be really cool to have an terminal access on the server. That’s exactly what this plugin does!
You have the possibility to launch a command (and naturally see the result) or to open a whole terminal on the server. You will get the same environment as your user on the system.
Type exit or Ctrl + D to come back to the terminal list.
Plugin users¶
The default authentication provider used in Ajenti
is the OS provider which allows all users of the system to log in.
The plugin auth_users
provides an alternative way to authenticate users, and to create custom users. All users data are stored in plain text, in /etc/ajenti/users.yml
(but this is configurable).

The default view presents a list of current users and let you:
- add a new user,
- manage the properties of an existing user,
- delete an existing user.

The property modal window displays some utilities per account:
- system account: all user accounts must be bound to a system account in order to set the privileges. An user bound to
root
wil have all privileges, but an user bound to a system user account likearnaud
will only have the privileges of the system userarnaud
.- password change: only a hash is stored, not the password itself,
- set the email: for notifications or password reset function,
- select the sidebar entries and permissions of the user.
Don’t forget to SAVE the changes when updating an user.
Architecture and how it works¶
Backend¶
Ajenti project itself consists of Ajenti Core and a set of stock plugins forming the Ajenti Panel.
Ajenti Core¶
Represents the core backend and it’s the entry point of Ajenti.
- HTTP server
- IoC container
- Base classes and Interfaces
- Simplistic web framework
- Set of core components aiding in client-server communications
Ajenti Panel¶
- Startup script
- Plugins developed for the Ajenti Core (
filemanager
,terminal
,notepad
, etc.)
Modus operandi¶
During bootstrap, Ajenti Core will locate and load Python modules containing Ajenti plugins (identified by a plugin.yml
file). It will then register the implementation classes found in them in the root IoC container. Some interfaces to be implemented include aj.api.http.HttpPlugin
, aj.plugins.core.api.sidebar.SidebarItemProvider
.
Ajenti Core runs a HTTP server on a specified port, managing a pool of isolated session workers and forwarding requests to these workers, delivering them to the relevant aj.api.http.HttpPlugin
instances. It also supports Socket.IO connections, forwarding them to the relevant aj.api.http.SocketEndpoint
instances.
Ajenti contains a mechanism for session authentication through PAM login and sudo
elevation. Standard core
plugin provides HTTP API for that.
Authenticated sessions are moved to isolated worker processes running under the corresponding account.
Frontend¶

- The frontend can be divided into two main parts:
- core part (plugin
shell
andngx-ajenti
) - extension plugins (
ace
,dashboard
,filemanager
,.. )
- core part (plugin
Screenshot
shell (plugin)¶
Serves as a container for other plugins. Plugins are implemented as micro-frontends and are loaded within the shell. It uses @angular-architects/module-federation package of Angular Architects. For deep dive into Webpack 5’s module federation usage with Angular see the link.
- Basic navigation (Header, Siderbar, Routing,.. )
- Container for other plugins
- Config management
ngx-ajenti (plugin)¶
Represents the shared library.
- Authentication and Identity management
- Global (TS) services and components
- Navigation (Header, Siderbar, Routing,.. )
- Config management
- Plugin manager
Ajenti Dev Multitool¶
sudo pip install ajenti-dev-multitool
ajenti-dev-multitool
is a mini-utility to help you with common plugin development tasks.
ajenti-dev-multitool
typically operates on all plugins found in current directory and below.
--run
will launch the globally installed Ajenti with plugins from the current directory.--run-dev
will additionally enable developer mode.--build-frontend
builds the frontend resources.--setuppy "<setup.py-command-with-args>"
runs a setuptools command on the plugin package. Asetup.py
file is generated automatically. Example:ajenti-dev-multitool --setuppy 'sdist upload --sign --identity "John Doe"'
User Interface¶
Basics¶
Ajenti frontend is a Angular based single-page rich web application.
Your plugins can extend it by adding new Angular components and routes.
Client-server communication is facilitated by AJAX requests to backend API (HttpClient
) and a Socket.IO connection (socket
and push
Angular services).
Client styling is based on a customized Bootstrap build.
Example¶
Warning
This part is obsolete. The demo-plugins repo must be converted from AngularJS to Angular.
Basic UI example can be browsed and downloaded at https://github.com/ajenti/demo-plugins/tree/master/demo_2_ui
The basic UI plugin includes:
- an AngularJS module containing a route and a controller:
- an AngularJS view template (HTML)
Handling HTTP Requests¶
This page describes how to handle HTTP request on the backend side.
Example¶
Basic HTTP API example can be browsed and downloaded at https://github.com/ajenti/demo-plugins/tree/master/demo_4_http
Plugins can provide their own HTTP endpoints by extending the aj.api.http.HttpPlugin
abstract class.
Example:
import time
from jadi import component
from aj.api.http import get, HttpPlugin
from aj.api.endpoint import endpoint, EndpointError, EndpointReturn
@component(HttpPlugin)
class Handler(HttpPlugin):
def __init__(self, context):
self.context = context
@get(r'/api/demo4/calculate/(?P<operation>\w+)/(?P<a>\d+)/(?P<b>\d+)')
@endpoint(api=True)
def handle_api_calculate(self, http_context, operation=None, a=None, b=None):
start_time = time.time()
try:
if operation == 'add':
result = int(a) + int(b)
elif operation == 'divide':
result = int(a) / int(b)
else:
raise EndpointReturn(404)
except ZeroDivisionError:
raise EndpointError('Division by zero')
return {
'value': result,
'time': time.time() - start_time
}
@endpoint(api=True)
mode provides automatic JSON encoding of the responses and error handling.
If you need lower-level access to the HTTP response, use @endpoint(page=True)
:
@get(r'/api/test')
@endpoint(page=True)
def handle_api_calculate(self, http_context):
http_context.add_header('Content-Type', '...')
content = "Hello!"
#return http_context.respond_not_found()
#return http_context.respond_forbidden()
#return http_context.file('/some/path')
http_context.respond_ok()
return content
See aj.http.HttpContext
for the available http_context
methods.
Dashboard Widgets¶
The dashboard (plugin) provides a way how to extend dashboard with some extra widgets. This is done by implementing a new module containing the new widget(s).
Example of a Traffic widget (located in the traffic
module)

Example implementation¶
- Elements to be implemented
- Backend: Widget class
- Backend: Widget config endpoint (Optional)
- Frontend: WidgetComponent
- Frontend: Widget config component (Optional)
Backend: Widget class¶
This class must implement the aj.plugins.dashboard.widget
. It’s used for the registration in the backend and as a provider for the widget data.
Dashboard will issue periodic requests to your aj.plugins.dashboard.api.Widget
implementations.
If user creates multiple widgets of same type, a single instance will be created to service their requests.
Example widget class:
@component(Widget)
class TrafficWidget(Widget):
id = 'traffic'
name = _('Traffic')
..
def get_value(self, config):
...
return { .. }
Backend: Widget config endpoint (Optional)¶
This is required only if the widget is configurable.
The endpoint is implemented as a handler from the HttpPlugin
The decorator @url
will register the endpoint in the backend.:
@component(HttpPlugin)
class Handler(HttpPlugin):
..
@url(r'/api/traffic/interfaces')
@endpoint(api=True)
def handle_api_interfaces(self, http_context):
..
return ..
Frontend: WidgetComponent¶
This is the actual UI shown to the user. It’s implemented as a Angular component.
This component must be exposed in the webpack.config.js
as part of the ModuleFederationPlugin.
Widget component implementation: https://github.com/ajenti/demo-plugins/tree/master/demo_5_widget/frontend/components/demowidget/
Webpack registration: https://github.com/ajenti/demo-plugins/tree/master/demo_5_widget//frontend/webpack.config.js#L35
Extension plugins¶
This page describes the way how to setup the development environment for the development of extension plugins.
Required knowledge¶
- Python 3, Typescript, Angular, HTML
Steps¶
- Setup Ajenti (core)
- Install build tools
- Setup plugin environment
1. Setup Ajenti (core)¶
The Ajenti (core) is required for the development and run of any plugin. There are two development scenarios:
Develop only an extension plugin
Install the Ajenti(Core): Installation guide
Develop an extension plugin + Ajenti(core) and the same time
Run the Ajenti(Core) in the development mode Core
2. Install build tools¶
Follow the steps in Build tools
4. Plugin development¶
4.1 Edit existing plugin¶
See the plugins-new/Readme.txt
4.2 Create a new plugin¶
Create a new plugin in the current directory:
ajenti-dev-multitool --new-plugin "Some plugin name"
Build frontend:
ajenti-dev-multitool --build-frontend
Start start the backend:
#If Ajenti(core) was installed
sudo ajenti-dev-multitool --run-dev
#Navigate to http://localhost:8000/
#If Ajenti(core) is running in the dev mode:
make rundev
See the plugins-new/Readme.txt to see how to start the frontend
What’s inside a plugin?¶
- Backend: Python modules, which contain
jadi.component
classes (components). - Frontend (optional): Angular components, services and LESS files.
Example plugin structure:
some_plugin_name
├── backend/
│ ├── controllers
│ │ └── dashboard.py
│ ├── __init__.py
│ └── requirements.txt
│
├── frontend/
│ ├── e2e/
│ └── src/
│ ├── components
│ │ └── uptime-widget.component.html
│ │ └── uptime-widget.component.less
│ │ └── uptime-widget.component.ts
│ ├── services
│ │ └── dashboard.service.ts
│ └── dashboard.module.ts
│
├── locale/
├── plugin.yml #plugin description
└── README.md
Example plugins¶
See the demo-plugins git repo for some example plugin implementations.
Warning
This part is obsolete. The demo-plugins repo must be converted from AngularJS to Angular.
Download plugins from here: https://github.com/ajenti/demo-plugins or clone this entire repository.
Prep work:
ajenti-dev-multitool --build-frontend
Run:
ajenti-dev-multitool --run-dev
Core¶
This page describes the way how to setup the development environment for the development of the core.
Attention
For plugin/extension development see Extension plugins
Required knowledge¶
- Python 3.x, async programming with gevent, HTML, Angular, Typescript, LESS
Prerequisites¶
Minimal set of software required to build and run Ajenti: git
, Node.js
Debian/Ubuntu extras: python3-dbus (ubuntu)
Automatic Installation (Backend + Frontend)¶
The following script will perform a complete automatic installation under Debian or Ubuntu, using virtual environment with Python. The virtual environment is then located in /opt/ajenti and the cloned git repository in /opt/ajenti/ajenti. This install script will install a lot of dependencies, this may take several minutes.
curl https://raw.githubusercontent.com/ajenti/ajenti/master/scripts/install-dev.sh | sudo bash -s -
After a successful installation, do the following to activate the dev mode:
- Activate the virtual environment : source /opt/ajenti/bin/activate
- Navigate in the git repository : cd /opt/ajenti/ajenti
- Launch a rundev recipe : make rundev ( quit with Ctrl+ C )
- Call https://localhost:8000 in your browser ( you will get some warnings because of the self-signed certificate, it’s perfectly normal.
Manual installation - Backend¶
Download the source code:
git clone git://github.com/ajenti/ajenti.git
Install the dependencies:
# Debian/Ubuntu
sudo apt-get install build-essential python3-pip python3-dev python3-lxml libffi-dev libssl-dev libjpeg-dev libpng-dev uuid-dev python3-dbus
# RHEL
sudo dnf install gcc python3-devel python3-pip libxslt-devel libxml2-devel libffi-devel openssl-devel libjpeg-turbo-devel libpng-devel dbus-python
cd ajenti
sudo pip3 install -r ajenti-core/requirements.txt
sudo pip3 install ajenti-dev-multitool
Install the build tools
Follow: Build tools
Ensure that resource compilation is set up correctly and works (optional):
make build
Launch Ajenti backend in dev mode:
make rundev
Navigate to http://localhost:8000/.
Hint
Additional debug information will be available in the console output and browser console.
Reloading the page with Ctrl-F5 (Cache-Control: no-cache
) will unconditionally rebuild all resources
Manual installation - Frontend¶
The setup the core frontend is needed to build and run the plugins: ngx-ajenti
and shell
The way how to do it is described here in the plugins-new/README.md See the Readme https://github.com/daniel-schulz/netzint-ajenti/blob/dev/plugins-new/README.md
For more info see What’s Ajenti and how it works.
Build tools¶
This setup is required for the development of the Core and the Extension plugins.
Steps¶
Install Curl:
sudo apt install curl
Install NodeJS - you can use the NodeSource repositories for quick setup:
# Using Ubuntu
curl -sL https://deb.nodesource.com/setup_17.x | sudo -E bash -
sudo apt-get install -y nodejs
# Using Debian, as root
curl -sL https://deb.nodesource.com/setup_17.x | bash -
apt-get install -y nodejs
# Using RHEL or centos, as root
curl -sL https://rpm.nodesource.com/setup_17.x | bash -
Install Yarn - Enable the official Yarn repository, import the repository GPG key, and install the package.:
# Using Ubuntu
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update
sudo apt install --no-install-recommends yarn
Install Angular CLI:
sudo yarn global add @angular/cli
Install Gettext:
# Ubuntu or Debian:
sudo apt-get install gettext
# RHEL or CentOS
dnf install gettext
Install Ajenti Dev Multitool:
pip3 install ajenti-dev-multitool
(More info about the Ajenti Dev Multitool)
API: jadi¶
-
jadi.
interface
(cls)[source]¶ Marks the decorated class as an abstract interface.
Injects following classmethods:
-
.
all
(context)¶ Returns a list of instances of each component in the
context
implementing this@interface
Parameters: context ( Context
) – context to look inReturns: list( cls
)
-
.
any
(context)¶ Returns the first suitable instance implementing this
@interface
or raisesNoImplementationError
if none is available.Parameters: context ( Context
) – context to look inReturns: cls
-
.
classes
()¶ Returns a list of classes implementing this
@interface
Returns: list(class)
-
-
jadi.
component
(iface)[source]¶ Marks the decorated class as a component implementing the given
iface
Parameters: iface ( interface()
) – the interface to implement
-
jadi.
service
(cls)[source]¶ Marks the decorated class as a singleton
service
.Injects following classmethods:
-
class
jadi.
Context
(parent=None)[source]¶ An IoC container for
interface()
s,service()
s andcomponent()
sParameters: parent ( Context
) – a parent context
API: aj¶
-
aj.
config
= <module 'aj.config' from '/home/docs/checkouts/readthedocs.org/user_builds/ajenti2/checkouts/ajenti-3-dev/ajenti-core/aj/config.py'>¶ Configuration dict
-
aj.
platform
= 'debian'¶ Current platform
-
aj.
platform_string
= 'Ubuntu 18.04.5 LTS'¶ Human-friendly platform name
-
aj.
platform_unmapped
= 'ubuntu'¶ Current platform without “Ubuntu is Debian”-like mapping
-
aj.
version
= '2.2.1'¶ Ajenti version
-
aj.
server
= None¶ Web server
-
aj.
debug
= False¶ Debug mode
API: aj.api.http¶
-
class
aj.api.http.
BaseHttpHandler
[source]¶ Base class for everything that can process HTTP requests
-
handle
(http_context)[source]¶ Should create a HTTP response in the given
http_context
and return the plain outputParameters: http_context ( aj.http.HttpContext
) – HTTP context
-
-
class
aj.api.http.
HttpMasterMiddleware
(context)[source]¶ -
handle
(http_context)[source]¶ Should create a HTTP response in the given
http_context
and return the plain outputParameters: http_context ( aj.http.HttpContext
) – HTTP context
-
-
class
aj.api.http.
HttpMiddleware
(context)[source]¶ -
handle
(http_context)[source]¶ Should create a HTTP response in the given
http_context
and return the plain outputParameters: http_context ( aj.http.HttpContext
) – HTTP context
-
-
class
aj.api.http.
HttpPlugin
(context)[source]¶ A base interface for HTTP request handling:
@component class HelloHttp(HttpPlugin): @get('/hello/(?P<name>.+)') def get_page(self, http_context, name=None): context.add_header('Content-Type', 'text/plain') context.respond_ok() return 'Hello, f"{name}"!'
-
handle
(http_context)[source]¶ Finds and executes the handler for given request context (handlers were methods decorated with
url()
and will be decorated with e.g. @get and @post in the future)Parameters: http_context ( aj.http.HttpContext
) – HTTP contextReturns: reponse data
-
-
class
aj.api.http.
SocketEndpoint
(context)[source]¶ Base interface for Socket.IO endpoints.
-
plugin
= None¶ arbitrary plugin ID for socket message routing
-
-
aj.api.http.
delete
(pattern)¶ Exposes the decorated method of your
HttpPlugin
via HTTPParameters: pattern (str) – URL regex ( ^
and$
are implicit)Return type: function Named capture groups will be fed to function as
**kwargs
-
aj.api.http.
get
(pattern)¶ Exposes the decorated method of your
HttpPlugin
via HTTPParameters: pattern (str) – URL regex ( ^
and$
are implicit)Return type: function Named capture groups will be fed to function as
**kwargs
-
aj.api.http.
head
(pattern)¶ Exposes the decorated method of your
HttpPlugin
via HTTPParameters: pattern (str) – URL regex ( ^
and$
are implicit)Return type: function Named capture groups will be fed to function as
**kwargs
-
aj.api.http.
patch
(pattern)¶ Exposes the decorated method of your
HttpPlugin
via HTTPParameters: pattern (str) – URL regex ( ^
and$
are implicit)Return type: function Named capture groups will be fed to function as
**kwargs
-
aj.api.http.
post
(pattern)¶ Exposes the decorated method of your
HttpPlugin
via HTTPParameters: pattern (str) – URL regex ( ^
and$
are implicit)Return type: function Named capture groups will be fed to function as
**kwargs
-
aj.api.http.
put
(pattern)¶ Exposes the decorated method of your
HttpPlugin
via HTTPParameters: pattern (str) – URL regex ( ^
and$
are implicit)Return type: function Named capture groups will be fed to function as
**kwargs
-
aj.api.http.
requests_decorator_generator
(method)[source]¶ Factorization to generate request decorators like @get or @post.
Parameters: method (basestring) – Request method decorator to generate, like get or post Returns: Return type:
-
aj.api.http.
url
(pattern)[source]¶ Exposes the decorated method of your
HttpPlugin
via HTTP. Will be deprecated in favor of new decorators ( @get, @post, … )Parameters: pattern (str) – URL regex ( ^
and$
are implicit)Return type: function Named capture groups will be fed to function as
**kwargs
API: aj.api.endpoint¶
-
exception
aj.api.endpoint.
EndpointError
(inner, message=None)[source]¶ To be raised by endpoints when a foreseen error occurs. This exception doesn’t cause a client-side crash dialog.
Parameters: - inner – inner exception
- message – message
-
exception
aj.api.endpoint.
EndpointReturn
(code, data=None)[source]¶ Raising
EndpointReturn
will return a custom HTTP code in the API endpoints.Parameters: - code – HTTP code
- data – response data
-
aj.api.endpoint.
endpoint
(page=False, api=False, auth=True)[source]¶ It’s recommended to decorate all HTTP handling methods with
@endpoint
.@endpoint(auth=True)
will require authenticated session before giving control to the handler.@endpoint(api=True)
will wrap responses and exceptions into JSON, and will also provide special handling ofEndpointsError
Parameters: - auth (bool) – requires authentication for this endpoint
- page (bool) – enables page mode
- api (bool) – enables API mode
API: aj.config¶
API: aj.core¶
-
aj.core.
run
(config=None, plugin_providers=None, product_name='ajenti', dev_mode=False, debug_mode=False, autologin=False)[source]¶ A global entry point for Ajenti.
Parameters: - config (
aj.config.BaseConfig
) – config file implementation instance to use - plugin_providers (list(
aj.plugins.PluginProvider
)) – list of plugin providers to load plugins from - product_name (str) – a product name to use
- dev_mode (bool) – enables dev mode (automatic resource recompilation)
- debug_mode (bool) – enables debug mode (verbose and extra logging)
- autologin (bool) – disables authentication and logs everyone in as the user running the panel. This is EXTREMELY INSECURE.
- config (
API: aj.entry¶
API: aj.http¶
-
class
aj.http.
HttpContext
(env, start_response=None)[source]¶ Instance of
HttpContext
is passed to all HTTP handler methods-
env
¶ WSGI environment dict
-
path
¶ Path segment of the URL
-
method
¶ Request method
-
headers
¶ List of HTTP response headers
-
body
¶ Request body
-
response_ready
¶ Indicates whether a HTTP response has already been submitted in this context
-
query
¶ HTTP query parameters
-
add_header
(key, value)[source]¶ Adds a given HTTP header to the response
Parameters: - key (str) – header name
- value (str) – header value
-
file
(path, stream=False, inline=False, name=None)[source]¶ Returns a GZip compressed response with content of file located in
path
and correct headers
-
gzip
(content, compression=6)[source]¶ Returns a GZip compressed response with given
content
and correct headersParameters: compression (int) – compression level from 0 to 9 Return type: str
-
-
class
aj.http.
HttpMiddlewareAggregator
(stack)[source]¶ Stacks multiple HTTP handlers together in a middleware fashion.
Parameters: stack (list( aj.api.http.BaseHttpHandler
)) – handler list-
handle
(http_context)[source]¶ Should create a HTTP response in the given
http_context
and return the plain outputParameters: http_context ( aj.http.HttpContext
) – HTTP context
-
-
class
aj.http.
HttpRoot
(handler)[source]¶ A root WSGI middleware object that creates the
HttpContext
and dispatches it to an HTTP handler.Parameters: handler ( aj.api.http.BaseHttpHandler
) – next middleware handler
API: aj.plugins¶
-
class
aj.plugins.
DirectoryPluginProvider
(path)[source]¶ A plugin provider that looks up plugins in a given directory.
Parameters: path – directory to look for plugins in
-
class
aj.plugins.
PythonPathPluginProvider
[source]¶ A plugin provider that looks up plugins on
$PYTHONPATH
-
class
aj.plugins.
Dependency
[source]¶ -
-
value
¶
-
yaml_loader
¶ alias of
yaml.loader.SafeLoader
-
yaml_tag
= '!Dependency'¶
-
-
class
aj.plugins.
ModuleDependency
(module_name=None)[source]¶ -
-
description
= 'Python module'¶
-
yaml_tag
= '!ModuleDependency'¶
-
-
class
aj.plugins.
PluginDependency
(plugin_name=None)[source]¶ -
-
description
= 'Plugin'¶
-
yaml_tag
= '!PluginDependency'¶
-
-
class
aj.plugins.
OptionalPluginDependency
(plugin_name=None)[source]¶ -
-
description
= 'Plugin'¶
-
yaml_tag
= '!OptionalPluginDependency'¶
-
-
class
aj.plugins.
BinaryDependency
(binary_name=None)[source]¶ -
-
description
= 'Application binary'¶
-
yaml_tag
= '!BinaryDependency'¶
-
-
class
aj.plugins.
FileDependency
(file_name=None)[source]¶ -
-
description
= 'File'¶
-
yaml_tag
= '!FileDependency'¶
-
Angular: ajenti.core¶
This Angular module contains core components of Ajenti frontend.
Services¶
-
class
config
()¶ -
config.
data
¶ Config file content object
-
config.
load
()¶ Gets complete configuration data of the backend
Returns: promise
-
config.
save
()¶ Updates and saves configuration data
Returns: promise
-
config.
getUserConfig
()¶ Gets per-user configuration data of the backend
Returns: promise → per-user Ajenti config object
-
config.
setUserConfig
(config)¶ Updates and saves per-user configuration data
Arguments: - config (object) – updated configuration data from
getUserConfig()
Returns: promise
- config (object) – updated configuration data from
-
-
class
core
()¶ -
core.
pageReload
()¶ Reloads the current URL
-
core.
restart
()¶ Restarts the Ajenti process
-
-
class
hotkeys
()¶ Captures shortcut key events
-
hotkeys.
ENTER, ESC
¶ Respective key codes
-
hotkeys.
on
(scope, handler, mode='keydown')¶ Registers a hotkey handler in the provided
scope
Arguments: - scope ($scope) –
$scope
to install handler into - handler (function(keyCode,rawEvent)) – handler function. If the function returns a truthy value, event is cancelled and other handlers aren’t notified.
- mode (string) – one of
keydown
,keypress
orkeyup
.
- scope ($scope) –
-
-
class
identity
()¶ Provides info on the authentication status and user/machine identity
-
identity.
user
¶ Name of the logged in user
-
identity.
effective
¶ Effective UID of the server process
-
identity.machine.
name
¶ User-provided name of the machine
-
identity.
isSuperuser
¶ Whether current user is a superuser or not
-
identity.
auth
(username, password, mode)¶ Attempts to authenticate current session as
username:password
with amode
ofnormal
orsudo
-
identity.
login
()¶ Redirects user to a login dialog
-
identity.
logout
()¶ Deauthenticates current session
-
identity.
elevate
()¶ Redirects user to a sudo elevation dialog
-
-
class
messagebox
()¶ Provides interface to modal messagebox engine
-
messagebox.
show
(options)¶ Opens a new messagebox.
Arguments: - options (object) –
- options.title (string) –
- options.text (string) –
- options.positive (string) – positive action button text. Clicking it will resolve the returned promise.
- options.negative (string) – negative action button text. Clicking it will reject the returned promise.
- options.template (string) – (optional) custom body template
- options.scrollable (boolean) – whether message body is scrollable
- options.progress (boolean) – whether to display an indeterminate progress indicator in the message
Returns: a Promise-like object with an additional
close()
method.
-
-
class
notify
()¶ -
notify.
info
(title, text)¶
-
notify.
success
(title, text)¶
-
notify.
warning
(title, text)¶
-
notify.
error
(title, text)¶ Shows an appropriately styled notification
-
notify.
custom
(style, title, text, url)¶ Shows a clickable notification leading to
url
.
-
-
class
pageTitle
()¶ Alters page
<title>
and global heading.-
pageTitle.
set
(text)¶ Sets title text
-
pageTitle.
set
(expression, scope) Sets an title expression to be watched. Example:
$scope.getTitle = (page) -> someService.getPageTitle(page) $scope.page = ... pageTitle.set("getTitle(page)", $scope)
-
-
class
push
()¶ Processes incoming push messages (see
aj.plugins.core.api.push
). This service has no public methods.This service broadcasts events that can be received as:
$scope.$on 'push:pluginname', (message) -> processMessage(message)...
-
class
tasks
()¶ An interface to the tasks engine (see
aj.plugins.core.api.tasks
).-
tasks.
tasks
¶ A list of task descriptors for the currently running tasks. Updated automatically.
-
tasks.
start
(cls, args, kwargs)¶ Starts a server-side task.
Arguments: - cls (string) – full task class name (
aj.plugins.pluginname....
) - args (array) – task arguments
- kwargs (object) – task keyword arguments
Returns: a promise, resolved once the task actually starts
- cls (string) – full task class name (
-
Directives¶
-
autofocus
()¶ Automatically focuses the input. Example:
<input type="text" autofocus ng:model="..." />
-
checkbox
()¶ Renders a checkbox. Example:
<span checkbox ng:model="..." text="Enable something"></span>
-
dialog
()¶ A modal dialog
Example:
<dialog ng:show="showDialog"> <div class="modal-header"> <h4> Heading </h4> </div> <div class="modal-body scrollable"> ... </div> <div class="modal-footer"> <a ng:click="..." class="btn btn-default btn-flat"> Do something </a> </div> </dialog>
Arguments: - ngShow (expression) –
- dialogClass (string) –
-
floating-toolbar
()¶ A toolbar pinned to the bottom edge. Example:
<div class="floating-toolbar-padder"></div> <floating-toolbar> <a ng:click="..." class="btn btn-default btn-flat"> Do something useful </a> </floating-toolbar> <!-- accented toolbar for selection actions --> <floating-toolbar class="accented" ng:show="haveSelectedItems"> Some action buttons here </floating-toolbar>
-
ng-enter
()¶ Action handler for Enter key in inputs. Example:
<input type="text" ng:enter="commitStuff()" ng:model="..." />
-
progress-spinner
()¶
-
root-access
()¶ Blocks its inner content if the current user is not a superuser.
-
smart-progress
()¶ An improved version of ui-bootstrap’s progressbar
Arguments: - animate (boolean) –
- value (float) –
- max (float) –
- text (string) –
- maxText (string) –
Filters¶
-
bytesFilter
(value, precision)¶ Arguments: - value (int) – number of bytes
- precision (int) – number of fractional digits in the output
Returns: string, e.g.:
123.45 KB
-
ordinalFilter
(value)¶ Arguments: - value (int) –
Returns: string, e.g.:
121st
-
pageFilter
(list, page, pageSize)¶ Provides a page-based view on an array
Arguments: - list (array) – input data
- page (int) – 1-based page index
- pageSize (int) – page size
Returns: array
Angular: ajenti.ace¶
ACE code editor integration
Angular: ajenti.augeas¶
Services¶
-
class
augeas
()¶ -
augeas.
get
(endpoint)¶ Reads an Augeas tree from server side.
Returns: promise → AugeasConfig
-
augeas.
set
(endpoint, config)¶ Overwrites an Augeas tree on the server side.
Returns: promise
-
-
class
AugeasNode
()¶ -
AugeasNode.
name
¶
-
AugeasNode.
value
¶
-
AugeasNode.
parent
¶
-
AugeasNode.
children
¶
-
AugeasNode.
fullPath
()¶
-
-
class
AugeasConfig
()¶ This is a JS doppelganger of normal Augeas API. In particular, it doesn’t support advanced XPath syntax, and operates with regular expressions instead.
-
AugeasConfig.
get
(path)¶ Returns: AugeasNode
-
AugeasConfig.
set
(path, value)¶
-
AugeasConfig.
model
(path)¶ Returns: a getter/setter function suitable for use as a ngModel
-
AugeasConfig.
insert
(path, value, index)¶
-
AugeasConfig.
remove
(path)¶
-
AugeasConfig.
match
(path)¶ Returns: Array(string)
-
AugeasConfig.
matchNodes
(path)¶ Returns: Array(AugeasNode)
-
Angular: ajenti.filesystem¶
Services¶
-
class
filesystem
()¶ -
filesystem.
read
(path)¶ Returns: promise → content of path
-
filesystem.
write
(path, content)¶ Returns: promise
-
filesystem.
list
(path)¶ Returns: promise → array
-
filesystem.
stat
(path)¶ Returns: promise → object
-
filesystem.
chmod
(path, mode)¶ Arguments: - mode (int) – numeric POSIX file mode
Returns: promise
-
filesystem.
createFile
(path, mode)¶ Arguments: - mode (int) – numeric POSIX file mode
Returns: promise
-
filesystem.
createDirectory
(path, mode)¶ Arguments: - mode (int) – numeric POSIX file mode
Returns: promise
-
filesystem.
downloadBlob
(content, mime, name)¶ Launches a browser-side file download
Arguments: - content (string) – Raw file content
- mime (string) – MIME type used
- name (string) – Default file name for saving
Returns: promise
-
Directives¶
-
file-dialog
()¶ File open/save dialog. Example:
<file-dialog mode="open" ng:show="openDialogVisible" on-select="open(item.path)" on-cancel="openDialogVisible = false"> </file-dialog> <file-dialog mode="save" ng:show="saveDialogVisible" on-select="saveAs(path)" on-cancel="saveDialogVisible = false" name="saveAsName"> </file-dialog>
Arguments: - ngShow (expression) –
- onSelect (expression(item)) – called after opening or saving a file.
item
is an object with apath
property. - onCancel (expression) – (optional) handler for the cancel button
- mode (string) – one of
open
,save
- name (binding) – (optional) name for the saved file
- path (binding) – (optional) current
-
path-selector
()¶ An input with a file selection dialog:
<path-selector ng:model="filePath"></path-selector>
Angular: ajenti.passwd¶
Angular: ajenti.services¶
Services¶
-
class
services
() -
services.
getManagers
()¶ Returns: promise → array of the available service managers
-
services.
getServices
(managerId)¶ Returns: promise → array of the available services in the ServiceManager
-
services.
getService
(managerId, serviceId)¶ Returns: promise → object, gets a single service from the manager
-
services.
runOperation
(managerId, serviceId, operation)¶ Arguments: - operation (string) – typically
start
,stop
,restart
,reload
; depends on the service manager
Returns: promise
- operation (string) – typically
-
Angular: ajenti.terminal¶
Services¶
-
class
terminals
()¶ -
terminals.
list
()¶ Returns: promise → array of opened terminal descriptors
-
terminals.
kill
(terminalId)¶ Kills a running terminal process
Returns: promise
-
terminals.
create
(options)¶ Creates a new terminal
Arguments: - options.command (string) –
- options.autoclose (boolean) –
Returns: promise → new terminal ID
-
terminals.
full
(terminalId)¶ Returns: promise → full content of the requested terminal
-
Plugin: aj.plugins.core.api.push¶
Plugin: aj.plugins.core.api.sidebar¶
Returns a complete tree of sidebar items.
Returns: dict
Interface for providing sidebar items.
Should return a list of sidebar items, each in the following format:
{ 'id': 'optional-id', 'attach': 'category:general', # id of the attachment point or None for top level 'name': 'Dashboard', 'icon': 'bar-chart', 'url': '/view/dashboard', 'children': [ ... ] }
Returns: list(dict)
Plugin: aj.plugins.core.api.tasks¶
-
class
aj.plugins.core.api.tasks.
Task
(context, *args, **kwargs)[source]¶ Tasks are one-off child processes with progress reporting. This is a base abstract class.
-
name
= None¶ Display name
-
push
(plugin, message)[source]¶ An interface to
aj.plugins.core.api.push.Push
usable from inside the task’s process
-