module

Beryl::CLI::Scan

Sous-commande beryl scan <host> : se connecte au rescue Linux, détecte les disques, propose un YAML pour le fichier host.

Forme typique : beryl scan ns3156789.ip-51-83-6.eu --domain=aloli.net --dns --write

Avec --dns : pose les records DNS (CNAME vers le FQDN OVH), le reverse DNS IPv4/IPv6 et renomme le serveur côté panel OVH. Avec --write : écrit ~/.config/beryl/<domaine>/<nom>.yml (nom court demandé interactivement ou via --hostname).

Constants

DEFAULT_RAID = 0

Prompt du niveau RAID sous forme numérique pour un pool donné. Convention parlante Aloli : 0, 1, 5, 6, 7, 10 plutôt que stripe/mirror/raidz…

Format cohérent avec pick_disks_for : options entre (…), défaut entre […] avec espaces français autour des :. Niveau RAID par défaut : toujours 0 (stripe), convention Aloli — backups bétonnés > redondance disque. L'opérateur qui veut autre chose doit le dire explicitement, pas de magie sur le nombre de disques (un défaut qui change selon le contexte = UX imprévisible).

EXIT_ABORTED = 16
EXIT_API_ERROR = 7
EXIT_BAD_CREDS = 4
EXIT_INSUFFICIENT = 17
EXIT_NO_DISKS = 15
EXIT_OK = 0
EXIT_SSH_FAILED = 2
EXIT_UNEXPECTED = 3
EXIT_USAGE = 1
FREEBSD_RESERVED_MOUNTPOINTS = ["bin", "boot", "dev", "etc", "home", "lib", "libexec", "media", "mnt", "net", "proc", "rescue", "sbin", "sys", "tmp", "usr", "var", "zroot"] of ::String

Noms courts qui, s'ils étaient acceptés, produiraient un pool z<nom> monté sur /<nom> — lequel écraserait un dossier système FreeBSD de premier niveau et casserait l'OS (bootloader, configuration, binaires, runtime).

Liste dérivée d'un ls -l / sur FreeBSD 15 après install fraîche. Ajouter ici tout nouveau top-level qui apparaîtrait dans une version future.

root figure à part (refusé avec un message dédié « réservé au pool boot zroot ») par ask_pool_short_name et parse_pool_spec.

POOL_NAME_RX = /\A[a-z][a-z0-9_]*\z/

Regex des noms de pool ZFS autorisés : commence par une lettre minuscule, suivie de lettres/chiffres/underscore. Convention standard ZFS — évite les caractères qui poseraient problème en shell ou dans un YAML (espaces, tirets, majuscules…).

Class methods

default_hostname(fqdn : String) : String
Source
disks_table(disks : Array(Disk)) : String
Source
parse_lsblk(output : String) : Array(Disk)
Source
parse_pool_spec(spec : String, remaining : Array(Disk)) : PoolSpec

Parse une spec --pool=SHORTNAME:DISKS:RAID et retourne un PoolSpec data (pool z<SHORTNAME> + mountpoint /<SHORTNAME>, boot: false).

  • SHORTNAME : nom court sans préfixe z (ex: data, cache). Refuse root (réservé au pool boot zroot).
  • DISKS : sda,sdb ou all (tous les disques restants).
  • RAID : 0|1|5|6|7|10.

Toutes les validations lèvent ArgumentError pour remonter un message clair à l'opérateur.

Source
read_disks(conn : SSH::Connection) : Array(Disk)
Source
render_yaml(host : Beryl::Config::ResolvedHost, short : String, pools : Array(PoolSpec), provider_override : String | Nil = nil, server_id_override : String | Nil = nil, scaleway_zone_override : String | Nil = nil) : String

Rend le YAML d'un host. Le fichier ne contient QUE ce qui est spécifique (provider/service_name/hostname/disques/raid). Le reste vient du merge (_default.yml, <domaine>.yml).

