1
- import { field , logger } from "@coder/logger"
2
- import * as cp from "child_process"
3
- import http from "http"
4
- import * as path from "path"
5
- import { CliMessage , OpenCommandPipeArgs } from "../../typings/ipc"
6
- import { plural } from "../common/util"
7
- import { createApp , ensureAddress } from "./app"
1
+ import { logger } from "@coder/logger"
8
2
import {
9
- AuthType ,
10
- DefaultedArgs ,
11
3
optionDescriptions ,
12
4
parse ,
13
5
readConfigFile ,
14
6
setDefaults ,
15
7
shouldOpenInExistingInstance ,
16
8
shouldRunVsCodeCli ,
17
9
} from "./cli"
18
- import { coderCloudBind } from "./coder_cloud"
19
10
import { commit , version } from "./constants"
11
+ import { openInExistingInstance , runCodeServer , runVsCodeCli } from "./main"
20
12
import * as proxyAgent from "./proxy_agent"
21
- import { register } from "./routes"
22
- import { humanPath , isFile , open } from "./util"
23
13
import { isChild , wrapper } from "./wrapper"
24
14
25
- export const runVsCodeCli = ( args : DefaultedArgs ) : void => {
26
- logger . debug ( "forking vs code cli..." )
27
- const vscode = cp . fork ( path . resolve ( __dirname , "../../lib/vscode/out/vs/server/fork" ) , [ ] , {
28
- env : {
29
- ...process . env ,
30
- CODE_SERVER_PARENT_PID : process . pid . toString ( ) ,
31
- } ,
32
- } )
33
- vscode . once ( "message" , ( message : any ) => {
34
- logger . debug ( "got message from VS Code" , field ( "message" , message ) )
35
- if ( message . type !== "ready" ) {
36
- logger . error ( "Unexpected response waiting for ready response" , field ( "type" , message . type ) )
37
- process . exit ( 1 )
38
- }
39
- const send : CliMessage = { type : "cli" , args }
40
- vscode . send ( send )
41
- } )
42
- vscode . once ( "error" , ( error ) => {
43
- logger . error ( "Got error from VS Code" , field ( "error" , error ) )
44
- process . exit ( 1 )
45
- } )
46
- vscode . on ( "exit" , ( code ) => process . exit ( code || 0 ) )
47
- }
48
-
49
- export const openInExistingInstance = async ( args : DefaultedArgs , socketPath : string ) : Promise < void > => {
50
- const pipeArgs : OpenCommandPipeArgs & { fileURIs : string [ ] } = {
51
- type : "open" ,
52
- folderURIs : [ ] ,
53
- fileURIs : [ ] ,
54
- forceReuseWindow : args [ "reuse-window" ] ,
55
- forceNewWindow : args [ "new-window" ] ,
56
- }
57
-
58
- for ( let i = 0 ; i < args . _ . length ; i ++ ) {
59
- const fp = path . resolve ( args . _ [ i ] )
60
- if ( await isFile ( fp ) ) {
61
- pipeArgs . fileURIs . push ( fp )
62
- } else {
63
- pipeArgs . folderURIs . push ( fp )
64
- }
65
- }
66
-
67
- if ( pipeArgs . forceNewWindow && pipeArgs . fileURIs . length > 0 ) {
68
- logger . error ( "--new-window can only be used with folder paths" )
69
- process . exit ( 1 )
70
- }
71
-
72
- if ( pipeArgs . folderURIs . length === 0 && pipeArgs . fileURIs . length === 0 ) {
73
- logger . error ( "Please specify at least one file or folder" )
74
- process . exit ( 1 )
75
- }
76
-
77
- const vscode = http . request (
78
- {
79
- path : "/" ,
80
- method : "POST" ,
81
- socketPath,
82
- } ,
83
- ( response ) => {
84
- response . on ( "data" , ( message ) => {
85
- logger . debug ( "got message from VS Code" , field ( "message" , message . toString ( ) ) )
86
- } )
87
- } ,
88
- )
89
- vscode . on ( "error" , ( error : unknown ) => {
90
- logger . error ( "got error from VS Code" , field ( "error" , error ) )
91
- } )
92
- vscode . write ( JSON . stringify ( pipeArgs ) )
93
- vscode . end ( )
94
- }
95
-
96
- const main = async ( args : DefaultedArgs ) : Promise < void > => {
97
- logger . info ( `code-server ${ version } ${ commit } ` )
98
-
99
- logger . info ( `Using user-data-dir ${ humanPath ( args [ "user-data-dir" ] ) } ` )
100
- logger . trace ( `Using extensions-dir ${ humanPath ( args [ "extensions-dir" ] ) } ` )
101
-
102
- if ( args . auth === AuthType . Password && ! args . password && ! args [ "hashed-password" ] ) {
103
- throw new Error (
104
- "Please pass in a password via the config file or environment variable ($PASSWORD or $HASHED_PASSWORD)" ,
105
- )
106
- }
107
-
108
- const [ app , wsApp , server ] = await createApp ( args )
109
- const serverAddress = ensureAddress ( server )
110
- await register ( app , wsApp , server , args )
111
-
112
- logger . info ( `Using config file ${ humanPath ( args . config ) } ` )
113
- logger . info ( `HTTP server listening on ${ serverAddress } ${ args . link ? "(randomized by --link)" : "" } ` )
114
-
115
- if ( args . auth === AuthType . Password ) {
116
- logger . info ( " - Authentication is enabled" )
117
- if ( args . usingEnvPassword ) {
118
- logger . info ( " - Using password from $PASSWORD" )
119
- } else if ( args . usingEnvHashedPassword ) {
120
- logger . info ( " - Using password from $HASHED_PASSWORD" )
121
- } else {
122
- logger . info ( ` - Using password from ${ humanPath ( args . config ) } ` )
123
- }
124
- } else {
125
- logger . info ( ` - Authentication is disabled ${ args . link ? "(disabled by --link)" : "" } ` )
126
- }
127
-
128
- if ( args . cert ) {
129
- logger . info ( ` - Using certificate for HTTPS: ${ humanPath ( args . cert . value ) } ` )
130
- } else {
131
- logger . info ( ` - Not serving HTTPS ${ args . link ? "(disabled by --link)" : "" } ` )
132
- }
133
-
134
- if ( args [ "proxy-domain" ] . length > 0 ) {
135
- logger . info ( ` - ${ plural ( args [ "proxy-domain" ] . length , "Proxying the following domain" ) } :` )
136
- args [ "proxy-domain" ] . forEach ( ( domain ) => logger . info ( ` - *.${ domain } ` ) )
137
- }
138
-
139
- if ( args . link ) {
140
- try {
141
- await coderCloudBind ( serverAddress . replace ( / ^ h t t p s ? : \/ \/ / , "" ) , args . link . value )
142
- logger . info ( " - Connected to cloud agent" )
143
- } catch ( err ) {
144
- logger . error ( err . message )
145
- wrapper . exit ( 1 )
146
- }
147
- }
148
-
149
- if ( ! args . socket && args . open ) {
150
- // The web socket doesn't seem to work if browsing with 0.0.0.0.
151
- const openAddress = serverAddress . replace ( "://0.0.0.0" , "://localhost" )
152
- try {
153
- await open ( openAddress )
154
- logger . info ( `Opened ${ openAddress } ` )
155
- } catch ( error ) {
156
- logger . error ( "Failed to open" , field ( "address" , openAddress ) , field ( "error" , error ) )
157
- }
158
- }
159
- }
160
-
161
15
async function entry ( ) : Promise < void > {
162
16
proxyAgent . monkeyPatch ( false )
163
17
@@ -170,7 +24,8 @@ async function entry(): Promise<void> {
170
24
if ( isChild ( wrapper ) ) {
171
25
const args = await wrapper . handshake ( )
172
26
wrapper . preventExit ( )
173
- return main ( args )
27
+ await runCodeServer ( args )
28
+ return
174
29
}
175
30
176
31
const cliArgs = parse ( process . argv . slice ( 2 ) )
0 commit comments