secubox-openwrt/docs-fr/admin-control-center/EXAMPLES.md
CyberMind-FR ccfb58124c docs: Add trilingual documentation (French and Chinese translations)
Add complete French (fr) and Chinese (zh) translations for all documentation:

- Root files: README, CHANGELOG, SECURITY, BETA-RELEASE
- docs/: All 16 core documentation files
- DOCS/: All 19 deep-dive documents including embedded/ and archive/
- package/secubox/: All 123+ package READMEs
- Misc: secubox-tools/, scripts/, EXAMPLES/, config-backups/, streamlit-apps/

Total: 346 translation files created

Each file includes language switcher links for easy navigation between
English, French, and Chinese versions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-20 10:00:18 +01:00

23 KiB

SecuBox Admin Control Center - Exemples d'Utilisation

Langues: English | Francais | 中文

Exemples complets pour la gestion des etats et les operations du registre des composants.


Table des Matieres

  1. Exemples CLI
  2. Exemples de Scripts Shell
  3. Exemples Frontend JavaScript
  4. Exemples d'Integration

Exemples CLI

Gestion d'Etat CLI

Operations de Base sur les Etats

# Obtenir l'etat actuel d'un composant
secubox-state get luci-app-auth-guardian

# Definir l'etat d'un composant
secubox-state set luci-app-auth-guardian starting user_request

# Voir l'historique des etats
secubox-state history luci-app-auth-guardian 20

# Lister tous les composants en cours d'execution
secubox-state list --state=running

# Lister toutes les applications
secubox-state list --type=app

# Valider la coherence de l'etat
secubox-state validate luci-app-auth-guardian

# Synchroniser la base de donnees d'etat avec le systeme
secubox-state sync

Gestion des Erreurs

# Effacer l'etat d'erreur
secubox-state clear-error luci-app-vpn-client

# Verifier le composant apres avoir efface l'erreur
secubox-state get luci-app-vpn-client

Gel/Degel des Composants

# Geler un composant critique
secubox-state freeze luci-app-firewall system_critical

# Verifier l'etat gele
secubox-state get luci-app-firewall

# Degeler (transitionner vers actif)
secubox-state set luci-app-firewall active admin_unfreeze

Registre des Composants CLI

Enregistrement de Composants

# Enregistrer un nouveau composant application
secubox-component register my-custom-app app '{
  "name": "My Custom App",
  "packages": ["my-custom-app", "dependency-pkg"],
  "capabilities": ["custom-feature"],
  "dependencies": {
    "required": ["luci-base"],
    "optional": []
  },
  "managed_services": ["my-service"]
}'

# Enregistrer un module
secubox-component register my-module module '{
  "name": "My Module",
  "packages": ["my-module-pkg"]
}'

# Enregistrer un widget
secubox-component register my-widget widget '{
  "name": "My Dashboard Widget",
  "packages": ["luci-app-widget-provider"]
}'

Requetes sur les Composants

# Obtenir les details d'un composant
secubox-component get luci-app-auth-guardian

# Lister toutes les applications
secubox-component list --type=app

# Lister tous les composants en cours d'execution
secubox-component list --state=running

# Lister les composants d'un profil
secubox-component list --profile=home-security

# Afficher l'arbre de dependances
secubox-component tree luci-app-auth-guardian

# Afficher les dependances inverses
secubox-component affected luci-base

Gestion des Composants

# Mettre a jour un parametre de composant
secubox-component set-setting luci-app-auth-guardian enabled true

# Desenregistrer un composant
secubox-component unregister my-old-app

Workflows Courants CLI

Installation d'une Application (Workflow Complet)

#!/bin/bash

APP_ID="luci-app-vpn-client"

# 1. Verifier si le composant est enregistre
if ! secubox-component get "$APP_ID" > /dev/null 2>&1; then
    echo "Component not registered, syncing registry..."
    secubox-sync-registry apps
fi

# 2. Definir l'etat a installing
secubox-state set "$APP_ID" installing user_install

# 3. Effectuer l'installation reelle (ceci serait fait par secubox-appstore)
# opkg install luci-app-vpn-client

# 4. En cas de succes, definir a installed
secubox-state set "$APP_ID" installed install_success

# 5. Configurer l'application
secubox-state set "$APP_ID" configuring user_config

# 6. Marquer comme configured
secubox-state set "$APP_ID" configured config_complete

