@@ -5,16 +5,32 @@ COCALC_SERVICE
5
5
*/
6
6
7
7
import { delay } from "awaiting" ;
8
- import type { ConatServer } from "@cocalc/conat/core/server" ;
9
8
import { lookup } from "dns/promises" ;
10
- import port from "@cocalc/backend/port" ;
11
9
import { hostname } from "node:os" ;
12
- import { getLogger } from "@cocalc/backend/logger" ;
10
+
13
11
import { executeCode } from "@cocalc/backend/execute-code" ;
14
- import { split } from "@cocalc/util/misc" ;
12
+ import { getLogger } from "@cocalc/backend/logger" ;
13
+ import port from "@cocalc/backend/port" ;
14
+ import type { ConatServer } from "@cocalc/conat/core/server" ;
15
+ import { split , unreachable } from "@cocalc/util/misc" ;
16
+ import { getAddressesFromK8sApi } from "./dns-scan-k8s-api" ;
15
17
16
18
export const SCAN_INTERVAL = 15_000 ;
17
19
20
+ type PeerDiscovery = "KUBECTL" | "API" ;
21
+
22
+ function isPeerDiscovery ( x : string ) : x is PeerDiscovery {
23
+ return x === "KUBECTL" || x === "API" ;
24
+ }
25
+
26
+ const PEER_DISCOVERY : PeerDiscovery = ( function ( ) {
27
+ const val = process . env . COCALC_CONAT_PEER_DISCOVERY ?? "KUBECTL" ;
28
+ if ( ! isPeerDiscovery ( val ) ) {
29
+ throw Error ( `Invalid COCALC_CONAT_PEER_DISCOVERY: ${ val } ` ) ;
30
+ }
31
+ return val ;
32
+ } ) ( ) ;
33
+
18
34
const logger = getLogger ( "conat:socketio:dns-scan" ) ;
19
35
20
36
export async function dnsScan ( server : ConatServer ) {
@@ -83,6 +99,32 @@ export async function getAddresses(): Promise<string[]> {
83
99
const h = hostname ( ) ;
84
100
const i = h . lastIndexOf ( "-" ) ;
85
101
const prefix = h . slice ( 0 , i ) ;
102
+
103
+ const podInfos = await getPodInfos ( ) ;
104
+ for ( const { name, podIP } of podInfos ) {
105
+ if ( name != h && name . startsWith ( prefix ) ) {
106
+ v . push ( `http://${ podIP } :${ port } ` ) ;
107
+ }
108
+ }
109
+ return v ;
110
+ }
111
+
112
+ async function getPodInfos ( ) : Promise < { name : string ; podIP : string } [ ] > {
113
+ switch ( PEER_DISCOVERY ) {
114
+ case "KUBECTL" :
115
+ return await getAddressesFromKubectl ( ) ;
116
+ case "API" :
117
+ return await getAddressesFromK8sApi ( ) ;
118
+ default :
119
+ unreachable ( PEER_DISCOVERY ) ;
120
+ throw Error ( `Unknown PEER_DISCOVERY: ${ PEER_DISCOVERY } ` ) ;
121
+ }
122
+ }
123
+
124
+ async function getAddressesFromKubectl ( ) : Promise <
125
+ { name : string ; podIP : string } [ ]
126
+ > {
127
+ const ret : { name : string ; podIP : string } [ ] = [ ] ;
86
128
const { stdout } = await executeCode ( {
87
129
command : "kubectl" ,
88
130
args : [
@@ -97,10 +139,10 @@ export async function getAddresses(): Promise<string[]> {
97
139
for ( const x of stdout . split ( "\n" ) ) {
98
140
const row = split ( x ) ;
99
141
if ( row . length == 2 ) {
100
- if ( row [ 0 ] != h && row [ 0 ] . startsWith ( prefix ) ) {
101
- v . push ( `http:// ${ row [ 1 ] } : ${ port } ` ) ;
102
- }
142
+ ret . push ( { name : row [ 0 ] , podIP : row [ 1 ] } ) ;
143
+ } else {
144
+ logger . warn ( `Unexpected row from kubectl: ${ x } ` ) ;
103
145
}
104
146
}
105
- return v ;
147
+ return ret ;
106
148
}
0 commit comments