Ajenti Web Interface Platform¶
Ajenti platform includes following products:
- Ajenti Core, a Python library, the platform itself including the HTTP server, socket engine and plugin container.
- Ajenti Panel, a startup script and a set of stock plugins such as file manager, network configurator and service manager.
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 and CSS, CoffeeScript and JavaScript auto-build support.
- Numerous stock directives.
- AngularJS templating.
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 and the port. It’s mean that an entry should look like http://my.domain.com:8000. If set, the first entry of this list will be used as url for the password reset functionality, for more security.
- 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 :
- Plugin development: like e.g. a plugin to manage the fstab file,
- Core development: 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.
What’s Ajenti and how it works¶
Ajenti Project itself consists of Ajenti Core itself and a set of stock plugins forming the Ajenti Panel.
Ajenti Core¶
Ajenti Core is a web interface development framework which includes a web server, IoC container, a simplistic web framework and set of core components aiding in client-server communications.
Ajenti Panel¶
Ajenti Panel consists of plugins developed for the Ajenti Core and a startup script, together providing a server administration panel experience. The Panel’s plugins include: file manager, 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.
Ajenti frontend is an AngularJS application composed from Angular modules provided by each plugin. Every plugin can contribute its own JS/CSS code to the combined resource package delivered to the client.
The core
plugin provides a ng:view
container for ngRoute
navigation. So, the plugins that have UI are expected to provide additional ngRoute
routes, templates and controllers.
Getting Started¶
Required knowledge¶
- Python 3
- JavaScript (ES5, ES6 or CoffeeScript)
- basic AngularJS knowledge (modules & controllers)
- basic HTML skills
Setting up development environment¶
1. Install Ajenti¶
We recommend to use the automatic installer - see the installation guide
2. Install build tools¶
Build tools require NodeJS - you can use the NodeSource repositories for quick setup:
# Using Ubuntu
curl -sL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
# Using Debian, as root
curl -sL https://deb.nodesource.com/setup_18.x | bash -
apt-get install -y nodejs
# Using RHEL, as root
curl -sL https://rpm.nodesource.com/setup_18.x | bash -
Now, install the build tools:
npm -g install bower babel-cli babel-preset-es2015 babel-plugin-external-helpers less coffee-script angular-gettext-cli angular-gettext-tools
# Ubuntu or Debian:
apt-get install gettext
# RHEL
dnf install gettext
3. Install ajenti-dev-multitool¶
pip3 install ajenti-dev-multitool
Your first plugin¶
Create a new plugin in the current directory:
ajenti-dev-multitool --new-plugin "Some plugin name"Build resources:
cd some_plugin_name ajenti-dev-multitool --buildAnd start it:
sudo ajenti-dev-multitool --run-devThis will start Ajenti with the stock plugins plus the current one, and will rebuild plugin resources every time you reload Ajenti in browser.
Navigate to http://localhost:8000/. You should see new plugin in the sidebar.
What’s inside¶
Each plugin package consists of Python modules, which contain jadi.component
classes (components).
Packages also may contain static files, templates and JS and CSS code, e.g.:
* some_plugin_name
- plugin.yml # plugin description
- __init__.py
- other_python_module.py
* resources
* vendor
- jquery-ui # Bower components
* js
- module.js # Angular.js code
- ecmascript6-code.es
- coffeescript-code.coffee
* css
- styles.css
- styles.less
* partials
-- index.html
Where to go from here¶
Example plugins¶
Download plugins from here: https://github.com/ajenti/demo-plugins or clone this entire repository.
Prep work:
ajenti-dev-multitool --bower install ajenti-dev-multitool --rebuildRun:
ajenti-dev-multitool --run-devHint
Changes in ES6, CoffeeScript and LESS files will be recompiled automatically when you refresh the page; Python code will not. 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
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.--bower "<bower-command-with-args>"
will run a Bower command for each plugin having its ownbower.json
file. Example:ajenti-dev-multitool --bower "install"
.--build
updates the resource bundles.--rebuild
will discard any previously built 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 AngularJS-based single-page rich web application.
Your plugins can extend it by adding new Angular components (services, controllers, directives) and routes (ngRoute
).
Client-server communication is facilitated by AJAX requests to backend API ($http
) and a Socket.IO connection (socket
and push
Angular services).
Client styling is based on a customized Twitter Bootstrap build.
Example¶
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)
Plugin resources¶
Basics¶
Plugin resource files are contained under resources
directory nested in the plugin directory.
We encourage following structure:
* plugin
* resources
* css
- styles.less
* js
- module.coffee
- routing.coffee
* controllers
- some.controller.coffee
* services
- some.service.coffee
* img
- image.png
* partials
- view.html
CSS, JS and HTML resources must be listed in the plugin.yml
file in order to be served to client. Example:
name: test
...
resources:
- 'resources/vendor/jquery/dist/jquery.min.js' # Bower component
- 'resources/css/animations.less' # Styles
- 'resources/js/core/filters.coffee' # JS
- 'resources/partial/index.html' # HTML
- 'ng:moduleName' # Special syntax for publishing an AngularJS module.
Please note that the last item instructs Ajenti core to load the specified AngularJS module (test
) from the plugin.
Bower components¶
Example can be browsed and downloaded at https://github.com/ajenti/demo-plugins/tree/master/demo_3_bower
Plugins can depend on Bower components. To use this feature, create a bower.json
file in your plugin directory:
{
"name": "plugin",
"private": true,
"dependencies": {
"jquery": "~2.1.3"
}
}
Components are installed into <plugin>/resources/vendor
directory. To install/update the components, run ajenti-dev-multitool --bower install
. You can also run make bower
in the root of a complete Ajenti code tree to install Bower components in all plugins.
You can run other Bower commands with e.g. ajenti-dev-multitool --bower "list --force --verbose"
.
Resource access¶
AngularJS templates are pre-loaded on the client. A template residing in plugins/test/resources/dir/template.html
can be accessed with the following URL: /test:resources/dir/template.html
.
Other resource files are available through HTTP at /resources/<plugin_id>/resources/<path>
.
Resource compilation¶
When running in dev mode (--dev
), Ajenti will invoke ajenti-dev-multitool --build
on page reload. Force-reloading the page (Ctrl/Cmd-F5) will rebuild all resources in all plugins using ajenti-dev-multitool --rebuild
ajenti-dev-multitool
will automatically compile CoffeeScript and LESS code, concatenate CSS and JS specified in plugin.yml
and place built CSS and JS files in plugin/resources/build
. Please note that ajenti-dev-multitool
will only process files in the current directory and below.
Handling HTTP Requests¶
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¶
Example¶
Basic example of a dynamic and configurable widget can be browsed and downloaded at https://github.com/ajenti/demo-plugins/tree/master/demo_5_widget
Plugins can provide dashboard widgets by extending the aj.plugins.dashboard.api.Widget
abstract class:
@component(Widget)
class RandomWidget(Widget):
id = 'random'
# display name
name = 'Random'
# template of the widget
template = '/demo_5_widget:resources/partial/widget.html'
# template of the configuration dialog
config_template = '/demo_5_widget:resources/partial/widget.config.html'
def __init__(self, context):
Widget.__init__(self, context)
def get_value(self, config):
# generate value based on widget's config
if 'bytes' not in config:
return 'Not configured'
return os.urandom(int(config['bytes'])).encode('hex')
There are some CSS classes available for the standard widget looks:
<div ng:controller="Demo5WidgetController">
<div class="widget-header">
Random
</div>
<div class="widget-value">
{{value || 'Unknown'}}
</div>
</div>
The templates should reference appropriate controllers:
angular.module('ajenti.demo5').controller 'Demo5WidgetController', ($scope) ->
# $scope.widget is our widget descriptor here
$scope.$on 'widget-update', ($event, id, data) ->
if id != $scope.widget.id
return
$scope.value = data
angular.module('ajenti.demo5').controller 'Demo5WidgetConfigController', ($scope) ->
# $scope.configuredWidget is our widget descriptor here
# some defaults
$scope.configuredWidget.config.bytes ?= 4
Initially, dashboard will create your widget with an empty ({}
) config and show the configuration dialog you provided.
Dashboard will issue periodic requests to your aj.plugins.dashboard.api.Widget
implementations. Your widget classes should not retain any state. If user creates multiple widgets of same type, a single instance will be created to service their requests.
Getting Started with Core Development¶
Attention
This article is only useful to the developers interested in developing the Ajenti core itself. For plugin/extension development, see Getting started with plugin development
Required knowledge¶
- Python 3.x
- async programming with gevent
- HTML
- CoffeeScript (with AngularJS)
- LESS
Prerequisites¶
The following is the absolutely minimal set of software required to build and run Ajenti:
- git
- bower, babel, babel-preset-es2015 and lessc (from NPM)
Debian/Ubuntu extras:
- python3-dbus (ubuntu)
Automatic Installation¶
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¶
First, it’s necessary to complete the install for plugin developpement mentioned here : Dev getting started
Download the source:
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 gettext
# RHEL
sudo dnf install gcc python3-devel python3-pip libxslt-devel libxml2-devel libffi-devel openssl-devel libjpeg-turbo-devel libpng-devel dbus-python gettext
cd ajenti
sudo pip3 install -r ajenti-core/requirements.txt
sudo pip3 install ajenti-dev-multitool
sudo npm install -g coffee-script less bower
Download and install Bower dependencies:
make bower
Ensure that resource compilation is set up correctly and works (optional):
make build
Launch Ajenti in dev mode:
make rundev
Navigate to http://localhost:8000/.
Hint
Changes in CoffeeScript and LESS files will be recompiled automatically when you refresh the page; Python code will not. 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
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/latest/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.6'¶ 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.
copy
(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.
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.
lock
(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.
mkcol
(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.
move
(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.
options
(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.
propfind
(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.
proppatch
(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.
unlock
(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.
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.
CGIFieldStorage
(fp=None, headers=None, outerboundary=b'', environ=environ({'READTHEDOCS_VIRTUALENV_PATH': '/home/docs/checkouts/readthedocs.org/user_builds/ajenti2/envs/latest', 'READTHEDOCS_CANONICAL_URL': 'http://docs.ajenti.org/en/latest/', 'RTD_PYTHON_VERSION_35': '3.5.10', 'HOSTNAME': 'build-21790423-project-27581-ajenti2', 'RTD_PYTHON_VERSION_27': '2.7.18', 'RTD_PYTHON_VERSION_36': '3.6.12', 'RTD_PYTHON_VERSION_37': '3.7.9', 'APPDIR': '/app', 'RTD_PYTHON_VERSION_38': '3.8.6', 'READTHEDOCS_GIT_CLONE_URL': 'https://github.com/ajenti/ajenti', 'HOME': '/home/docs', 'RTD_SETUPTOOLS_VERSION': '45.1.0', 'NO_COLOR': '1', 'READTHEDOCS': 'True', 'RTD_PYPY_VERSION_35': 'pypy3.5-7.0.0', 'READTHEDOCS_PROJECT': 'ajenti2', 'READTHEDOCS_OUTPUT': '/home/docs/checkouts/readthedocs.org/user_builds/ajenti2/checkouts/latest/_readthedocs/', 'PATH': '/home/docs/checkouts/readthedocs.org/user_builds/ajenti2/envs/latest/bin:/home/docs/.pyenv/shims:/home/docs/.pyenv/shims:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/docs/.conda/bin:/home/docs/.pyenv/bin:/home/docs/.conda/bin:/home/docs/.pyenv/bin', 'READTHEDOCS_VERSION_TYPE': 'branch', 'RTD_PIP_VERSION': '20.0.1', 'LANG': 'C.UTF-8', 'READTHEDOCS_LANGUAGE': 'en', 'DEBIAN_FRONTEND': 'noninteractive', 'READTHEDOCS_GIT_COMMIT_HASH': '0dae5b9f3f29b1204d14beebaa47b3aad2e80b0f', 'READTHEDOCS_VERSION_NAME': 'latest', 'RTD_VIRTUALENV_VERSION': '16.7.9', 'RTD_CONDA_VERSION': '4.6.14', 'READTHEDOCS_VERSION': 'latest', 'PWD': '/home/docs/checkouts/readthedocs.org/user_builds/ajenti2/checkouts/latest/docs/source', 'PYENV_ROOT': '/home/docs/.pyenv', 'READTHEDOCS_GIT_IDENTIFIER': 'master', 'DOCUTILSCONFIG': '/home/docs/checkouts/readthedocs.org/user_builds/ajenti2/checkouts/latest/docs/source/docutils.conf'}), keep_blank_values=0, strict_parsing=0, limit=None, encoding='utf-8', errors='replace', max_num_fields=None)[source]¶
-
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
-
Plugin: aj.plugins.augeas.api¶
-
class
aj.plugins.augeas.api.
Augeas
(modules=[], loadpath=None)[source]¶ A smarter and faster wrapper around
augeas.Augeas
.augeasFor faster startup, no modules and lenses are preloaded:
aug = Augeas(modules=[{ 'name': 'Interfaces', # module name 'lens': 'Interfaces.lns', # lens name 'incl': [ # included files list self.path, self.path + '.d/*', ] }])
Don’t forget to call
load()
afterwards.-
raise_error
()[source]¶ Extracts error information from Augeas tree and raises
AugeasError
-
Plugin: aj.plugins.auth-users.api¶
Plugin: aj.plugins.dashboard.api¶
Plugin: aj.plugins.check_certificates.api¶
-
aj.plugins.check_certificates.api.
CertLimitSSL
(hostname, port)[source]¶ Get the SSL certificate from a host.
Parameters: - hostname (string) – Hostname
- port (integer) – Port
Returns: OpenSSL cert
Return type: OpenSSL cert
-
aj.plugins.check_certificates.api.
CertLimitSTARTTLS
(hostname)[source]¶ Get the SSL certificate from host with STARTTLS connection on port 587.
Parameters: hostname (string) – Hostname Returns: OpenSSL cert Return type: OpenSSL cert
-
aj.plugins.check_certificates.api.
checkOnDom
(hostname, port='443')[source]¶ Store all details from a certificate into a dict and add a status attribute to display a bootstrap class for the time remaining before renew : - renew the next 7 days : danger - renew the next 14 days: warning - renew the next 28 days : info - or success
Parameters: - hostname (string) – Hostname
- port (string) – Port to test, default 443
Returns: Dict with all details from the certificate
Return type: dict
Plugin: aj.plugins.datetime.api¶
Plugin: aj.plugins.network.api¶
Plugin: aj.plugins.packages.api¶
-
class
aj.plugins.packages.api.
Package
(manager)[source]¶ Basic container class for package informations.
Plugin: aj.plugins.power.api¶
-
class
aj.plugins.power.api.
PowerManager
(context)[source]¶ Utility class for power management.
-
classmethod
get
(context)¶
-
get_adapters
()[source]¶ Read the list of adapters from /proc/acpi/ac_adapter.
Returns: List of adapters, one per dict Return type: list of dict
-
classmethod