# 7. Activer
secubox-state set "$APP_ID" activating user_activate
secubox-state set "$APP_ID" active activation_complete

# 8. Demarrer le service
secubox-state set "$APP_ID" starting user_start

# 9. Marquer comme running
secubox-state set "$APP_ID" running start_success

Changement d'Etat en Masse

#!/bin/bash

# Arreter toutes les applications en cours d'execution
for app_id in $(secubox-state list --state=running --type=app | jq -r '.[].id'); do
    echo "Stopping $app_id..."
    secubox-state set "$app_id" stopping bulk_shutdown
    secubox-state set "$app_id" stopped shutdown_complete
done

Script de Verification de Sante

#!/bin/bash

echo "=== SecuBox Component Health Check ==="
echo

# Obtenir tous les composants
components=$(secubox-component list)

# Compter par etat
echo "Component Distribution:"
echo "  Running:     $(echo "$components" | jq '[.[] | select(.current_state=="running")] | length')"
echo "  Stopped:     $(echo "$components" | jq '[.[] | select(.current_state=="stopped")] | length')"
echo "  Error:       $(echo "$components" | jq '[.[] | select(.current_state=="error")] | length')"
echo "  Frozen:      $(echo "$components" | jq '[.[] | select(.current_state=="frozen")] | length')"
echo "  Disabled:    $(echo "$components" | jq '[.[] | select(.current_state=="disabled")] | length')"
echo

# Afficher les composants en erreur
error_count=$(echo "$components" | jq '[.[] | select(.current_state=="error")] | length')
if [ "$error_count" -gt 0 ]; then
    echo "Components in ERROR state:"
    echo "$components" | jq -r '.[] | select(.current_state=="error") | "  - \(.name) (\(.id))"'
    echo
fi

# Afficher les composants geles
frozen_count=$(echo "$components" | jq '[.[] | select(.current_state=="frozen")] | length')
if [ "$frozen_count" -gt 0 ]; then
    echo "Components in FROZEN state:"
    echo "$components" | jq -r '.[] | select(.current_state=="frozen") | "  - \(.name) (\(.id))"'
    echo
fi

# Valider tous les etats des composants
echo "Validating component states..."
invalid_count=0
for comp_id in $(echo "$components" | jq -r '.[].id'); do
    if ! secubox-state validate "$comp_id" > /dev/null 2>&1; then
        echo "  ⚠ Invalid state: $comp_id"
        invalid_count=$((invalid_count + 1))
    fi
done

if [ "$invalid_count" -eq 0 ]; then
    echo "  ✓ All component states are valid"
else
    echo "  ✗ Found $invalid_count invalid states"
fi

Exemples de Scripts Shell

Exemple: Demarrage Automatique de Toutes les Applications au Boot

#!/bin/bash
# /etc/init.d/secubox-autostart

START=99
STOP=10

start() {
    echo "Starting SecuBox components..."

    # Obtenir tous les composants actifs
    components=$(secubox-component list --state=active --type=app)

    for app_id in $(echo "$components" | jq -r '.[].id'); do
        # Verifier si auto_start est active
        auto_start=$(secubox-component get "$app_id" | jq -r '.settings.auto_start // false')

        if [ "$auto_start" = "true" ]; then
            echo "  Starting $app_id..."
            secubox-state set "$app_id" starting boot_autostart

            # Demarrer les services geres
            services=$(secubox-component get "$app_id" | jq -r '.managed_services[]')
            for service in $services; do
                /etc/init.d/"$service" start
            done

            secubox-state set "$app_id" running start_success
        fi
    done
}

stop() {
    echo "Stopping SecuBox components..."

    # Obtenir tous les composants en cours d'execution
    components=$(secubox-state list --state=running --type=app)

    for app_id in $(echo "$components" | jq -r '.[].id'); do
        echo "  Stopping $app_id..."
        secubox-state set "$app_id" stopping shutdown

        # Arreter les services geres
        services=$(secubox-component get "$app_id" | jq -r '.managed_services[]')
        for service in $services; do
            /etc/init.d/"$service" stop
        done

        secubox-state set "$app_id" stopped stop_success
    done
}

Exemple: Resolveur de Dependances de Composants

#!/bin/bash

