# Onoxsoft Sysapi Bash Wrapper Scripts

Production bash scripts called by the PHP `SudoBashSysapi` adapter via `sudo`.
Each script reads JSON from stdin, performs real Linux operations, and emits
a JSON result to stdout. All scripts live at `/usr/local/onoxsoft/bin/`.

---

## Install Location

```
/usr/local/onoxsoft/bin/onx-*
/usr/local/onoxsoft/bin/_lib/common.sh
```

## Deployment Steps

```bash
# 1. Copy scripts
rsync -av scripts/sysapi/ /usr/local/onoxsoft/bin/

# 2. Set ownership and permissions
chown -R root:apache /usr/local/onoxsoft/bin/
chmod 750 /usr/local/onoxsoft/bin/onx-*
chmod 640 /usr/local/onoxsoft/bin/_lib/common.sh

# 3. Ensure log directory exists
mkdir -p /var/log/onox
chown root:apache /var/log/onox
chmod 770 /var/log/onox

# 4. XFS quota — ensure /home is mounted with quota enabled
# In /etc/fstab, the /home entry must include: usrquota,grpquota
# e.g.: /dev/sdb1 /home xfs defaults,usrquota,grpquota 0 0
# Remount or reboot, then: quotacheck -cum /home; quotaon /home

# 5. Create onox skel directory
mkdir -p /etc/skel/onox
# Populate with default dotfiles (.bashrc, .bash_profile, etc.)

# 6. Create onoxsoft-users group
groupadd onoxsoft-users 2>/dev/null || true
```

## Sudoers Entry

Create `/etc/sudoers.d/onoxsoft` with the following content (use `visudo -f`):

```sudoers
apache ALL=(root) NOPASSWD: /usr/local/onoxsoft/bin/onx-*
Defaults!/usr/local/onoxsoft/bin/onx-* !requiretty
Defaults!/usr/local/onoxsoft/bin/onx-* log_output, log_input
```

## Dependencies

All scripts require the following to be installed on the server:

| Tool        | Package (AlmaLinux 9)     | Used by                            |
|-------------|---------------------------|------------------------------------|
| `jq`        | `jq`                      | all scripts (JSON parsing)         |
| `useradd`   | `shadow-utils`            | onx-user-add                       |
| `usermod`   | `shadow-utils`            | onx-user-suspend, onx-user-unsuspend |
| `userdel`   | `shadow-utils`            | onx-user-terminate                 |
| `setquota`  | `quota`                   | onx-user-add, onx-quota-apply      |
| `repquota`  | `quota`                   | onx-quota-check                    |
| `chpasswd`  | `shadow-utils`            | onx-user-password                  |
| `pure-pw`   | `pure-ftpd`               | onx-user-password (FTP scope)      |
| `htpasswd`  | `httpd-tools`             | onx-user-password (webdisk scope)  |
| `mysql`     | `mariadb`                 | onx-user-terminate (DB cleanup)    |
| `tar`       | `tar`                     | onx-user-terminate (backup)        |
| `mysqldump` | `mariadb`                 | onx-backup-run, onx-snapshot-create |
| `sha256sum` | `coreutils`               | onx-backup-run, onx-backup-restore, onx-snapshot-* |
| `rsync`     | `rsync`                   | onx-backup-restore, onx-snapshot-* |
| `realpath`  | `coreutils`               | path validation in backup/snapshot |
| `cronie`    | `cronie` (Debian: `cron`) | onx-cron-write (daemon reload)     |

```bash
# Install all at once
dnf install -y jq shadow-utils quota pure-ftpd httpd-tools mariadb tar rsync coreutils cronie
```

### Filesystem layout

```
/var/backups/onoxsoft/             # owned root:root, mode 0700
    onx_<user>-<ts>.tar.gz         # account archives (mode 0600)
    onx_<user>-<ts>.tar.gz.sha256  # checksum sidecar
    snapshots/                     # cpmove-format exports (optional)
/etc/cron.d/onoxsoft-<user>        # cron.d managed by onx-cron-write (0644)
/etc/onoxsoft/secrets.env          # MySQL credentials (root:root 0600)
```

## Script Reference

| Script              | Purpose                                         |
|---------------------|-------------------------------------------------|
| `onx-user-add`      | Create Linux user, home structure, XFS quota    |
| `onx-user-suspend`  | Lock password, disable shell, move vhosts       |
| `onx-user-unsuspend`| Reverse suspension                              |
| `onx-user-terminate`| Remove user, data, vhosts, DBs (with backup)    |
| `onx-user-password` | Reset Linux / FTP / WebDAV passwords            |
| `onx-quota-apply`   | Set XFS block+inode quota for /home             |
| `onx-quota-check`   | Query current quota usage from repquota         |
| `onx-backup-run`    | Create per-account tar.gz (home + dbs + mail + dns) |
| `onx-backup-restore`| Restore from a previously created backup tar.gz |
| `onx-backup-list`   | Enumerate backups (size, mtime, sha256, owner)  |
| `onx-backup-prune`  | Retention policy (keep_count + keep_days)       |
| `onx-snapshot-create`| Export account in cpmove (cPanel) / onoxsoft format |
| `onx-snapshot-restore`| Import a cpmove or onoxsoft snapshot          |
| `onx-cron-write`    | Write /etc/cron.d/onoxsoft-<user> + reload cron |

## Exit Code Semantics

| Code | Meaning                                      |
|------|----------------------------------------------|
| 0    | Success                                      |
| 1    | Invalid input (regex / missing required field)|
| 2    | Preflight fail (dependency missing, etc.)    |
| 3    | Execution fail                               |
| 4    | Execution fail + rollback succeeded          |
| 5    | Execution fail + rollback FAILED (critical)  |

## Logging

All operations are appended to `/var/log/onox/sysapi.log` in UTC ISO8601 format:

```
[2026-05-13T10:00:00Z] [onx-user-add] useradd OK: onx_demo01
[2026-05-13T10:00:01Z] [onx-user-add] quota applied: 2048MB soft / 2252MB hard
```

## Testing (Manual)

```bash
# Test onx-user-add
echo '{"username":"onx_test01","email":"test@example.com","package":"starter","uid":null}' \
  | sudo /usr/local/onoxsoft/bin/onx-user-add

# Test onx-quota-check
echo '{"username":"onx_test01"}' \
  | sudo /usr/local/onoxsoft/bin/onx-quota-check
```
