-
Notifications
You must be signed in to change notification settings - Fork 2
feat: Implement interface monitoring setup and cleanup #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,195 @@ | ||
| --- | ||
| - name: Create interface monitor directory | ||
| file: | ||
| path: "/mnt/interface-monitor" | ||
| state: directory | ||
| mode: "0755" | ||
|
|
||
| - name: Create log file with correct ownership and permissions | ||
| file: | ||
| path: "/var/log/interface_monitor.log" | ||
| state: touch | ||
| owner: root | ||
| group: root | ||
| mode: "0644" | ||
|
|
||
| - name: Create interface monitoring script | ||
| copy: | ||
| dest: "/mnt/interface-monitor/monitor_interfaces.sh" | ||
| content: | | ||
| #!/bin/bash | ||
| # Network Interface Monitor Script | ||
| # Monitors USB-to-Ethernet adapters and brings them up if they're down | ||
| # Interfaces: {{ interfaces | join(', ') }} | ||
|
|
||
| # Configuration | ||
| INTERFACES=({{ interfaces | map('quote') | join(' ') }}) | ||
|
Comment on lines
+16
to
+26
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chainVerify the Line 26 uses Confirm that:
To verify this, check if the interfaces variable is defined by searching the playbook context: 🏁 Script executed: #!/bin/bash
# Search for where `interfaces` variable is defined or passed in Ansible files
# Look for variable definitions in defaults, vars, or task invocations
find backend/control_center/ansible -name "*.yml" -o -name "*.yaml" | xargs rg -n "interfaces:" -A 2 -B 2Length of output: 0 🏁 Script executed: #!/bin/bash
# 1. Verify the monitoring task file exists
echo "=== Checking if monitoring task file exists ==="
ls -la backend/control_center/ansible/roles/ovs-port-setup/tasks/setup_interface_monitoring.yml 2>&1
# 2. Search for "interfaces" more broadly (without colon requirement)
echo -e "\n=== Searching for 'interfaces' pattern in Ansible files ==="
find backend/control_center/ansible -type f \( -name "*.yml" -o -name "*.yaml" \) -exec rg -l "interfaces" {} \;
# 3. Check role structure for defaults and vars
echo -e "\n=== Role defaults/main.yml content ==="
if [ -f "backend/control_center/ansible/roles/ovs-port-setup/defaults/main.yml" ]; then
cat backend/control_center/ansible/roles/ovs-port-setup/defaults/main.yml
else
echo "File not found"
fi
echo -e "\n=== Role vars/main.yml content ==="
if [ -f "backend/control_center/ansible/roles/ovs-port-setup/vars/main.yml" ]; then
cat backend/control_center/ansible/roles/ovs-port-setup/vars/main.yml
else
echo "File not found"
fi
# 4. Search for playbooks that might call this role
echo -e "\n=== Searching for playbook files that call ovs-port-setup role ==="
find backend/control_center/ansible -type f -name "*.yml" -o -name "*.yaml" | xargs rg -l "ovs-port-setup" | head -10Length of output: 1173 🏁 Script executed: #!/bin/bash
# 1. Read the main playbook to understand how the role is invoked
echo "=== Main playbook: ovs-port-setup.yml ==="
cat backend/control_center/ansible/playbooks/ovs-port-setup.yml
# 2. Check role's tasks/main.yml if it exists
echo -e "\n=== Role tasks/main.yml ==="
if [ -f "backend/control_center/ansible/roles/ovs-port-setup/tasks/main.yml" ]; then
cat backend/control_center/ansible/roles/ovs-port-setup/tasks/main.yml
else
echo "File not found"
fi
# 3. Check add_ports.yml to see how it references interfaces
echo -e "\n=== Role add_ports.yml (first 50 lines) ==="
head -50 backend/control_center/ansible/roles/ovs-port-setup/tasks/add_ports.yml
# 4. Check the full setup_interface_monitoring.yml to see context of interfaces usage
echo -e "\n=== Full setup_interface_monitoring.yml ==="
cat backend/control_center/ansible/roles/ovs-port-setup/tasks/setup_interface_monitoring.ymlLength of output: 6571 🏁 Script executed: #!/bin/bash
# Check for group_vars and host_vars directories
echo "=== Searching for group_vars and host_vars ==="
find backend/control_center/ansible -type d -name "group_vars" -o -type d -name "host_vars"
echo -e "\n=== Content of group_vars directories ==="
find backend/control_center/ansible -path "*group_vars*" -type f | head -20
echo -e "\n=== Content of host_vars directories ==="
find backend/control_center/ansible -path "*host_vars*" -type f | head -20
echo -e "\n=== Searching for interfaces variable definition in all yml/yaml files ==="
rg -n "^\s*interfaces\s*:" backend/control_center/ansible --type yaml -C 3 | head -100
echo -e "\n=== Check inventory files ==="
find backend/control_center/ansible -name "inventory*" -o -name "hosts*" | head -10Length of output: 238 The Verification found that
Without this variable, the Jinja template will produce an empty or malformed INTERFACES array, and the monitoring script will be non-functional. The Required action: Define 🤖 Prompt for AI Agents |
||
| LOG_FILE="/var/log/interface_monitor.log" | ||
| LOCK_FILE="/var/run/interface_monitor.lock" | ||
|
|
||
| # Function to log messages with timestamp | ||
| log_message() { | ||
| echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE" 2>/dev/null | ||
| } | ||
|
|
||
| # Function to check if interface is up | ||
| is_interface_up() { | ||
| local interface="$1" | ||
| # Check if interface exists and is UP | ||
| if ip link show "$interface" 2>/dev/null | grep -q "state UP"; then | ||
| return 0 # Interface is up | ||
| else | ||
| return 1 # Interface is down | ||
| fi | ||
| } | ||
|
|
||
| # Function to bring interface up | ||
| bring_interface_up() { | ||
| local interface="$1" | ||
| log_message "Attempting to bring up interface: $interface" | ||
|
|
||
| # Try to bring the interface up | ||
| if ip link set "$interface" up 2>/dev/null; then | ||
| # Wait a moment for the interface to stabilize | ||
| sleep 2 | ||
|
|
||
| # Check if it's actually up now | ||
| if is_interface_up "$interface"; then | ||
| log_message "SUCCESS: Interface $interface is now UP" | ||
| return 0 | ||
| else | ||
| log_message "WARNING: Interface $interface command succeeded but interface still appears down" | ||
| return 1 | ||
| fi | ||
| else | ||
| log_message "ERROR: Failed to bring up interface $interface" | ||
| return 1 | ||
| fi | ||
| } | ||
|
|
||
| # Function to check if script is already running | ||
| check_lock() { | ||
| if [ -f "$LOCK_FILE" ]; then | ||
| local pid=$(cat "$LOCK_FILE") | ||
| if kill -0 "$pid" 2>/dev/null; then | ||
| log_message "WARNING: Monitor script already running (PID: $pid)" | ||
| exit 1 | ||
| else | ||
| # Lock file exists but process is dead, remove it | ||
| rm -f "$LOCK_FILE" | ||
| fi | ||
| fi | ||
| } | ||
|
|
||
| # Function to create lock file | ||
| create_lock() { | ||
| echo $$ > "$LOCK_FILE" | ||
| } | ||
|
|
||
| # Function to cleanup lock file | ||
| cleanup() { | ||
| rm -f "$LOCK_FILE" | ||
| exit 0 | ||
| } | ||
|
|
||
| # Set up signal handlers for cleanup | ||
| trap cleanup EXIT INT TERM | ||
|
|
||
| # Main monitoring function | ||
| main() { | ||
| # Check for lock file to prevent multiple instances | ||
| check_lock | ||
| create_lock | ||
|
|
||
| log_message "Starting interface monitoring check" | ||
|
|
||
| local interfaces_brought_up=0 | ||
|
|
||
| # Check each interface | ||
| for interface in "${INTERFACES[@]}"; do | ||
| if is_interface_up "$interface"; then | ||
| log_message "Interface $interface is UP - OK" | ||
| else | ||
| log_message "Interface $interface is DOWN - attempting to bring up" | ||
| if bring_interface_up "$interface"; then | ||
| ((interfaces_brought_up++)) | ||
| fi | ||
| fi | ||
| done | ||
|
|
||
| # Summary | ||
| if [ $interfaces_brought_up -gt 0 ]; then | ||
| log_message "SUMMARY: Brought up $interfaces_brought_up interface(s)" | ||
| else | ||
| log_message "SUMMARY: All interfaces are UP - no action needed" | ||
| fi | ||
|
|
||
| log_message "Interface monitoring check completed" | ||
| } | ||
|
|
||
| # Run main function (redirect all output to /dev/null to avoid console output) | ||
| main "$@" > /dev/null 2>&1 | ||
| mode: "0755" | ||
|
|
||
| - name: Create systemd service file for interface monitor | ||
| copy: | ||
| dest: "/etc/systemd/system/interface-monitor.service" | ||
| content: | | ||
| [Unit] | ||
| Description=Network Interface Monitor | ||
| Documentation=Monitor USB-to-Ethernet adapters and bring them up if down | ||
| After=network.target | ||
|
|
||
| [Service] | ||
| Type=oneshot | ||
| ExecStart=/mnt/interface-monitor/monitor_interfaces.sh | ||
| User=root | ||
| StandardOutput=journal | ||
| StandardError=journal | ||
|
|
||
| [Install] | ||
| WantedBy=multi-user.target | ||
| mode: "0644" | ||
|
|
||
| - name: Create systemd timer file for interface monitor | ||
| copy: | ||
| dest: "/etc/systemd/system/interface-monitor.timer" | ||
| content: | | ||
| [Unit] | ||
| Description=Network Interface Monitor Timer | ||
| Requires=interface-monitor.service | ||
|
|
||
| [Timer] | ||
| OnBootSec=30s | ||
| OnUnitActiveSec=30s | ||
| Persistent=true | ||
|
|
||
| [Install] | ||
| WantedBy=timers.target | ||
| mode: "0644" | ||
|
|
||
| - name: Create logrotate configuration for interface monitor | ||
| copy: | ||
| dest: "/etc/logrotate.d/interface-monitor" | ||
| content: | | ||
| /var/log/interface_monitor.log { | ||
| daily | ||
| rotate 7 | ||
| compress | ||
| delaycompress | ||
| missingok | ||
| notifempty | ||
| create 644 root root | ||
| maxsize 3M | ||
| } | ||
| mode: "0644" | ||
|
|
||
| - name: Reload systemd to pick up new service and timer files | ||
| ansible.builtin.systemd: | ||
| daemon_reload: yes | ||
|
|
||
| - name: Enable and start interface monitor timer | ||
| ansible.builtin.systemd: | ||
| name: "interface-monitor.timer" | ||
| enabled: yes | ||
| state: started | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add blank line at end of file.
Missing blank line at end of file. POSIX convention and most linters expect files to end with a newline character.
Apply this diff:
📝 Committable suggestion
🧰 Tools
🪛 dotenv-linter (4.0.0)
[warning] 53-53: [EndingBlankLine] No blank line at the end of the file
(EndingBlankLine)
🤖 Prompt for AI Agents