1
1
import { getInstance } from "../base" ;
2
2
3
- import { Config } from "../config" ;
4
3
import path from "path" ;
5
4
import { OutputChannel , extensions , window } from "vscode" ;
5
+ import { Config } from "../config" ;
6
6
7
7
import { stat } from "fs/promises" ;
8
8
import { SERVER_VERSION_FILE } from "./SCVersion" ;
9
9
10
+ import IBMi from "@halcyontech/vscode-ibmi-types/api/IBMi" ;
11
+ import Crypto from 'crypto' ;
12
+ import { readFileSync } from "fs" ;
13
+
10
14
const ExecutablePathDir = `$HOME/.vscode/` ;
11
15
12
16
export enum UpdateStatus {
@@ -33,7 +37,7 @@ export class ServerComponent {
33
37
if ( show ) {
34
38
this . outputChannel . show ( ) ;
35
39
}
36
-
40
+
37
41
if ( this . outputChannel ) {
38
42
this . outputChannel . appendLine ( jsonString ) ;
39
43
}
@@ -43,15 +47,15 @@ export class ServerComponent {
43
47
return this . installed ;
44
48
}
45
49
46
- static getInitCommand ( ) : string | undefined {
50
+ static getInitCommand ( ) : string | undefined {
47
51
const path = this . getComponentPath ( ) ;
48
52
49
53
if ( path ) {
50
54
return `/QOpenSys/QIBM/ProdData/JavaVM/jdk80/64bit/bin/java -Dos400.stdio.convert=N -jar ${ path } --single`
51
55
}
52
56
}
53
57
54
- static getComponentPath ( ) : string | undefined {
58
+ static getComponentPath ( ) : string | undefined {
55
59
if ( Config . ready ) {
56
60
const installedVersion = Config . getServerComponentName ( ) ;
57
61
@@ -82,6 +86,10 @@ export class ServerComponent {
82
86
return this . installed ;
83
87
}
84
88
89
+ static reset ( ) {
90
+ this . installed = false ;
91
+ }
92
+
85
93
static async isAlreadyInstalled ( ) {
86
94
const instance = getInstance ( ) ;
87
95
const connection = instance . getConnection ( ) ;
@@ -107,13 +115,13 @@ export class ServerComponent {
107
115
const assetPath = path . join ( extensionPath , `dist` , SERVER_VERSION_FILE ) ;
108
116
const assetExistsLocally = await exists ( assetPath ) ;
109
117
110
- ServerComponent . writeOutput ( JSON . stringify ( { assetPath, assetExists : assetExistsLocally } ) ) ;
118
+ ServerComponent . writeOutput ( JSON . stringify ( { assetPath, assetExists : assetExistsLocally } ) ) ;
111
119
112
120
if ( assetExistsLocally ) {
113
121
const basename = SERVER_VERSION_FILE ;
114
122
const lastInstalledName = Config . getServerComponentName ( ) ;
115
123
116
- ServerComponent . writeOutput ( JSON . stringify ( { basename, lastInstalledName} ) ) ;
124
+ ServerComponent . writeOutput ( JSON . stringify ( { basename, lastInstalledName } ) ) ;
117
125
118
126
await this . initialise ( ) ;
119
127
@@ -132,26 +140,49 @@ export class ServerComponent {
132
140
const stuffInStderr = commandResult . stderr . length > 0 ;
133
141
const remotePath = path . posix . join ( commandResult . stdout , basename ) ;
134
142
135
- ServerComponent . writeOutput ( JSON . stringify ( { remotePath, ExecutablePathDir} ) ) ;
143
+ ServerComponent . writeOutput ( JSON . stringify ( { remotePath, ExecutablePathDir } ) ) ;
144
+
145
+ const remoteExists = await connection . content . testStreamFile ( remotePath , "f" ) ;
146
+ const md5IsEqual = remoteExists && await compareMD5Hash ( connection , assetPath , remotePath ) ;
147
+ if ( ! remoteExists || ! md5IsEqual ) {
148
+ if ( remoteExists ) {
149
+ const allowWrite = await connection . sendCommand ( {
150
+ command : `chmod 600 ${ remotePath } `
151
+ } ) ;
152
+ if ( allowWrite . code !== 0 ) {
153
+ this . writeOutput ( JSON . stringify ( allowWrite ) ) ;
154
+ window . showErrorMessage ( `Remote file ${ remotePath } cannot be written; try to delete it and reconnect.` , 'Show' )
155
+ . then ( show => {
156
+ if ( show ) {
157
+ this . outputChannel . show ( ) ;
158
+ }
159
+ } ) ;
160
+ return UpdateStatus . FAILED ;
161
+ }
162
+ }
163
+ await connection . uploadFiles ( [ { local : assetPath , remote : remotePath } ] ) ;
136
164
137
- await connection . uploadFiles ( [ { local : assetPath , remote : remotePath } ] ) ;
165
+ const scAuth = await connection . sendCommand ( {
166
+ command : `chmod 400 ${ remotePath } `
167
+ } ) ;
138
168
139
- const scAuth = await connection . sendCommand ( {
140
- command : `chmod 400 ${ remotePath } `
141
- } ) ;
169
+ this . writeOutput ( JSON . stringify ( scAuth ) ) ;
142
170
143
- this . writeOutput ( JSON . stringify ( scAuth ) ) ;
171
+ await Config . setServerComponentName ( basename ) ;
144
172
145
- await Config . setServerComponentName ( basename ) ;
173
+ if ( stuffInStderr ) {
174
+ ServerComponent . writeOutput ( `Server component was uploaded to ${ remotePath } but there was something in stderr, which is not right. It might be worth seeing your user profile startup scripts.` ) ;
175
+ }
146
176
147
- if ( stuffInStderr ) {
148
- ServerComponent . writeOutput ( `Server component was uploaded to ${ remotePath } but there was something in stderr, which is not right. It might be worth seeing your user profile startup scripts.` ) ;
177
+ window . showInformationMessage ( `Db2 for IBM i extension server component has been updated!` ) ;
178
+ this . installed = true ;
179
+ updateResult = UpdateStatus . JUST_UPDATED ;
180
+ }
181
+ else {
182
+ await Config . setServerComponentName ( basename ) ;
183
+ this . installed = true ;
184
+ updateResult = UpdateStatus . UP_TO_DATE ;
149
185
}
150
-
151
- window . showInformationMessage ( `Db2 for IBM i extension server component has been updated!` ) ;
152
- this . installed = true ;
153
- updateResult = UpdateStatus . JUST_UPDATED ;
154
-
155
186
} else {
156
187
updateResult = UpdateStatus . FAILED ;
157
188
@@ -196,4 +227,20 @@ async function exists(path: string) {
196
227
} catch ( e ) {
197
228
return false ;
198
229
}
230
+ }
231
+
232
+ async function compareMD5Hash ( connection : IBMi , local : string , remote : string ) {
233
+ const localMD5 = Crypto . createHash ( "md5" )
234
+ . update ( readFileSync ( local ) )
235
+ . digest ( "hex" )
236
+ . toLowerCase ( ) ;
237
+
238
+ const remoteMD5Result = ( await connection . sendCommand ( { command : `${ connection . remoteFeatures . md5sum } ${ remote } ` } ) ) ;
239
+ if ( remoteMD5Result . code === 0 ) {
240
+ return localMD5 === remoteMD5Result . stdout . split ( / \s + / ) [ 0 ] ;
241
+ }
242
+ else {
243
+ ServerComponent . writeOutput ( JSON . stringify ( remoteMD5Result ) ) ;
244
+ return false ;
245
+ }
199
246
}
0 commit comments