resolve_dependencies() {
    local component_id="$1"
    local resolved=()
    local seen=()

    resolve_recursive() {
        local comp_id="$1"

        # Verifier si deja vu (dependance circulaire)
        for s in "${seen[@]}"; do
            if [ "$s" = "$comp_id" ]; then
                echo "Error: Circular dependency detected: $comp_id" >&2
                return 1
            fi
        done

        seen+=("$comp_id")

        # Obtenir les dependances requises
        local deps=$(secubox-component get "$comp_id" | jq -r '.dependencies.required[]')

        for dep in $deps; do
            resolve_recursive "$dep"
        done

        # Ajouter a la liste resolue
        resolved+=("$comp_id")
    }

    resolve_recursive "$component_id"

    # Afficher dans l'ordre d'installation
    printf '%s\n' "${resolved[@]}"
}

# Utilisation
echo "Install order for luci-app-auth-guardian:"
resolve_dependencies "luci-app-auth-guardian"

Exemple: Observateur de Transitions d'Etat

#!/bin/bash

watch_state_transitions() {
    local component_id="$1"
    local last_state=""

    echo "Watching state transitions for: $component_id"
    echo "Press Ctrl+C to stop"
    echo

    while true; do
        current_state=$(secubox-state get "$component_id" | jq -r '.current_state')

        if [ "$current_state" != "$last_state" ]; then
            timestamp=$(date "+%Y-%m-%d %H:%M:%S")
            echo "[$timestamp] State changed: $last_state -> $current_state"
            last_state="$current_state"
        fi

        sleep 1
    done
}

# Utilisation
watch_state_transitions "luci-app-vpn-client"

Exemples Frontend JavaScript

Exemple: Tableau de Bord des Composants

'use strict';
'require view';
'require secubox-admin.api as api';
'require secubox-admin.components.StateIndicator as StateIndicator';

return view.extend({
    load: function() {
        return api.getAllComponentsWithStates({ type: 'app' });
    },

    render: function(components) {
        var container = E('div', { 'class': 'component-dashboard' });

        components.forEach(function(comp) {
            var card = E('div', {
                'class': 'component-card',
                'style': 'padding: 1rem; margin-bottom: 1rem; border: 1px solid #e5e7eb; border-radius: 0.5rem;'
            });

            // Nom du composant
            var name = E('h3', {}, comp.name);
            card.appendChild(name);

            // Indicateur d'etat
            var state = comp.state_info ? comp.state_info.current_state : 'unknown';
            var stateIndicator = StateIndicator.render(state, {
                showIcon: true,
                showLabel: true
            });
            card.appendChild(stateIndicator);

            // Boutons d'action
            var actions = E('div', { 'style': 'margin-top: 1rem; display: flex; gap: 0.5rem;' });

            if (state === 'stopped') {
                var startBtn = E('button', {
                    'class': 'btn cbi-button-action',
                    'click': function() {
                        api.setComponentState(comp.id, 'starting', 'user_action')
                            .then(function() {
                                location.reload();
                            });
                    }
                }, 'Start');
                actions.appendChild(startBtn);
            } else if (state === 'running') {
                var stopBtn = E('button', {
                    'class': 'btn cbi-button-negative',
                    'click': function() {
                        api.setComponentState(comp.id, 'stopping', 'user_action')
                            .then(function() {
                                location.reload();
                            });
                    }
                }, 'Stop');
                actions.appendChild(stopBtn);
            }

            card.appendChild(actions);
            container.appendChild(card);
        });

        return container;
    }
});

Exemple: Gestionnaire de Transition d'Etat

function handleStateTransition(componentId, newState) {
    // Afficher l'indicateur de chargement
    ui.showModal(_('Changing State'), [
        E('p', { 'class': 'spinning' }, _('Updating component state...'))
    ]);

    // Valider la transition
    return api.getComponentState(componentId).then(function(stateInfo) {
        var currentState = stateInfo.current_state;

        if (!stateUtils.canTransition(currentState, newState)) {
            ui.hideModal();
            ui.addNotification(null,
                E('p', _('Invalid state transition: %s -> %s').format(currentState, newState)),
                'error'
            );
            return Promise.reject('Invalid transition');
        }

        // Executer la transition
        return api.setComponentState(componentId, newState, 'user_action');
    }).then(function(result) {
        ui.hideModal();

        if (result.success) {
            ui.addNotification(null,
                E('p', _('State changed successfully')),
                'success'
            );

            // Recharger les donnees du composant
            return api.getComponentWithState(componentId);
        } else {
            throw new Error(result.message || 'State change failed');
        }
    }).catch(function(error) {
        ui.hideModal();
        ui.addNotification(null,
            E('p', _('Error: %s').format(error.message || error)),
            'error'
        );
    });
}

