Skip to content

Commit b2afa0f

Browse files
committed
chore: linting and readme
1 parent c9203dd commit b2afa0f

4 files changed

Lines changed: 340 additions & 6 deletions

File tree

README.md

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
Stop hand-editing YAML. Build observability pipelines with drag-and-drop<br>and deploy them across your entire fleet from a single dashboard.
1818

19-
[Quick Start](#-quick-start) · [Features](#-features) · [Configuration](#%EF%B8%8F-configuration) · [Development](#-development)
19+
[Quick Start](#-quick-start) · [Deployment](#-deployment) · [Features](#-features) · [Configuration](#%EF%B8%8F-configuration) · [Development](#-development)
2020

2121
</div>
2222

@@ -158,6 +158,87 @@ VF_URL=http://your-server:3000 VF_TOKEN=<token> ./vf-agent
158158

159159
Your pipeline is now running across all enrolled nodes.
160160

161+
## 📦 Deployment
162+
163+
### Server
164+
165+
Run the VectorFlow server with Docker Compose:
166+
167+
```bash
168+
cd vectorflow/docker/server
169+
docker compose up -d
170+
```
171+
172+
See [Configuration → Server](#%EF%B8%8F-configuration) for all available environment variables.
173+
174+
### Agent
175+
176+
#### Option A: Docker
177+
178+
The simplest way to run the agent — ideal for containerized environments:
179+
180+
```bash
181+
cd vectorflow/docker/agent
182+
183+
cat > .env << 'EOF'
184+
VF_URL=http://your-vectorflow-server:3000
185+
VF_TOKEN=paste-enrollment-token-here
186+
EOF
187+
188+
docker compose up -d
189+
```
190+
191+
#### Option B: Standalone Binary (Linux)
192+
193+
Install the agent as a native systemd service. The install script downloads the agent binary, installs Vector if needed, and configures everything automatically:
194+
195+
```bash
196+
curl -sSfL https://raw.githubusercontent.com/TerrifiedBug/vectorflow/main/agent/install.sh | \
197+
sudo bash -s -- --url https://vectorflow.example.com --token <enrollment-token>
198+
```
199+
200+
**Managing the service:**
201+
202+
```bash
203+
systemctl status vf-agent # Check status
204+
journalctl -u vf-agent -f # Follow logs
205+
sudo systemctl restart vf-agent # Restart
206+
```
207+
208+
**Upgrading:**
209+
210+
```bash
211+
# Upgrade to the latest release
212+
curl -sSfL https://raw.githubusercontent.com/TerrifiedBug/vectorflow/main/agent/install.sh | sudo bash
213+
214+
# Install a specific version
215+
curl -sSfL https://raw.githubusercontent.com/TerrifiedBug/vectorflow/main/agent/install.sh | \
216+
sudo bash -s -- --version v0.3.0
217+
```
218+
219+
Existing configuration at `/etc/vectorflow/agent.env` is preserved during upgrades.
220+
221+
**Uninstalling:**
222+
223+
```bash
224+
sudo systemctl stop vf-agent
225+
sudo systemctl disable vf-agent
226+
sudo rm /etc/systemd/system/vf-agent.service
227+
sudo systemctl daemon-reload
228+
sudo rm /usr/local/bin/vf-agent
229+
sudo rm -rf /var/lib/vf-agent /etc/vectorflow
230+
```
231+
232+
#### Option C: Manual Binary
233+
234+
Download the binary from [Releases](https://github.com/TerrifiedBug/vectorflow/releases) and run it directly:
235+
236+
```bash
237+
VF_URL=http://your-server:3000 VF_TOKEN=<token> ./vf-agent
238+
```
239+
240+
See [Configuration → Agent](#%EF%B8%8F-configuration) for all available environment variables.
241+
161242
## 🛠️ Tech Stack
162243

163244
| Layer | Technology |

agent/install.sh

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
#!/usr/bin/env bash
2+
# VectorFlow Agent Installer
3+
# Usage: curl -sSfL https://raw.githubusercontent.com/TerrifiedBug/vectorflow/main/agent/install.sh | sudo bash -s -- [OPTIONS]
4+
5+
set -euo pipefail
6+
7+
REPO="TerrifiedBug/vectorflow"
8+
INSTALL_DIR="/usr/local/bin"
9+
DATA_DIR="/var/lib/vf-agent"
10+
VECTOR_DATA_DIR="/var/lib/vector"
11+
CONFIG_DIR="/etc/vectorflow"
12+
ENV_FILE="${CONFIG_DIR}/agent.env"
13+
SERVICE_NAME="vf-agent"
14+
VECTOR_VERSION="0.44.0"
15+
16+
# Defaults
17+
VF_URL=""
18+
VF_TOKEN=""
19+
VERSION="latest"
20+
21+
# ─────────────────────────────────────────────────
22+
# Helpers
23+
# ─────────────────────────────────────────────────
24+
25+
info() { printf '\033[1;34m[info]\033[0m %s\n' "$*"; }
26+
ok() { printf '\033[1;32m[ok]\033[0m %s\n' "$*"; }
27+
warn() { printf '\033[1;33m[warn]\033[0m %s\n' "$*"; }
28+
fatal() { printf '\033[1;31m[error]\033[0m %s\n' "$*" >&2; exit 1; }
29+
30+
usage() {
31+
cat <<'EOF'
32+
VectorFlow Agent Installer
33+
34+
Usage:
35+
curl -sSfL https://raw.githubusercontent.com/TerrifiedBug/vectorflow/main/agent/install.sh | \
36+
sudo bash -s -- [OPTIONS]
37+
38+
Options:
39+
--url <url> VectorFlow server URL (e.g. https://vectorflow.example.com)
40+
--token <token> One-time enrollment token from the VectorFlow UI
41+
--version <tag> Release version to install (default: latest)
42+
--help Show this help message
43+
44+
Examples:
45+
# Fresh install
46+
curl -sSfL .../install.sh | sudo bash -s -- --url https://vf.example.com --token abc123
47+
48+
# Upgrade to latest
49+
curl -sSfL .../install.sh | sudo bash
50+
51+
# Install specific version
52+
curl -sSfL .../install.sh | sudo bash -s -- --version v0.3.0
53+
EOF
54+
exit 0
55+
}
56+
57+
# ─────────────────────────────────────────────────
58+
# Argument parsing
59+
# ─────────────────────────────────────────────────
60+
61+
while [ $# -gt 0 ]; do
62+
case "$1" in
63+
--url) VF_URL="$2"; shift 2 ;;
64+
--token) VF_TOKEN="$2"; shift 2 ;;
65+
--version) VERSION="$2"; shift 2 ;;
66+
--help) usage ;;
67+
*) fatal "Unknown option: $1 (use --help for usage)" ;;
68+
esac
69+
done
70+
71+
# ─────────────────────────────────────────────────
72+
# Preflight checks
73+
# ─────────────────────────────────────────────────
74+
75+
info "Running preflight checks..."
76+
77+
[ "$(uname -s)" = "Linux" ] || fatal "This installer only supports Linux"
78+
[ "$(id -u)" -eq 0 ] || fatal "Please run as root (use sudo)"
79+
command -v curl >/dev/null || fatal "curl is required but not found"
80+
command -v systemctl >/dev/null || fatal "systemd is required but not found"
81+
82+
# ─────────────────────────────────────────────────
83+
# Detect architecture
84+
# ─────────────────────────────────────────────────
85+
86+
UNAME_ARCH="$(uname -m)"
87+
case "${UNAME_ARCH}" in
88+
x86_64) ARCH="amd64" ;;
89+
aarch64) ARCH="arm64" ;;
90+
arm64) ARCH="arm64" ;;
91+
*) fatal "Unsupported architecture: ${UNAME_ARCH}" ;;
92+
esac
93+
info "Detected architecture: ${ARCH}"
94+
95+
# ─────────────────────────────────────────────────
96+
# Resolve version
97+
# ─────────────────────────────────────────────────
98+
99+
if [ "${VERSION}" = "latest" ]; then
100+
info "Resolving latest release..."
101+
VERSION=$(curl -sSf "https://api.github.com/repos/${REPO}/releases/latest" \
102+
| grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/')
103+
[ -n "${VERSION}" ] || fatal "Could not determine latest release version"
104+
fi
105+
info "Target version: ${VERSION}"
106+
107+
# ─────────────────────────────────────────────────
108+
# Download and verify agent binary
109+
# ─────────────────────────────────────────────────
110+
111+
BINARY_NAME="vf-agent-linux-${ARCH}"
112+
DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${VERSION}/${BINARY_NAME}"
113+
CHECKSUM_URL="https://github.com/${REPO}/releases/download/${VERSION}/checksums.txt"
114+
115+
TMPDIR=$(mktemp -d)
116+
trap 'rm -rf "${TMPDIR}"' EXIT
117+
118+
info "Downloading ${BINARY_NAME}..."
119+
curl -sSfL -o "${TMPDIR}/${BINARY_NAME}" "${DOWNLOAD_URL}" \
120+
|| fatal "Failed to download binary from ${DOWNLOAD_URL}"
121+
122+
info "Verifying checksum..."
123+
curl -sSfL -o "${TMPDIR}/checksums.txt" "${CHECKSUM_URL}" \
124+
|| fatal "Failed to download checksums from ${CHECKSUM_URL}"
125+
126+
(cd "${TMPDIR}" && grep "${BINARY_NAME}" checksums.txt | sha256sum -c --quiet) \
127+
|| fatal "Checksum verification failed — aborting"
128+
ok "Checksum verified"
129+
130+
# ─────────────────────────────────────────────────
131+
# Install agent binary
132+
# ─────────────────────────────────────────────────
133+
134+
info "Installing vf-agent to ${INSTALL_DIR}..."
135+
install -m 755 "${TMPDIR}/${BINARY_NAME}" "${INSTALL_DIR}/vf-agent"
136+
ok "Installed vf-agent $(${INSTALL_DIR}/vf-agent --version 2>/dev/null || echo "${VERSION}")"
137+
138+
# ─────────────────────────────────────────────────
139+
# Install Vector (if not present)
140+
# ─────────────────────────────────────────────────
141+
142+
if command -v vector >/dev/null; then
143+
ok "Vector already installed: $(vector --version 2>/dev/null || echo 'unknown version')"
144+
else
145+
info "Vector not found — installing v${VECTOR_VERSION}..."
146+
147+
case "${ARCH}" in
148+
amd64) VECTOR_ARCH="x86_64" ;;
149+
arm64) VECTOR_ARCH="aarch64" ;;
150+
esac
151+
152+
VECTOR_TARBALL="vector-${VECTOR_VERSION}-${VECTOR_ARCH}-unknown-linux-musl.tar.gz"
153+
VECTOR_URL="https://packages.timber.io/vector/${VECTOR_VERSION}/${VECTOR_TARBALL}"
154+
155+
curl -sSfL -o "${TMPDIR}/${VECTOR_TARBALL}" "${VECTOR_URL}" \
156+
|| fatal "Failed to download Vector from ${VECTOR_URL}"
157+
158+
tar -xzf "${TMPDIR}/${VECTOR_TARBALL}" -C "${TMPDIR}"
159+
VECTOR_DIR=$(find "${TMPDIR}" -maxdepth 1 -type d -name "vector-*" | head -1)
160+
[ -d "${VECTOR_DIR}" ] || fatal "Could not find extracted Vector directory"
161+
162+
install -m 755 "${VECTOR_DIR}/bin/vector" "${INSTALL_DIR}/vector"
163+
ok "Installed Vector v${VECTOR_VERSION}"
164+
fi
165+
166+
# ─────────────────────────────────────────────────
167+
# Create directories
168+
# ─────────────────────────────────────────────────
169+
170+
info "Creating directories..."
171+
install -d -m 0700 "${DATA_DIR}"
172+
install -d -m 0755 "${VECTOR_DATA_DIR}"
173+
install -d -m 0755 "${CONFIG_DIR}"
174+
175+
# ─────────────────────────────────────────────────
176+
# Write environment file (preserve on upgrade)
177+
# ─────────────────────────────────────────────────
178+
179+
if [ -f "${ENV_FILE}" ]; then
180+
warn "Existing ${ENV_FILE} found — preserving (edit manually to change settings)"
181+
else
182+
info "Writing ${ENV_FILE}..."
183+
cat > "${ENV_FILE}" <<ENVEOF
184+
# VectorFlow Agent Configuration
185+
# See: https://github.com/${REPO}#agent
186+
187+
VF_URL=${VF_URL}
188+
VF_TOKEN=${VF_TOKEN}
189+
VF_DATA_DIR=${DATA_DIR}
190+
VF_VECTOR_BIN=${INSTALL_DIR}/vector
191+
ENVEOF
192+
chmod 0600 "${ENV_FILE}"
193+
ok "Environment file written"
194+
195+
if [ -z "${VF_URL}" ]; then
196+
warn "VF_URL is empty — edit ${ENV_FILE} before starting the service"
197+
fi
198+
fi
199+
200+
# ─────────────────────────────────────────────────
201+
# Write systemd unit
202+
# ─────────────────────────────────────────────────
203+
204+
info "Writing systemd unit..."
205+
cat > "/etc/systemd/system/${SERVICE_NAME}.service" <<'UNITEOF'
206+
[Unit]
207+
Description=VectorFlow Agent
208+
Documentation=https://github.com/TerrifiedBug/vectorflow
209+
After=network-online.target
210+
Wants=network-online.target
211+
212+
[Service]
213+
Type=simple
214+
EnvironmentFile=/etc/vectorflow/agent.env
215+
ExecStart=/usr/local/bin/vf-agent
216+
Restart=on-failure
217+
RestartSec=5
218+
KillMode=mixed
219+
KillSignal=SIGTERM
220+
TimeoutStopSec=30
221+
LimitNOFILE=65536
222+
223+
[Install]
224+
WantedBy=multi-user.target
225+
UNITEOF
226+
227+
# ─────────────────────────────────────────────────
228+
# Enable and start service
229+
# ─────────────────────────────────────────────────
230+
231+
info "Enabling and starting ${SERVICE_NAME}..."
232+
systemctl daemon-reload
233+
systemctl enable "${SERVICE_NAME}" --quiet
234+
systemctl restart "${SERVICE_NAME}"
235+
236+
# ─────────────────────────────────────────────────
237+
# Done
238+
# ─────────────────────────────────────────────────
239+
240+
echo ""
241+
ok "VectorFlow Agent installed successfully!"
242+
echo ""
243+
echo " Service status: systemctl status ${SERVICE_NAME}"
244+
echo " Follow logs: journalctl -u ${SERVICE_NAME} -f"
245+
echo " Configuration: ${ENV_FILE}"
246+
echo " Restart: systemctl restart ${SERVICE_NAME}"
247+
echo ""
248+
249+
if [ -z "${VF_URL}" ] && [ ! -f "${ENV_FILE}" ]; then
250+
warn "Don't forget to set VF_URL and VF_TOKEN in ${ENV_FILE}, then restart:"
251+
echo " sudo systemctl restart ${SERVICE_NAME}"
252+
echo ""
253+
fi

