Skip to content

libpcp_web: accept NaN/Inf in series_pmAtomValue_conv_str on float/do… #438

libpcp_web: accept NaN/Inf in series_pmAtomValue_conv_str on float/do…

libpcp_web: accept NaN/Inf in series_pmAtomValue_conv_str on float/do… #438

Workflow file for this run

name: macOS CI
on:
push:
jobs:
build:
runs-on: macos-latest
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.ref_name }}
- name: Install Homebrew
run: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- name: Wait for Homebrew install to settle
run: sleep 3
- name: Install Homebrew deps
id: install-brew-deps
run: |
PACKAGES=$(grep -v '^#' build/mac/brew-packages.txt | grep -v '^$' | tr '\n' ' ')
echo "Installing: $PACKAGES"
brew install $PACKAGES
- name: Set up Python build environment
id: install-python-deps
run: |
python3 --version
./build/mac/setup-python-env.sh build/mac/requirements-test.txt
python3 -c "import requests; print('requests', requests.__version__)"
- name: Build on macOS
id: Build
run: |
xcodebuild -version
./Makepkgs -verbose
# Validate PMID consistency
- name: Validate PMID Consistency
id: pmid-validation
if: success()
run: |
echo "Validating PMID consistency across pmns, metrics.c, and darwin.h..."
./build/mac/test/integration/test-pmid-consistency.sh
# Darwin PMDA Unit Tests (pre-installation)
- name: Run Darwin PMDA Unit Tests
id: unit-tests
if: success()
run: |
echo "Running all PMDA unit tests..."
cd build/mac/test
./run-unit-tests.sh
- name: Debug on unit test failure
if: failure() && steps.unit-tests.conclusion == 'failure'
run: |
echo "Unit tests failed. Checking build artifacts..."
find . -name "pmda_darwin.dylib" -o -name "pmdadarwin"
echo "Checking for dbpmda..."
find . -name "dbpmda"
- name: Debug on failure
if: failure() && steps.Build.conclusion == 'failure'
run: |
cat /Users/runner/work/pcp/pcp/Logs/pcp
- name: Debug on Python installation failure
if: failure() && steps.install-python-deps.conclusion == 'failure'
run: |
echo "Python installation failed. Collecting debug info..."
brew --version
brew config
brew doctor
ls -la /usr/local/bin | grep python
df -h
brew list
- name: Debug on brew dependency installation failure
if: failure() && steps.install-brew-deps.conclusion == 'failure'
run: |
echo "Dependency installation failed. Collecting debug info..."
brew --version
brew config
brew doctor
ls -la /usr/local/bin | grep python
df -h
brew list
# Start valkey before install so pmproxy can connect on startup
- name: Start valkey
run: brew services start valkey
# Installation testing steps
- name: Mount DMG and Install PKG
if: success()
id: install-test
run: |
# Find the generated DMG
DMG_PATH=$(find pcp-**/build/mac -name "pcp-*.dmg" | head -1)
echo "Found DMG: $DMG_PATH"
# Mount the DMG
MOUNT_OUTPUT=$(hdiutil attach "$DMG_PATH" | tail -1)
VOLUME_PATH=$(echo "$MOUNT_OUTPUT" | awk '{print $3}')
echo "Mounted at: $VOLUME_PATH"
# Find and install the PKG
PKG_PATH=$(find "$VOLUME_PATH" -name "*.pkg" | head -1)
echo "Found PKG: $PKG_PATH"
# Install (sudo is passwordless in GitHub Actions)
sudo installer -pkg "$PKG_PATH" -target / -verbose -dumplog
- name: Debug on install failure
if: failure() && steps.install-test.conclusion == 'failure'
run: |
echo "=== /var/log/install.log (last 100 lines) ==="
sudo tail -100 /var/log/install.log
- name: Verify Installation
if: success() && steps.install-test.conclusion == 'success'
run: |
# Check critical binaries exist (will fail build if not found)
echo "Checking for installed binaries..."
which pminfo && echo "✓ pminfo found at $(which pminfo)"
which pmval && echo "✓ pmval found at $(which pmval)"
which pmlogger && echo "✓ pmlogger found at $(which pmlogger)"
# Check for expected directories (will fail build if not found)
echo "Checking for expected directories..."
test -d /etc/pcp && echo "✓ /etc/pcp exists"
test -d /var/lib/pcp && echo "✓ /var/lib/pcp exists"
# Darwin PMDA Integration Tests (post-installation)
- name: Wait for pmcd to start
if: success() && steps.install-test.conclusion == 'success'
id: wait-for-pmcd
run: |
echo "=== Installation Verification ==="
echo "PCP installation check:"
which pmcd && echo "pmcd binary: $(which pmcd)" || echo "pmcd not in PATH"
which pminfo && echo "pminfo binary: $(which pminfo)" || echo "pminfo not in PATH"
which pcp && echo "pcp binary: $(which pcp)" || echo "pcp not in PATH"
echo ""
echo "Critical directories:"
test -d /etc/pcp && echo "✓ /etc/pcp exists" || echo "✗ /etc/pcp MISSING"
test -d /var/lib/pcp && echo "✓ /var/lib/pcp exists" || echo "✗ /var/lib/pcp MISSING"
test -d /var/log/pcp && echo "✓ /var/log/pcp exists" || echo "✗ /var/log/pcp MISSING"
test -d /var/log/pcp/pmcd && echo "✓ /var/log/pcp/pmcd exists" || echo "✗ /var/log/pcp/pmcd MISSING"
echo ""
echo "pmcd.conf contents:"
cat /etc/pcp/pmcd/pmcd.conf 2>/dev/null || echo "pmcd.conf not found"
echo ""
echo "Checking launchd plist:"
test -f /Library/LaunchDaemons/org.pcp.pmcd.plist && echo "✓ org.pcp.pmcd.plist exists" || echo "✗ org.pcp.pmcd.plist MISSING"
echo ""
echo "=== Waiting for pmcd service to start (post-install) ==="
echo "The installer should have started pmcd via launchd..."
TIMEOUT=60 # Wait up to 60 seconds
ELAPSED=0
INTERVAL=3
while [ $ELAPSED -lt $TIMEOUT ]; do
echo "Checking if pmcd is responding (${ELAPSED}s elapsed)..."
# Check if pcp command works (like in .cirrus.yml)
if pcp 2>/dev/null; then
echo "✓ pmcd service is responding!"
break
fi
# Also check if pminfo can connect
if pminfo -h localhost -f hinv.ncpu 2>/dev/null; then
echo "✓ pmcd is accepting connections!"
break
fi
sleep $INTERVAL
ELAPSED=$((ELAPSED + INTERVAL))
done
if [ $ELAPSED -ge $TIMEOUT ]; then
echo "✗ ERROR: pmcd service failed to start within $TIMEOUT seconds"
echo ""
echo "=== Diagnostic Information ==="
echo "pmcd process status:"
pgrep pmcd && echo "pmcd is running (PID: $(pgrep pmcd))" || echo "pmcd NOT running"
echo ""
echo "pmcd full process details:"
ps aux | grep pmcd | grep -v grep || echo "No pmcd process found"
echo ""
echo "pmcd command line:"
sudo ps -p $(pgrep pmcd) -o pid,ppid,user,command 2>/dev/null || echo "Cannot get process details"
echo ""
echo "pmcd network connections:"
sudo lsof -i -P | grep pmcd || echo "No network connections"
echo ""
echo "pmcd log (last 30 lines):"
sudo tail -30 /var/log/pcp/pmcd/pmcd.log 2>/dev/null || echo "No pmcd.log"
echo ""
echo "launchd plist stdout/stderr:"
sudo cat /var/log/pcp/pmcd/plist.stdout 2>/dev/null || echo "No plist.stdout"
sudo cat /var/log/pcp/pmcd/plist.stderr 2>/dev/null || echo "No plist.stderr"
exit 1
fi
echo ""
echo "=== pmcd Service Verification ==="
echo "pmcd process status:"
pgrep pmcd && echo "✓ pmcd is running (PID: $(pgrep pmcd))" || echo "✗ pmcd failed to start"
echo ""
echo "pmcd command line:"
sudo ps -p $(pgrep pmcd) -o pid,ppid,user,command || echo "Cannot get process details"
echo ""
echo "pmcd listening ports:"
sudo lsof -i -P | grep pmcd || echo "No network connections found for pmcd"
echo ""
echo "Test localhost connectivity to pmcd port (44321):"
nc -z localhost 44321 && echo "✓ Can connect to localhost:44321" || echo "✗ Cannot connect to localhost:44321"
echo ""
echo "Test 127.0.0.1 connectivity to pmcd port (44321):"
nc -z 127.0.0.1 44321 && echo "✓ Can connect to 127.0.0.1:44321" || echo "✗ Cannot connect to 127.0.0.1:44321"
- name: Run Darwin PMDA Integration Tests
id: integration-tests
if: success() && steps.wait-for-pmcd.conclusion == 'success'
run: |
echo "=== Python and pmrep debugging ==="
echo "pmrep location:"
which pmrep
head -1 $(which pmrep)
echo ""
echo "Python versions available:"
which python3 && python3 --version || echo "python3 not found"
which python && python --version || echo "python not found"
echo ""
echo "Python sys.path for pmrep's Python:"
$(head -1 $(which pmrep) | sed 's/#!//') -c "import sys; print('\n'.join(sys.path))"
echo ""
echo "Looking for pcp module:"
find /usr/local -name "pcp.py" -o -name "pcp" -type d 2>/dev/null | grep -i python || echo "No pcp module found in /usr/local"
cat python3-pcp.list || echo "Doesn't look like the Python3 installation bit triggered"
echo ""
echo "Check if pcp module is installed:"
$(head -1 $(which pmrep) | sed 's/#!//') -c "import pcp; print('pcp module location:', pcp.__file__)" 2>&1 || echo "pcp module not importable"
echo ""
echo "Running Darwin PMDA integration tests..."
cd build/mac/test/integration
./run-integration-tests.sh
- name: Test pmstat with Darwin metrics
if: success() && steps.integration-tests.conclusion == 'success'
run: |
echo "Testing pmstat output..."
cd build/mac/test/integration
./test-pmstat.sh
- name: Verify openmetrics PMDA enabled
if: success() && steps.wait-for-pmcd.conclusion == 'success'
run: |
echo "Checking openmetrics PMDA status..."
if pminfo openmetrics 2>/dev/null | head -5; then
echo "openmetrics PMDA is active"
else
echo "WARNING: openmetrics PMDA not active (may need pmcd restart for .NeedInstall processing)"
test -f /var/lib/pcp/pmdas/openmetrics/.NeedInstall && echo ".NeedInstall marker exists (pending)" || true
test -f /var/lib/pcp/pmdas/openmetrics/.NeedInstall.failed && echo ".NeedInstall.failed exists (installation failed)" || true
sudo grep -i "openmetrics\|NeedInstall\|pmda_setup" /var/log/pcp/pmcd/pmcd.log 2>/dev/null | tail -20 || true
fi
- name: Verify zeroconf pmlogconf configs installed
if: success() && steps.install-test.conclusion == 'success'
run: |
echo "Checking for zeroconf pmlogconf configs..."
if test -d /var/lib/pcp/config/pmlogconf/zeroconf; then
echo "zeroconf configs installed:"
ls /var/lib/pcp/config/pmlogconf/zeroconf/
else
echo "ERROR: zeroconf config directory not found"
exit 1
fi
- name: Wait for pmproxy to start
id: wait-for-pmproxy
if: success() && steps.integration-tests.conclusion == 'success'
run: |
echo "=== Waiting for pmproxy service to start ==="
echo "The installer should have started pmproxy via launchd..."
TIMEOUT=60
ELAPSED=0
INTERVAL=3
while [ $ELAPSED -lt $TIMEOUT ]; do
echo "Checking pmproxy (${ELAPSED}s elapsed)..."
# Check if pmproxy responds to ping
if curl -s http://localhost:44322/series/ping 2>/dev/null | grep -q '"success":true'; then
echo "✓ pmproxy is responding!"
break
fi
sleep $INTERVAL
ELAPSED=$((ELAPSED + INTERVAL))
done
echo ""
echo "=== pmproxy log files debug ==="
if [ -d /var/log/pcp/pmproxy ]; then
echo "✓ pmproxy log directory exists"
echo "Log directory contents:"
ls -la /var/log/pcp/pmproxy/ 2>/dev/null || echo "Cannot list directory"
echo ""
for logfile in /var/log/pcp/pmproxy/*.log; do
if [ -f "$logfile" ]; then
echo "=== Contents of $logfile ==="
sudo cat "$logfile" 2>/dev/null || echo "Cannot read $logfile"
echo ""
fi
done
else
echo "✗ pmproxy log directory does not exist"
fi
if [ $ELAPSED -ge $TIMEOUT ]; then
echo "✗ Timeout waiting for pmproxy"
exit 1
fi
echo ""
echo "=== pmproxy connectivity checks ==="
nc -z localhost 44322 && echo "✓ Port 44322 open" || echo "✗ Port 44322 closed"
echo ""
echo "=== pmproxy process status ==="
pgrep pmproxy && echo "✓ pmproxy running (PID: $(pgrep pmproxy))" || echo "✗ pmproxy not running"
echo ""
echo "pmproxy command line:"
sudo ps -p $(pgrep pmproxy) -o pid,ppid,user,command 2>/dev/null || echo "Cannot get process details"
echo ""
echo "pmproxy listening ports:"
sudo lsof -i -P | grep pmproxy || echo "No network connections found for pmproxy"
- name: Debug on integration test failure
if: failure() && (steps.integration-tests.conclusion == 'failure' || steps.wait-for-pmcd.conclusion == 'failure')
run: |
echo "Integration tests failed. Collecting diagnostics..."
echo "=== PCP Configuration ==="
pmconfig 2>&1 || echo "pmconfig failed"
echo ""
echo "=== pmcd.conf contents ==="
cat /etc/pcp/pmcd/pmcd.conf 2>/dev/null || echo "pmcd.conf not found"
echo ""
echo "=== pmcd status ==="
pgrep pmcd && echo "pmcd is running (PID: $(pgrep pmcd))" || echo "pmcd not running"
echo ""
echo "=== pmcd network connections ==="
sudo lsof -i -P | grep pmcd || echo "No network connections for pmcd"
echo ""
echo "=== All listening ports ==="
sudo lsof -i -P | grep LISTEN || echo "No listening ports found"
echo ""
echo "=== Connectivity tests ==="
nc -z localhost 44321 && echo "✓ localhost:44321 is reachable" || echo "✗ localhost:44321 is NOT reachable"
nc -z 127.0.0.1 44321 && echo "✓ 127.0.0.1:44321 is reachable" || echo "✗ 127.0.0.1:44321 is NOT reachable"
echo ""
echo "=== pmcd log (last 50 lines) ==="
sudo tail -50 /var/log/pcp/pmcd/pmcd.log 2>/dev/null || echo "No pmcd log found"
echo ""
echo "=== darwin PMDA log (last 50 lines) ==="
sudo tail -50 /var/log/pcp/pmcd/darwin.log 2>/dev/null || echo "No darwin PMDA log found"
echo ""
echo "=== darwin PMDA status ==="
pminfo -f pmcd.agent.status 2>/dev/null | grep darwin || echo "Darwin PMDA not loaded"
echo ""
echo "=== Available PMDAs ==="
ls -la /usr/local/lib/pcp/pmdas/ 2>/dev/null || ls -la /Library/PCP/pmdas/ 2>/dev/null || echo "PMDA directory not found"
echo ""
echo "=== Test simple metric with explicit localhost ==="
pminfo -h localhost -f hinv.ncpu 2>&1 || echo "pminfo with localhost failed"
echo ""
echo "=== Test simple metric with explicit 127.0.0.1 ==="
pminfo -h 127.0.0.1 -f hinv.ncpu 2>&1 || echo "pminfo with 127.0.0.1 failed"
echo ""
echo "=== Test simple metric with default host ==="
pminfo -f hinv.ncpu 2>&1 || echo "pminfo with default host failed"
echo ""
echo "=== PCP environment variables ==="
env | grep PCP || echo "No PCP env vars set"
- name: Cleanup - Unmount DMG
if: always()
run: |
# Unmount any mounted PCP volumes
hdiutil detach /Volumes/pcp* 2>/dev/null || true
# New steps for handling releases on version tags below
- name: Check if version tag
if: github.ref_type == 'tag'
id: check_tag
uses: actions-ecosystem/action-regex-match@v2
with:
text: ${{ github.ref_name }}
regex: '^[0-9]+\.[0-9]+\.[0-9]+$'
flags: g # Global flag, but optional if just checking match
- name: Generate Github Summary - version tag detected
if: steps.check_tag.outputs.match != ''
run: |
echo "RELEASE DETECTED!" >> $GITHUB_STEP_SUMMARY
- name: Generate Github Summary - no version tag
if: steps.check_tag.outputs.match == ''
run: |
echo "Not a Release!" >> $GITHUB_STEP_SUMMARY
- name: Release
uses: softprops/action-gh-release@v3
if: steps.check_tag.outputs.match != ''
with:
files: |
pcp-**/build/mac/pcp-*.dmg