// Utilisation
handleStateTransition('luci-app-vpn-client', 'starting');

Exemple: Moniteur d'Etat en Temps Reel

var StateMonitor = baseclass.extend({
    __init__: function(componentId) {
        this.componentId = componentId;
        this.pollInterval = 2000; // 2 secondes
        this.callbacks = [];
    },

    start: function() {
        var self = this;
        this.lastState = null;

        this.pollId = poll.add(function() {
            return api.getComponentState(self.componentId).then(function(stateInfo) {
                var currentState = stateInfo.current_state;

                if (currentState !== self.lastState) {
                    self.notifyChange(self.lastState, currentState, stateInfo);
                    self.lastState = currentState;
                }
            });
        }, this.pollInterval / 1000);
    },

    stop: function() {
        if (this.pollId) {
            poll.remove(this.pollId);
            this.pollId = null;
        }
    },

    onChange: function(callback) {
        this.callbacks.push(callback);
    },

    notifyChange: function(oldState, newState, stateInfo) {
        this.callbacks.forEach(function(callback) {
            callback(oldState, newState, stateInfo);
        });
    }
});

// Utilisation
var monitor = new StateMonitor('luci-app-vpn-client');

monitor.onChange(function(oldState, newState, stateInfo) {
    console.log('State changed:', oldState, '->', newState);

    // Mettre a jour l'interface
    var indicator = document.getElementById('state-indicator');
    if (indicator) {
        var newIndicator = StateIndicator.render(newState);
        indicator.replaceWith(newIndicator);
    }
});

monitor.start();

Exemple: Operations en Masse

function bulkStartComponents(componentIds) {
    ui.showModal(_('Starting Components'), [
        E('p', {}, _('Starting %d components...').format(componentIds.length)),
        E('div', { 'id': 'bulk-progress' })
    ]);

    var progressDiv = document.getElementById('bulk-progress');
    var completed = 0;
    var failed = 0;

    // Demarrer tous les composants en parallele
    return api.bulkSetComponentState(componentIds, 'starting', 'bulk_start')
        .then(function(results) {
            results.forEach(function(result, index) {
                var componentId = componentIds[index];

                if (result.success) {
                    completed++;
                    progressDiv.appendChild(
                        E('div', { 'style': 'color: #10b981;' },
                            '✓ ' + componentId
                        )
                    );
                } else {
                    failed++;
                    progressDiv.appendChild(
                        E('div', { 'style': 'color: #ef4444;' },
                            '✗ ' + componentId + ': ' + (result.error || 'Unknown error')
                        )
                    );
                }
            });

            setTimeout(function() {
                ui.hideModal();

                var message = _('Completed: %d, Failed: %d').format(completed, failed);
                ui.addNotification(null, E('p', message),
                    failed > 0 ? 'warning' : 'success'
                );
            }, 2000);
        });
}

// Utilisation
var appsToStart = ['luci-app-vpn-client', 'luci-app-firewall', 'luci-app-ddns'];
bulkStartComponents(appsToStart);

Exemples d'Integration

Exemple: Formulaire LuCI avec Conscience d'Etat

var form = new form.Map('myapp', _('My Application'));

var section = form.section(form.TypedSection, 'config');

// Ajouter l'indicateur d'etat a la section
section.load = function() {
    var self = this;

    return Promise.all([
        form.TypedSection.prototype.load.call(this),
        api.getComponentState('my-app')
    ]).then(function(results) {
        var stateInfo = results[1];

        // Ajouter les informations d'etat au titre de la section
        var stateIndicator = StateIndicator.render(stateInfo.current_state);
        var titleNode = self.titleFn ? document.querySelector('.cbi-section-node h3') : null;
        if (titleNode) {
            titleNode.appendChild(document.createTextNode(' '));
            titleNode.appendChild(stateIndicator);
        }

        return results[0];
    });
};

// Ajouter une option tenant compte de l'etat
var stateOption = section.option(form.DummyValue, '_state', _('Service State'));
stateOption.cfgvalue = function() {
    return api.getComponentState('my-app').then(function(stateInfo) {
        return StateIndicator.render(stateInfo.current_state);
    });
};