Niveau RAID en notation numérique (0=stripe, 1=mirror, 5=raidz, 6=raidz2, 7=raidz3, 10=mirror_stripe) — traduit en mode ZFS par Beryl::Config::Zpool.zfs_mode au moment du bootstrap.

Source
rerun_with_write(args : Array(String), short : String, raw_host : String | Nil = nil, normalized_host : String | Nil = nil) : String

Construit la commande à proposer quand beryl scan affiche un YAML en mode suggestion (pas de --write) : même args, mais en ajoutant --write et, si l'opérateur n'a pas passé --hostname, le short résolu interactivement pour éviter le re-prompt.

Source
resolve_disk_selection(all : Array(Disk), answer : String) : Array(Disk)
Source
resolve_write_target(explicit : String | Nil, auto : Bool, config_root : String, account_name : String, domain_name : String, short : String) : String | Nil
Source
run(config_root : String, args : Array(String)) : Int32
Source
run_dns_setup(host : Beryl::Config::ResolvedHost, hostname_flag : String | Nil, zone_flag : String | Nil, non_interactive : Bool, dry_run : Bool = false) : Beryl::CLI::DnsSetup::Plan

Flux --dns : prompt nom + zone, calcule le plan, applique.

Source
run_dns_setup_dedibox(host : Beryl::Config::ResolvedHost, hostname_flag : String | Nil, zone_flag : String | Nil, non_interactive : Bool, dry_run : Bool, server_id_str : String) : Beryl::CLI::DnsSetup::Plan

Variante Dedibox de run_dns_setup. Différences :

  • IPs + current_hostname viennent de l'API Dedibox (GET /server/{id}), pas OVH.
  • records A/AAAA posés via le DNS provider de la zone (typiquement OVH côté Aloli si la zone aloli.net y est hébergée). On réutilise DnsSetup.ensure_record / refresh_zone.
  • rename console : DediboxApi::Client.servers.update_hostname (API validée live 24 avril 2026).
  • reverse DNS : skip, l'API Dedibox ne l'expose pas. Warning explicite pour que l'opérateur le pose manuellement dans https://console.online.net.
Source
run_dns_setup_scaleway(host : Beryl::Config::ResolvedHost, hostname_flag : String | Nil, zone_flag : String | Nil, non_interactive : Bool, dry_run : Bool, server_id : String, zone_override : String | Nil) : Beryl::CLI::DnsSetup::Plan

Variante Scaleway de run_dns_setup. Différences vs Dedibox :

  • IPs + current_name viennent de l'API Scaleway (client.baremetal.servers.get(uuid, zone)). Si la zone n'est pas fournie explicitement (cas d'un UUID brut venu du shortcut), on la retrouve via find_any_zone.
  • Records A/AAAA posés via le DNS provider de la zone (OVH côté Aloli). Même code que Dedibox.
  • Rename console : client.baremetal.servers.update(name:). Scaleway n'a pas de séparation « nom système / nom console » comme Dedibox : le name sert de nom d'affichage dans la console et dans les logs d'install.
  • Reverse DNS : EXPOSÉ par l'API Scaleway, client.baremetal.servers.update(reverse:). Contrairement à Dedibox (qui force l'opérateur à passer par la console web), on peut le poser automatiquement.
Source
validate_pool_name!(name : String) : Nil

Valide le nom court d'un pool ZFS (sans préfixe z). Lève ArgumentError avec un message explicite sur quoi l'opérateur aurait dû taper. Utilisé à la fois côté interactif (ask_pool_short_name) et côté CLI (parse_pool_spec).

Deux checks :

  1. Format regex (lettre minuscule + [a-z0-9_]*).
  2. Noms réservés qui écraseraient un dossier système FreeBSD de premier niveau (/bin, /etc, /usr, /var, /tmp, /boot…) et casseraient l'OS. Sécurité : mieux vaut refuser que laisser l'opérateur saboter son FreeBSD au prochain boot.
Source
validate_raid!(answer : String) : Int32

Valide une chaîne RAID. Lève ArgumentError sur entrée non-numérique ou niveau inconnu.

Source

Nested types