Skip to content

Commit 163d01c

Browse files
committed
Let hub remember its own ID and other peer hubs so that it can restart in the same state
1 parent 9d6298f commit 163d01c

File tree

3 files changed

+123
-6
lines changed

3 files changed

+123
-6
lines changed

agent/db.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,7 @@ function getHub(id) {
127127
} catch {
128128
var hub = {}
129129
}
130-
hub.zone = r.zone
131-
return hub
130+
return { zone: r.zone, ...hub }
132131
})[0]
133132
)
134133
}

hub/db.js

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ var db = null
33
function open(pathname) {
44
db = sqlite(pathname)
55

6+
db.exec(`
7+
CREATE TABLE IF NOT EXISTS hubs (
8+
id TEXT PRIMARY KEY,
9+
zone TEXT NOT NULL,
10+
info TEXT NOT NULL
11+
)
12+
`)
13+
614
db.exec(`
715
CREATE TABLE IF NOT EXISTS certificates (
816
name TEXT PRIMARY KEY,
@@ -44,6 +52,98 @@ function open(pathname) {
4452
`)
4553
}
4654

55+
function allHubs() {
56+
var all = {}
57+
db.sql('SELECT id, info FROM hubs')
58+
.exec()
59+
.forEach(r => {
60+
try {
61+
all[r.id] = {
62+
zone: r.zone,
63+
...JSON.parse(r.info),
64+
}
65+
} catch {}
66+
})
67+
return all
68+
}
69+
70+
function setHubs(hubs) {
71+
var old = {}
72+
db.sql('SELECT id FROM hubs')
73+
.exec()
74+
.forEach(r => old[r.id] = true)
75+
Object.entries(hubs).forEach(
76+
([id, hub]) => {
77+
var info = JSON.stringify({ ports: hub.ports, version: hub.version })
78+
if (id in old) {
79+
db.sql('UPDATE hubs SET zone = ?, info = ? WHERE id = ?')
80+
.bind(1, hub.zone)
81+
.bind(2, info)
82+
.bind(3, id)
83+
.exec()
84+
} else {
85+
db.sql('INSERT INTO hubs(id, zone, info) VALUES(?, ?, ?)')
86+
.bind(1, id)
87+
.bind(2, hub.zone)
88+
.bind(3, info)
89+
.exec()
90+
}
91+
}
92+
)
93+
Object.keys(old).forEach(
94+
id => {
95+
if (!(id in hubs)) {
96+
db.sql('DELETE FROM hubs WHERE id = ?')
97+
.bind(1, id)
98+
.exec()
99+
}
100+
}
101+
)
102+
}
103+
104+
function getHub(id) {
105+
return (
106+
db.sql('SELECT zone, info FROM hubs WHERE id = ?')
107+
.bind(1, id)
108+
.exec()
109+
.map(r => {
110+
try {
111+
var hub = JSON.parse(r.info)
112+
} catch {
113+
var hub = {}
114+
}
115+
return { zone: r.zone, ...hub }
116+
})[0]
117+
)
118+
}
119+
120+
function setHub(id, hub) {
121+
var old = getHub(id)
122+
if (old) {
123+
var zone = hub.zone || old.zone
124+
var info = {
125+
ports: hub.ports || old.ports,
126+
version: hub.version || old.version,
127+
}
128+
db.sql('UPDATE hubs SET zone = ?, info = ? WHERE id = ?')
129+
.bind(1, zone)
130+
.bind(2, JSON.stringify(info))
131+
.bind(3, id)
132+
.exec()
133+
} else {
134+
var zone = hub.zone
135+
var info = {
136+
ports: hub.ports,
137+
version: hub.version,
138+
}
139+
db.sql('INSERT INTO hubs(id, zone, info) VALUES(?, ?, ?)')
140+
.bind(1, id)
141+
.bind(2, zone)
142+
.bind(3, JSON.stringify(info))
143+
.exec()
144+
}
145+
}
146+
47147
function getCert(name) {
48148
return db.sql(`SELECT data FROM certificates WHERE name = ?`)
49149
.bind(1, name)
@@ -70,6 +170,10 @@ function delCert(name) {
70170
.exec()
71171
}
72172

173+
function allKeys() {
174+
return db.sql(`SELECT name, data FROM keys`).exec()
175+
}
176+
73177
function getKey(name) {
74178
return db.sql(`SELECT data FROM keys WHERE name = ?`)
75179
.bind(1, name)
@@ -242,9 +346,14 @@ function delEviction(username) {
242346

243347
export default {
244348
open,
349+
allHubs,
350+
setHubs,
351+
getHub,
352+
setHub,
245353
getCert,
246354
setCert,
247355
delCert,
356+
allKeys,
248357
getKey,
249358
setKey,
250359
delKey,

hub/main.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ var evictions = {}
207207
var caCert = null
208208
var myCert = null
209209
var myKey = null
210-
var myID = algo.uuid()
210+
var myID = ''
211211
var myNames = []
212212
var myZone = ''
213213
var startTime = Date.now()
@@ -277,14 +277,23 @@ function main() {
277277
return Promise.reject()
278278
}
279279

280+
var key = db.allKeys().find(k => k.name.startsWith('hub/'))
281+
if (key) {
282+
myID = key.name.substring(4)
283+
} else {
284+
myID = algo.uuid()
285+
}
286+
280287
myNames = args['--names'] || []
281288

282289
return ca.init(args['--ca']).then(() => {
283290
myKey = new crypto.PrivateKey({ type: 'rsa', bits: 2048 })
284291
var pkey = new crypto.PublicKey(myKey)
292+
var name = 'hub/' + myID
293+
db.setKey(name, pkey.toPEM().toString())
285294
return Promise.all([
286295
ca.getCertificate('ca').then(crt => caCert = crt),
287-
ca.signCertificate('hub/' + myID, pkey).then(crt => myCert = crt),
296+
ca.signCertificate(name, pkey).then(crt => myCert = crt),
288297
])
289298
}).then(() => {
290299
start(args['--listen'] || '0.0.0.0:8888', args['--bootstrap'])
@@ -478,13 +487,13 @@ function start(listen, bootstrap) {
478487

479488
if (cluster) {
480489
cluster.bootstrap(bootstrap).then(() => {
481-
logInfo(`Hub instance started in zone '${myZone}' listening at ${listen}`)
490+
logInfo(`Hub ${myID} started in zone '${myZone}' listening at ${listen}`)
482491
}).catch(() => {
483492
logError(`Unable to bootstrap hub instance in zone '${myZone}'`)
484493
pipy.exit(-1)
485494
})
486495
} else {
487-
logInfo(`Hub started at ${listen}`)
496+
logInfo(`Hub ${myID} started at ${listen}`)
488497
}
489498

490499
startPing()

0 commit comments

Comments
 (0)