// Ajouter des boutons de controle
var controlOption = section.option(form.Button, '_control', _('Service Control'));
controlOption.inputtitle = _('Start');
controlOption.onclick = function() {
    return handleStateTransition('my-app', 'starting');
};

Exemple: Mises a Jour d'Etat via WebSocket

// Note: Necessite le support WebSocket cote backend

var StateWebSocket = baseclass.extend({
    __init__: function(url) {
        this.url = url || 'ws://localhost:8080/state-updates';
        this.ws = null;
        this.callbacks = {};
    },

    connect: function() {
        var self = this;

        this.ws = new WebSocket(this.url);

        this.ws.onopen = function() {
            console.log('State WebSocket connected');
        };

        this.ws.onmessage = function(event) {
            var data = JSON.parse(event.data);

            if (data.type === 'state_change') {
                self.handleStateChange(data);
            }
        };

        this.ws.onerror = function(error) {
            console.error('WebSocket error:', error);
        };

        this.ws.onclose = function() {
            console.log('WebSocket closed, reconnecting...');
            setTimeout(function() {
                self.connect();
            }, 5000);
        };
    },

    subscribe: function(componentId, callback) {
        if (!this.callbacks[componentId]) {
            this.callbacks[componentId] = [];
        }
        this.callbacks[componentId].push(callback);

        // Envoyer le message d'abonnement
        this.send({
            type: 'subscribe',
            component_id: componentId
        });
    },

    handleStateChange: function(data) {
        var componentId = data.component_id;
        var callbacks = this.callbacks[componentId] || [];

        callbacks.forEach(function(callback) {
            callback(data.old_state, data.new_state, data.state_info);
        });
    },

    send: function(data) {
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
            this.ws.send(JSON.stringify(data));
        }
    }
});

// Utilisation
var ws = new StateWebSocket();
ws.connect();

ws.subscribe('luci-app-vpn-client', function(oldState, newState, stateInfo) {
    console.log('Real-time update:', oldState, '->', newState);
    // Mettre a jour l'interface immediatement
});

Exemples de Tests

Exemple: Test Unitaire pour les Transitions d'Etat

describe('State Transitions', function() {
    it('should allow valid transitions', function() {
        expect(stateUtils.canTransition('stopped', 'starting')).toBe(true);
        expect(stateUtils.canTransition('starting', 'running')).toBe(true);
        expect(stateUtils.canTransition('running', 'stopping')).toBe(true);
    });

    it('should reject invalid transitions', function() {
        expect(stateUtils.canTransition('stopped', 'running')).toBe(false);
        expect(stateUtils.canTransition('available', 'running')).toBe(false);
    });

    it('should handle error transitions', function() {
        expect(stateUtils.canTransition('installing', 'error')).toBe(true);
        expect(stateUtils.canTransition('error', 'available')).toBe(true);
    });
});

Exemple: Test d'Integration

#!/bin/bash

test_component_lifecycle() {
    local app_id="test-app"

    echo "Testing component lifecycle for: $app_id"

    # 1. Enregistrer le composant
    echo "  1. Registering component..."
    secubox-component register "$app_id" app '{"name":"Test App","packages":["test-pkg"]}'

    # 2. Initialiser l'etat
    echo "  2. Initializing state..."
    secubox-state set "$app_id" available init

    # 3. Installer
    echo "  3. Installing..."
    secubox-state set "$app_id" installing test
    secubox-state set "$app_id" installed test

    # 4. Activer
    echo "  4. Activating..."
    secubox-state set "$app_id" configuring test
    secubox-state set "$app_id" configured test
    secubox-state set "$app_id" activating test
    secubox-state set "$app_id" active test

    # 5. Demarrer
    echo "  5. Starting..."
    secubox-state set "$app_id" starting test
    secubox-state set "$app_id" running test

    # 6. Arreter
    echo "  6. Stopping..."
    secubox-state set "$app_id" stopping test
    secubox-state set "$app_id" stopped test

    # 7. Desinstaller
    echo "  7. Uninstalling..."
    secubox-state set "$app_id" uninstalling test
    secubox-state set "$app_id" available test

    # 8. Nettoyage
    echo "  8. Cleaning up..."
    secubox-component unregister "$app_id"

    echo "✓ Lifecycle test completed successfully"
}

test_component_lifecycle

Voir Aussi:


Version: 1.0 Derniere Mise a Jour: 2026-01-05