parent
a828a1233d
commit
9453db0e99
@ -0,0 +1,110 @@ |
||||
#!/usr/bin/node |
||||
// Simple systemd unit generator for etcd |
||||
// Copyright (c) Vitaliy Filippov, 2019+ |
||||
// License: MIT |
||||
|
||||
// USAGE: |
||||
// 1) Put the same etcd_address into /etc/vitastor/vitastor.conf on all monitor nodes |
||||
// 2) Run ./make-etcd.js. It will create the etcd service on one of specified IPs |
||||
|
||||
const child_process = require('child_process'); |
||||
const fs = require('fs'); |
||||
const os = require('os'); |
||||
|
||||
run().catch(e => { console.error(e); process.exit(1); }); |
||||
|
||||
async function run() |
||||
{ |
||||
const config_path = process.argv[2] || '/etc/vitastor/vitastor.conf'; |
||||
if (config_path == '-h' || config_path == '--help') |
||||
{ |
||||
console.log( |
||||
'Initialize systemd etcd service for Vitastor\n'+ |
||||
'(c) Vitaliy Filippov, 2019+ (MIT)\n'+ |
||||
'\n'+ |
||||
'USAGE:\n'+ |
||||
'1) Put the same etcd_address into /etc/vitastor/vitastor.conf on all monitor nodes\n'+ |
||||
'2) Run '+process.argv[1]+' [config_path]\n' |
||||
); |
||||
process.exit(0); |
||||
} |
||||
if (!fs.existsSync(config_path)) |
||||
{ |
||||
console.log(config_path+' is missing'); |
||||
process.exit(1); |
||||
} |
||||
if (fs.existsSync("/etc/systemd/system/etcd.service")) |
||||
{ |
||||
console.log("/etc/systemd/system/etcd.service already exists"); |
||||
process.exit(1); |
||||
} |
||||
const config = JSON.parse(fs.readFileSync(config_path, { encoding: 'utf-8' })); |
||||
if (!config.etcd_address) |
||||
{ |
||||
console.log("etcd_address is missing in "+config_path); |
||||
process.exit(1); |
||||
} |
||||
const etcds = (config.etcd_address instanceof Array ? config.etcd_address : (''+config.etcd_address).split(/,/)) |
||||
.map(s => (''+s).replace(/^https?:\/\/\[?|\]?(:\d+)?\/.*$/g, '').toLowerCase()); |
||||
const num = select_local_etcd(etcds); |
||||
if (num < 0) |
||||
{ |
||||
console.log('No matching IPs in etcd_address from '+config_path); |
||||
process.exit(0); |
||||
} |
||||
const etcd_cluster = etcds.map((e, i) => `etcd${i}=http://${e}:2380`).join(','); |
||||
await system(`mkdir -p /var/lib/etcd${num}.etcd`); |
||||
fs.writeFileSync( |
||||
"/etc/systemd/system/etcd.service", |
||||
`[Unit] |
||||
Description=etcd for vitastor |
||||
After=network-online.target local-fs.target time-sync.target |
||||
Wants=network-online.target local-fs.target time-sync.target |
||||
|
||||
[Service] |
||||
Restart=always |
||||
ExecStart=/usr/local/bin/etcd -name etcd${num} --data-dir /var/lib/etcd${num}.etcd \\ |
||||
--advertise-client-urls http://${etcds[num]}:2379 --listen-client-urls http://${etcds[num]}:2379 \\ |
||||
--initial-advertise-peer-urls http://${etcds[num]}:2380 --listen-peer-urls http://${etcds[num]}:2380 \\ |
||||
--initial-cluster-token vitastor-etcd-1 --initial-cluster ${etcd_cluster} \\ |
||||
--initial-cluster-state new --max-txn-ops=100000 --max-request-bytes=104857600 \\ |
||||
--auto-compaction-retention=10 --auto-compaction-mode=revision |
||||
WorkingDirectory=/var/lib/etcd${num}.etcd |
||||
ExecStartPre=+chown -R etcd /var/lib/etcd${num}.etcd |
||||
User=etcd |
||||
PrivateTmp=false |
||||
TasksMax=infinity |
||||
Restart=always |
||||
StartLimitInterval=0 |
||||
RestartSec=10 |
||||
|
||||
[Install] |
||||
WantedBy=local.target |
||||
`); |
||||
await system(`useradd etcd`); |
||||
await system(`systemctl daemon-reload`); |
||||
await system(`systemctl enable etcd`); |
||||
await system(`systemctl start etcd`); |
||||
process.exit(0); |
||||
} |
||||
|
||||
function select_local_etcd(etcds) |
||||
{ |
||||
const ifaces = os.networkInterfaces(); |
||||
for (const ifname in ifaces) |
||||
for (const iface of ifaces[ifname]) |
||||
for (let i = 0; i < etcds.length; i++) |
||||
if (etcds[i] == iface.address.toLowerCase()) |
||||
return i; |
||||
return -1; |
||||
} |
||||
|
||||
async function system(cmd) |
||||
{ |
||||
const cp = child_process.spawn(cmd, { shell: true, stdio: [ 0, 1, 2 ] }); |
||||
let finish_cb; |
||||
cp.on('exit', () => finish_cb && finish_cb()); |
||||
if (cp.exitCode == null) |
||||
await new Promise(ok => finish_cb = ok); |
||||
return cp.exitCode; |
||||
} |
@ -1,50 +0,0 @@ |
||||
#!/bin/bash |
||||
# Simple systemd unit generator for etcd |
||||
# Copyright (c) Vitaliy Filippov, 2019+ |
||||
# License: MIT |
||||
|
||||
# USAGE: [IP_SUBSTR=10.200.1.] [ETCD_HOSTS=etcd0=http://10.200.1.10:2380,...] ./make-etcd.sh |
||||
|
||||
IP_SUBSTR=${IP_SUBSTR:-10.200.1.} |
||||
ETCD_HOSTS=${ETCD_HOSTS:-etcd0=http://10.200.1.10:2380,etcd1=http://10.200.1.11:2380,etcd2=http://10.200.1.12:2380} |
||||
|
||||
# determine IP |
||||
IP=`ip -json a s | jq -r '.[].addr_info[] | select(.local | startswith("'$IP_SUBSTR'")) | .local'` |
||||
[ "$IP" != "" ] || exit 1 |
||||
ETCD_NUM=${ETCD_HOSTS/$IP*/} |
||||
[ "$ETCD_NUM" != "$ETCD_HOSTS" ] || exit 1 |
||||
ETCD_NUM=$(echo $ETCD_NUM | tr -d -c , | wc -c) |
||||
|
||||
useradd etcd |
||||
|
||||
mkdir -p /var/lib/etcd$ETCD_NUM.etcd |
||||
cat >/etc/systemd/system/etcd.service <<EOF |
||||
[Unit] |
||||
Description=etcd for vitastor |
||||
After=network-online.target local-fs.target time-sync.target |
||||
Wants=network-online.target local-fs.target time-sync.target |
||||
|
||||
[Service] |
||||
Restart=always |
||||
ExecStart=/usr/local/bin/etcd -name etcd$ETCD_NUM --data-dir /var/lib/etcd$ETCD_NUM.etcd \\ |
||||
--advertise-client-urls http://$IP:2379 --listen-client-urls http://$IP:2379 \\ |
||||
--initial-advertise-peer-urls http://$IP:2380 --listen-peer-urls http://$IP:2380 \\ |
||||
--initial-cluster-token vitastor-etcd-1 --initial-cluster $ETCD_HOSTS \\ |
||||
--initial-cluster-state new --max-txn-ops=100000 --max-request-bytes=104857600 \\ |
||||
--auto-compaction-retention=10 --auto-compaction-mode=revision |
||||
WorkingDirectory=/var/lib/etcd$ETCD_NUM.etcd |
||||
ExecStartPre=+chown -R etcd /var/lib/etcd$ETCD_NUM.etcd |
||||
User=etcd |
||||
PrivateTmp=false |
||||
TasksMax=infinity |
||||
Restart=always |
||||
StartLimitInterval=0 |
||||
RestartSec=10 |
||||
|
||||
[Install] |
||||
WantedBy=local.target |
||||
EOF |
||||
|
||||
systemctl daemon-reload |
||||
systemctl enable etcd |
||||
systemctl start etcd |
Loading…
Reference in new issue