src/components/dashboard/metric-chart.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ export function MetricChart({
217217
<ChartTooltip
218218
content={
219219
<ChartTooltipContent
220-
labelFormatter={(_value, payload) => {
220+
labelFormatter={(_value: string, payload: Array<{ payload?: { t?: number } }>) => {
221221
const timestamp = payload?.[0]?.payload?.t;
222222
if (!timestamp) return "";
223223
return new Date(Number(timestamp)).toLocaleTimeString([], {
@@ -226,7 +226,7 @@ export function MetricChart({
226226
second: "2-digit",
227227
});
228228
}}
229-
formatter={(value, name) => (
229+
formatter={(value: number | string, name: string) => (
230230
<div className="flex w-full items-center justify-between gap-2">
231231
<span className="text-muted-foreground">
232232
{chartConfig[name as string]?.label ?? name}

src/components/fleet/node-metrics-charts.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ export function NodeMetricsCharts({ nodeId }: NodeMetricsChartsProps) {
232232
<ChartTooltip
233233
content={
234234
<ChartTooltipContent
235-
formatter={(value, name) => (
235+
formatter={(value: number | string, name: string) => (
236236
<div className="flex w-full items-center justify-between gap-2">
237237
<span className="text-muted-foreground">{cpuChartConfig[name as keyof typeof cpuChartConfig]?.label ?? name}</span>
238238
<span className="font-mono font-medium text-foreground">{formatPercent(Number(value) ?? 0)}</span>
@@ -276,7 +276,7 @@ export function NodeMetricsCharts({ nodeId }: NodeMetricsChartsProps) {
276276
<ChartTooltip
277277
content={
278278
<ChartTooltipContent
279-
formatter={(value, name) => (
279+
formatter={(value: number | string, name: string) => (
280280
<div className="flex w-full items-center justify-between gap-2">
281281
<span className="text-muted-foreground">{memoryChartConfig[name as keyof typeof memoryChartConfig]?.label ?? name}</span>
282282
<span className="font-mono font-medium text-foreground">{formatPercent(Number(value) ?? 0)}</span>
@@ -319,7 +319,7 @@ export function NodeMetricsCharts({ nodeId }: NodeMetricsChartsProps) {
319319
<ChartTooltip
320320
content={
321321
<ChartTooltipContent
322-
formatter={(value, name) => (
322+
formatter={(value: number | string, name: string) => (
323323
<div className="flex w-full items-center justify-between gap-2">
324324
<span className="text-muted-foreground">{diskChartConfig[name as keyof typeof diskChartConfig]?.label ?? name}</span>
325325
<span className="font-mono font-medium text-foreground">{formatBytesRate(Number(value) ?? 0)}</span>

0 commit comments

Comments
 (0)