@@ -14,6 +14,7 @@ const crypto = require('crypto')
1414const sudo = require ( 'sudo-prompt' )
1515const { EventEmitter } = require ( 'events' )
1616const os = require ( 'os' )
17+ const winston = require ( 'winston' )
1718
1819let VBoxManage
1920
@@ -24,22 +25,37 @@ if (os.platform() === 'darwin') {
2425}
2526
2627class VRouter {
27- constructor ( ) {
28+ constructor ( cfgObj ) {
2829 let config
2930 let cfg = path . join ( getAppDir ( ) , packageJson . name , 'config.json' )
30- try {
31- config = fs . readJsonSync ( cfg )
32- } catch ( err ) {
33- const template = path . join ( __dirname , '..' , 'config' , 'config.json' )
34- config = fs . readJsonSync ( template )
35- fs . copySync ( template , cfg )
36- }
37- if ( ! config . host . configDir ) {
38- config . host . configDir = path . join ( getAppDir ( ) , packageJson . name )
31+ if ( ! cfgObj ) {
32+ try {
33+ config = fs . readJsonSync ( cfg )
34+ } catch ( err ) {
35+ const template = path . join ( __dirname , '..' , 'config' , 'config.json' )
36+ config = fs . readJsonSync ( template )
37+ fs . copySync ( template , cfg )
38+ }
39+ if ( ! config . host . configDir ) {
40+ config . host . configDir = path . join ( getAppDir ( ) , packageJson . name )
41+ }
42+ } else {
43+ config = cfgObj
3944 }
4045 this . config = config
4146 this . process = new EventEmitter ( )
4247 this . remote = null
48+ winston . configure ( {
49+ transports : [
50+ new ( winston . transports . File ) ( {
51+ filename : path . join ( this . config . host . configDir , 'vrouter.log' ) ,
52+ level : 'info'
53+ } ) ,
54+ new ( winston . transports . Console ) ( {
55+ level : 'debug'
56+ } )
57+ ]
58+ } )
4359 }
4460
4561 // os
@@ -111,7 +127,7 @@ class VRouter {
111127 return match [ 1 ]
112128 }
113129 }
114- return Error ( `can not find NetworkService match ${ inf } ` )
130+ throw Error ( `can not find NetworkService match ${ inf } ` )
115131 }
116132 async getCurrentGateway ( ) {
117133 let networkService
@@ -162,7 +178,7 @@ class VRouter {
162178 if ( match && match [ 1 ] ) {
163179 ip = match [ 1 ]
164180 } else {
165- return Error ( 'can not get Router IP' )
181+ throw Error ( 'can not get Router IP' )
166182 }
167183 }
168184 const cmd1 = `/sbin/route change default ${ ip } `
@@ -604,15 +620,15 @@ class VRouter {
604620 infos . set ( temp [ 0 ] . replace ( / " / g, '' ) , temp [ 1 ] . replace ( / " / g, '' ) )
605621 } )
606622 if ( infos . get ( 'nic1' ) !== 'hostonly' ) {
607- return Error ( "NIC1 isn't hostonly network" )
623+ throw Error ( "NIC1 isn't hostonly network" )
608624 }
609625 if ( ! / ^ v b o x n e t \d + $ / ig. test ( infos . get ( 'hostonlyadapter1' ) ) ) {
610- return Error ( "NIC1 doesn't specify host-only adapter" )
626+ throw Error ( "NIC1 doesn't specify host-only adapter" )
611627 }
612628 const inf = infos . get ( 'hostonlyadapter1' )
613629 const ip = await this . getInfIP ( inf )
614630 if ( ip !== this . config . host . ip ) {
615- return Error ( "host-only adapter doesn't config as hostIP" )
631+ throw Error ( "host-only adapter doesn't config as hostIP" )
616632 }
617633 return inf
618634 }
@@ -625,16 +641,16 @@ class VRouter {
625641 infos . set ( temp [ 0 ] . replace ( / " / g, '' ) , temp [ 1 ] . replace ( / " / g, '' ) )
626642 } )
627643 if ( infos . get ( 'nic2' ) !== 'bridged' ) {
628- return Error ( "NIC2 isn't bridged network" )
644+ throw Error ( "NIC2 isn't bridged network" )
629645 }
630646 const inf = infos . get ( 'bridgeadapter2' )
631647 if ( ! inf ) {
632- return Error ( "NIC2 doesn't specify bridged adapter" )
648+ throw Error ( "NIC2 doesn't specify bridged adapter" )
633649 }
634650 cmd = `/sbin/ifconfig ${ inf . trim ( ) . split ( ':' ) [ 0 ] } `
635651 const infConfig = await this . localExec ( cmd )
636652 const statusMatch = / s t a t u s : a c t i v e / ig. exec ( infConfig )
637- if ( ! statusMatch ) return Error ( "bridged adapter doesn't active" )
653+ if ( ! statusMatch ) throw Error ( "bridged adapter doesn't active" )
638654 return inf
639655 }
640656
@@ -653,10 +669,12 @@ class VRouter {
653669 }
654670 await this . isNIC1ConfigedAsHostonly ( this . config . vrouter . name , this . config . host . ip )
655671 . catch ( ( ) => {
672+ winston . debug ( `isNIC1ConfigedAsHostonly return false. vrouter: ${ this . config . vrouter . name } , hostip: ${ this . config . host . ip } ` )
656673 return this . specifyHostonlyAdapter ( )
657674 } )
658675 await this . isNIC2ConfigedAsBridged ( this . config . vrouter . name )
659676 . catch ( ( ) => {
677+ winston . debug ( `isNIC2ConfigedAsBridged return false. vrouter: ${ this . config . vrouter . name } , hostip: ${ this . config . host . ip } ` )
660678 return this . specifyBridgeAdapter ( )
661679 } )
662680 }
@@ -721,7 +739,7 @@ class VRouter {
721739 }
722740 async changevmTZ ( ) {
723741 const cc = String . raw `
724- uci set system.@system[0].hostname='VRouter '
742+ uci set system.@system[0].hostname='${ this . config . vrouter . name } '
725743 uci set system.@system[0].timezone='HKT-8'
726744 uci set system.@system[0].zonename='Asia/Hong Kong'
727745 uci commit system`
@@ -760,9 +778,11 @@ class VRouter {
760778 async getCfgContent ( fileName ) {
761779 const filePath = path . join ( this . config . host . configDir , fileName )
762780 try {
763- return fs . readFile ( filePath , 'utf8' )
781+ const content = await fs . readFile ( filePath , 'utf8' )
782+ return content
764783 } catch ( error ) {
765784 const template = path . join ( __dirname , '../config' , fileName )
785+ winston . debug ( `can not find ${ filePath } , copy template ${ template } to appdir` )
766786 await fs . copy ( template , filePath )
767787 return fs . readFile ( filePath , 'utf8' )
768788 }
@@ -772,7 +792,7 @@ class VRouter {
772792 const stats = await fs . stat ( cfgPath )
773793 . catch ( ( ) => null )
774794 if ( stats && stats . isFile ( ) && ! overwrite ) {
775- return Promise . resolve ( cfgPath )
795+ return cfgPath
776796 }
777797 const ws = fs . createWriteStream ( cfgPath )
778798 const promise = new Promise ( ( resolve , reject ) => {
@@ -792,6 +812,7 @@ class VRouter {
792812 // "selectedBL": {"gfwDomains":true, "extraBlackList":true},
793813 // "selectedWL": {"chinaIPs":true, "lanNetworks":true, "extraWhiteList":true},
794814 if ( this . config . firewall . selectedWL . lanNetworks ) {
815+ winston . debug ( `getCfgContent: ${ this . config . firewall . lanNetworks } ` )
795816 const lan = await this . getCfgContent ( this . config . firewall . lanNetworks )
796817 lan . split ( '\n' ) . forEach ( ( line ) => {
797818 const trimLine = line . trim ( )
@@ -1508,7 +1529,7 @@ class VRouter {
15081529 await fs . stat ( dest )
15091530 return dest
15101531 } catch ( error ) {
1511- console . log ( ` ${ dest } not exist, copy template to it. `)
1532+ winston . debug ( ` copy template: ${ fileName } `)
15121533 await fs . copy ( template , dest )
15131534 return dest
15141535 }
@@ -1533,6 +1554,7 @@ class VRouter {
15331554 break
15341555 case 'ktService' :
15351556 p = await this . generateService ( 'kcptun' )
1557+ winston . debug ( `generateService-kcptun for proxies: ${ this . config . firewall . currentProxies } ` )
15361558 await this . scp ( p , '/etc/init.d/' )
15371559 await this . serialExec ( `chmod +x /etc/init.d/${ this . config . kcptun . service } ` )
15381560 break
@@ -1551,6 +1573,7 @@ class VRouter {
15511573 break
15521574 case 'ipset' :
15531575 p = await this . generateIPsets ( overwrite )
1576+ winston . debug ( 'generated ipset' )
15541577 await this . scp ( p , this . config . vrouter . configDir )
15551578 break
15561579 case 'firewall' :
@@ -1599,7 +1622,7 @@ class VRouter {
15991622 async connect ( startFirst ) {
16001623 const state = await this . getvmState ( )
16011624 if ( state !== 'running' ) {
1602- return Error ( "vm doesn't running." )
1625+ throw Error ( "vm doesn't running." )
16031626 }
16041627 return new Promise ( ( resolve , reject ) => {
16051628 const conn = new Client ( )
0 commit comments