You've already forked configurator
mirror of
https://github.com/armbian/configurator.git
synced 2026-01-06 10:36:02 -08:00
Making the software a bit more user-friendly
There's still a lot to do before it becomes really user-friendly, but at least, this thing won't spout weird Debug messages for nothing at the moment. Also, you can now specify the execution mode using '--mode=' The DESIGN.md now looks more like a "First module guide" but some parts are now missing... I'll try to fix that when possible. Signed-off-by: Myy Miouyouyou <myy@miouyouyou.fr>
This commit is contained in:
95
DESIGN.md
95
DESIGN.md
@@ -1,39 +1,78 @@
|
||||
Version: 1
|
||||
Status: DRAFT
|
||||
|
||||
# Status
|
||||
|
||||
While this tutorial will explain you how to start coding your own
|
||||
module, it won't be prepared for packaging...
|
||||
|
||||
TODO : Add a 'build' script example that make the whole thing ready
|
||||
for packaging.
|
||||
|
||||
# Main design
|
||||
|
||||
## Adding a simple module directly on your system
|
||||
## Coding your own CLI module
|
||||
|
||||
For each module you want to add :
|
||||
1. Create a directory where you'll put the CLI module code and `cd` into it.
|
||||
Example :
|
||||
```bash
|
||||
mkdir -p ~/Documents/my_armbian_module
|
||||
cd ~/Documents/my_armbian_module
|
||||
```
|
||||
|
||||
1. Create the following subdirectory :
|
||||
`/usr/share/armbian/configurator/modules/${module_name}/cli` .
|
||||
2. Copy your module executable file to :
|
||||
`/usr/share/armbian/configurator/modules/${module_name}/cli/module` .
|
||||
The file can actually be an absolute symlink to a system executable
|
||||
file too.
|
||||
3. Write a short description of the module in
|
||||
`/usr/share/armbian/configurator/modules/${module_name}/DESC` .
|
||||
2. Create a file named `DESC` and write a short description
|
||||
for this module.
|
||||
```bash
|
||||
echo "Best module ever" > DESC
|
||||
```
|
||||
|
||||
That's about it.
|
||||
3. Add a `module` file and ensure it is executable. This file
|
||||
will be the one executed by the configurator when running
|
||||
your module.
|
||||
```bash
|
||||
echo '#!/bin/bash' > module
|
||||
echo "echo 'I told you, best module ever \!'" >> module
|
||||
chmod +x module
|
||||
```
|
||||
|
||||
For deveopment purposes, you might want to actually symlink
|
||||
`/usr/share/armbian/configurator/modules/${module_name}` to
|
||||
a development directory inside your home directory.
|
||||
For example :
|
||||
`sudo ln -s /usr/share/armbian/configurator/modules/${module_name} /home/YourUserName/module_name`
|
||||
4. Create the directory `/usr/share/armbian/configurator/modules/${module_name}/cli`
|
||||
Example, if your module is named 'my_module' :
|
||||
```bash
|
||||
module_name=my_module
|
||||
sudo mkdir -p "/usr/share/armbian/configurator/modules/${module_name}"
|
||||
```
|
||||
5. Link the `DESC` file to `/usr/share/armbian/configurator/modules/${module_name}/DESC`
|
||||
```bash
|
||||
module_name=my_module
|
||||
sudo ln -s "${PWD}/DESC" "/usr/share/armbian/configurator/modules/${module_name}/DESC"
|
||||
```
|
||||
6. Link the directory itself to `/usr/share/armbian/configurator/modules/${module_name}/cli`
|
||||
```bash
|
||||
module_name=my_module
|
||||
sudo ln -s "${PWD}" "/usr/share/armbian/configurator/modules/${module_name}/cli"
|
||||
```
|
||||
|
||||
## Adding a GUI (X11/Wayland) to a module
|
||||
Now, the module is recognized by the configurator.
|
||||
|
||||
1. Create the directory :
|
||||
`/usr/share/armbian/configurator/modules/${module_name}/gui`
|
||||
Launch the configurator without arguments to see your module in the list.
|
||||
Launch the configurator with the name of your module to launch it :
|
||||
|
||||
2. Add at least the executable file to :
|
||||
`/usr/share/armbian/configurator/modules/${module_name}/gui/module`
|
||||
```bash
|
||||
module_name=my_module
|
||||
configurator ${module_name}
|
||||
```
|
||||
|
||||
Then copy all the files required by the GUI into its specific folder,
|
||||
`/usr/share/armbian/configurator/modules/${module_name}/gui`.
|
||||
```
|
||||
I told you, best module ever !
|
||||
```
|
||||
|
||||
## Adding a GUI (X11/Wayland) to your module
|
||||
|
||||
1. Create a directory where you'll put the GUI executable of your module.
|
||||
2. Make sure your GUI executable name is named `module`
|
||||
3. Link it to `/usr/share/armbian/configurator/modules/${module_name}/gui`
|
||||
|
||||
You're done
|
||||
|
||||
## Adding a translation to the short description
|
||||
|
||||
@@ -49,8 +88,8 @@ avoid using precise locales names when you can.
|
||||
Let's say you want to add a French translation for a module
|
||||
description.
|
||||
|
||||
French locales start with `fr`.
|
||||
French locale for people living in France specifically is : `fr_FR`.
|
||||
French locales start with `fr`.
|
||||
French locale for people living in France specifically is : `fr_FR`.
|
||||
French locale for people living in Canada specifically is : `fr_CA`.
|
||||
|
||||
So, if you want to add a french translation, add either a
|
||||
@@ -58,17 +97,17 @@ So, if you want to add a french translation, add either a
|
||||
|
||||
If you add both `DESC.fr_FR` and `DESC.fr`, the system will use :
|
||||
|
||||
* `DESC.fr_FR` for people using the `fr_FR` locale.
|
||||
* `DESC.fr_FR` for people using the `fr_FR` locale.
|
||||
* `DESC.fr` for people using `fr_CA` locale.
|
||||
|
||||
If you only add `DESC.fr`, the system will use :
|
||||
|
||||
* `DESC.fr` for people using the `fr_FR` locale.
|
||||
* `DESC.fr` for people using the `fr_FR` locale.
|
||||
* `DESC.fr` for people using `fr_CA` locale.
|
||||
|
||||
if you only add `DESC.fr_FR`, the system will use :
|
||||
|
||||
* `DESC.fr_FR` for people using the `fr_FR` locale.
|
||||
* `DESC.fr_FR` for people using the `fr_FR` locale.
|
||||
* `DESC` (default english version) for people using the `fr_CA` locale.
|
||||
|
||||
## Prepare for packaging
|
||||
|
||||
89
configurator
89
configurator
@@ -1,8 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from argparse import ArgumentParser, RawDescriptionHelpFormatter
|
||||
import logging
|
||||
from pathlib import Path
|
||||
import os
|
||||
from pathlib import Path
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -16,7 +17,7 @@ class Helpers:
|
||||
@staticmethod
|
||||
def get_logger(name: str = 'default'):
|
||||
logger = logging.getLogger(name)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
# Avoid messages duplication after multiple Jupyter Lab runs
|
||||
handler_console = None
|
||||
@@ -164,8 +165,8 @@ class Configurator:
|
||||
|
||||
def print_modules(self):
|
||||
for module_name in self.modules:
|
||||
modes = self.module_modes(module_name)
|
||||
desc = self.module_desc(module_name)
|
||||
modes = ', '.join(self.module_modes(module_name))
|
||||
desc = self.module_desc(module_name).strip()
|
||||
self.logger.info(f'\t{module_name}\t{modes}\t{desc}')
|
||||
|
||||
def system_can_handle_gui(self):
|
||||
@@ -173,7 +174,8 @@ class Configurator:
|
||||
|
||||
def execute_module(self, module_name: str, arguments: list, mode: str = '') -> int:
|
||||
if not self.module_exist(module_name):
|
||||
self.logger.critical(f'{module_name} does not exist !')
|
||||
self.logger.critical(f'Module {module_name} does not exist !')
|
||||
return -1
|
||||
|
||||
modes = self.module_modes(module_name)
|
||||
|
||||
@@ -188,13 +190,13 @@ class Configurator:
|
||||
mode = 'cli'
|
||||
else:
|
||||
if not mode in modes:
|
||||
self.logger.critical(f'{module_name} has no {mode} mode')
|
||||
sys.exit(1)
|
||||
self.logger.critical(f'The module {module_name} has no {mode} mode')
|
||||
return -1
|
||||
|
||||
subprocess.run([self.module_path(module_name) / mode / 'module'] + arguments)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
def parse_arguments(arguments: list):
|
||||
|
||||
# TODO Make it configurable through config files
|
||||
# AND command line arguments
|
||||
@@ -205,17 +207,62 @@ if __name__ == '__main__':
|
||||
|
||||
configurator = Configurator(modules_dirpath=modules_dirpath)
|
||||
|
||||
# Not using ArgParser at the moment since I need to keep
|
||||
# track of the position of the arguments.
|
||||
# All the arguments passed after the module name are passed
|
||||
# to the module 'as-is' and should not be interpreted in any
|
||||
# way.
|
||||
# Parsing the arguments before with ArgParser should not
|
||||
# be THAT hard... still, this will be for the next time.
|
||||
arguments = sys.argv
|
||||
n_args = len(arguments)
|
||||
if n_args < 2:
|
||||
epilog = 'The modules are all installed in /usr/share/armbian/configurator/modules\n\n'
|
||||
epilog += 'Example usage :\n'
|
||||
epilog += ' configurator docker\n'
|
||||
|
||||
|
||||
parser = ArgumentParser(
|
||||
description='Armbian configurator')
|
||||
#formatter_class=RawDescriptionHelpFormatter,
|
||||
#epilog=epilog)
|
||||
parser.add_argument('module')
|
||||
parser.add_argument('--mode', nargs=1, choices=['cli', 'tui', 'gui'], help='Launch a module in a specific mode')
|
||||
|
||||
|
||||
# Basically, ArgParse should only manage the arguments that
|
||||
# are passed to the configurator.
|
||||
# The other arguments must be passed "as-is" to the module.
|
||||
# So :
|
||||
# * We search for the first argument that doesn't start with
|
||||
# a dash
|
||||
# * We consider that to be the module name
|
||||
# * We cut the array after the module name.
|
||||
# This new array is considered to be the arguments to
|
||||
# the module.
|
||||
configurator_args = arguments[1:]
|
||||
module_args = []
|
||||
for i in range(1,len(arguments)):
|
||||
if not (arguments[i].startswith("-")):
|
||||
next_arg = i + 1
|
||||
configurator_args = arguments[1:next_arg]
|
||||
module_args = arguments[next_arg:]
|
||||
break
|
||||
|
||||
result = []
|
||||
try:
|
||||
result = parser.parse_args(configurator_args)
|
||||
except:
|
||||
print('\nAvailable modules are :\n')
|
||||
configurator.print_modules()
|
||||
else:
|
||||
module_name = arguments[1]
|
||||
configurator.execute_module(module_name, arguments=arguments[2:])
|
||||
print(epilog)
|
||||
sys.exit(1)
|
||||
|
||||
mode = ''
|
||||
if result.mode:
|
||||
mode = mode.join(result.mode)
|
||||
|
||||
sys.exit(configurator.execute_module(result.module, arguments=module_args, mode=mode))
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
|
||||
parse_arguments(sys.argv)
|
||||
sys.exit(0)
|
||||
#arguments = sys.argv
|
||||
#n_args = len(arguments)
|
||||
#if n_args < 2:
|
||||
#configurator.print_modules()
|
||||
#else:
|
||||
#module_name = arguments[1]
|
||||
#configurator.execute_module(module_name, arguments=arguments[2:])
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
version: 1
|
||||
# Directory containing the docker-compose templates to install
|
||||
templates_dir: "/usr/share/armbian/configurator/modules/docker/softwares"
|
||||
templates_dir: "/usr/share/armbian/configurator/modules/docker/cli/softwares"
|
||||
# Directory where docker-compose installations are
|
||||
install_dir: "/opt/armbian/docker"
|
||||
# The name of the docker service
|
||||
|
||||
Reference in New Issue
Block a user