1
0

Salt-Minion-Setup.nsi 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392
  1. !define PRODUCT_NAME "Salt Minion"
  2. !define PRODUCT_NAME_OTHER "Salt"
  3. !define PRODUCT_PUBLISHER "SaltStack, Inc"
  4. !define PRODUCT_WEB_SITE "http://saltstack.org"
  5. !define PRODUCT_CALL_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\salt-call.exe"
  6. !define PRODUCT_CP_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\salt-cp.exe"
  7. !define PRODUCT_KEY_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\salt-key.exe"
  8. !define PRODUCT_MASTER_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\salt-master.exe"
  9. !define PRODUCT_MINION_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\salt-minion.exe"
  10. !define PRODUCT_RUN_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\salt-run.exe"
  11. !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
  12. !define PRODUCT_UNINST_KEY_OTHER "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME_OTHER}"
  13. !define PRODUCT_UNINST_ROOT_KEY "HKLM"
  14. !define OUTFILE "Salt-Minion-${PRODUCT_VERSION}-Py${PYTHON_VERSION}-${CPUARCH}-Setup.exe"
  15. # Import Libraries
  16. !include "MUI2.nsh"
  17. !include "nsDialogs.nsh"
  18. !include "LogicLib.nsh"
  19. !include "FileFunc.nsh"
  20. !include "StrFunc.nsh"
  21. !include "x64.nsh"
  22. !include "WinMessages.nsh"
  23. !include "WinVer.nsh"
  24. ${StrLoc}
  25. ${StrStrAdv}
  26. !ifdef SaltVersion
  27. !define PRODUCT_VERSION "${SaltVersion}"
  28. !else
  29. !define PRODUCT_VERSION "Undefined Version"
  30. !endif
  31. !ifdef PythonVersion
  32. !define PYTHON_VERSION "${PythonVersion}"
  33. !else
  34. !define PYTHON_VERSION "3"
  35. !endif
  36. !if "$%PROCESSOR_ARCHITECTURE%" == "AMD64"
  37. !define CPUARCH "AMD64"
  38. !else if "$%PROCESSOR_ARCHITEW6432%" == "AMD64"
  39. !define CPUARCH "AMD64"
  40. !else
  41. !define CPUARCH "x86"
  42. !endif
  43. # Part of the Trim function for Strings
  44. !define Trim "!insertmacro Trim"
  45. !macro Trim ResultVar String
  46. Push "${String}"
  47. Call Trim
  48. Pop "${ResultVar}"
  49. !macroend
  50. # Part of the Explode function for Strings
  51. !define Explode "!insertmacro Explode"
  52. !macro Explode Length Separator String
  53. Push `${Separator}`
  54. Push `${String}`
  55. Call Explode
  56. Pop `${Length}`
  57. !macroend
  58. ###############################################################################
  59. # Configure Pages, Ordering, and Configuration
  60. ###############################################################################
  61. !define MUI_ABORTWARNING
  62. !define MUI_ICON "salt.ico"
  63. !define MUI_UNICON "salt.ico"
  64. !define MUI_WELCOMEFINISHPAGE_BITMAP "panel.bmp"
  65. !define MUI_UNWELCOMEFINISHPAGE_BITMAP "panel.bmp"
  66. # Welcome page
  67. !insertmacro MUI_PAGE_WELCOME
  68. # License page
  69. !insertmacro MUI_PAGE_LICENSE "LICENSE.txt"
  70. # Configure Minion page
  71. Page custom pageMinionConfig pageMinionConfig_Leave
  72. # Instfiles page
  73. !insertmacro MUI_PAGE_INSTFILES
  74. # Finish page (Customized)
  75. !define MUI_PAGE_CUSTOMFUNCTION_SHOW pageFinish_Show
  76. !define MUI_PAGE_CUSTOMFUNCTION_LEAVE pageFinish_Leave
  77. !insertmacro MUI_PAGE_FINISH
  78. # Uninstaller pages
  79. !insertmacro MUI_UNPAGE_INSTFILES
  80. # Language files
  81. !insertmacro MUI_LANGUAGE "English"
  82. ###############################################################################
  83. # Custom Dialog Box Variables
  84. ###############################################################################
  85. Var Dialog
  86. Var Label
  87. Var CheckBox_Minion_Start
  88. Var CheckBox_Minion_Start_Delayed
  89. Var ConfigMasterHost
  90. Var MasterHost
  91. Var MasterHost_State
  92. Var ConfigMinionName
  93. Var MinionName
  94. Var MinionName_State
  95. Var ExistingConfigFound
  96. Var ConfigType
  97. Var ConfigType_State
  98. Var CustomConfig
  99. Var CustomConfig_btn
  100. Var CustomConfig_State
  101. Var WarningCustomConfig
  102. Var WarningExistingConfig
  103. Var WarningDefaultConfig
  104. Var StartMinion
  105. Var StartMinionDelayed
  106. Var DeleteInstallDir
  107. Var ConfigWriteMinion
  108. Var ConfigWriteMaster
  109. ###############################################################################
  110. # Minion Settings Dialog Box
  111. ###############################################################################
  112. Function pageMinionConfig
  113. # Set Page Title and Description
  114. !insertmacro MUI_HEADER_TEXT "Minion Settings" "Set the Minion Master and ID"
  115. nsDialogs::Create 1018
  116. Pop $Dialog
  117. ${If} $Dialog == error
  118. Abort
  119. ${EndIf}
  120. # Master IP or Hostname Dialog Control
  121. ${NSD_CreateLabel} 0 0 100% 12u "Master IP or Hostname:"
  122. Pop $Label
  123. ${NSD_CreateText} 0 13u 100% 12u $MasterHost_State
  124. Pop $MasterHost
  125. # Minion ID Dialog Control
  126. ${NSD_CreateLabel} 0 30u 100% 12u "Minion Name:"
  127. Pop $Label
  128. ${NSD_CreateText} 0 43u 100% 12u $MinionName_State
  129. Pop $MinionName
  130. # Config Drop List
  131. ${NSD_CreateDropList} 0 65u 25% 36u ""
  132. Pop $ConfigType
  133. ${NSD_CB_AddString} $ConfigType "Default Config"
  134. ${NSD_CB_AddString} $ConfigType "Custom Config"
  135. ${NSD_OnChange} $ConfigType pageMinionConfig_OnChange
  136. # Add Existing Config Warning Label
  137. ${NSD_CreateLabel} 0 80u 100% 60u "The values above are taken from an \
  138. existing configuration found in `c:\salt\conf\minion`. Configuration \
  139. settings defined in the `minion.d` directories, if they exist, are not \
  140. shown here.$\r$\n\
  141. $\r$\n\
  142. Clicking `Install` will leave the existing config unchanged."
  143. Pop $WarningExistingConfig
  144. CreateFont $0 "Arial" 10 500 /ITALIC
  145. SendMessage $WarningExistingConfig ${WM_SETFONT} $0 1
  146. SetCtlColors $WarningExistingConfig 0xBB0000 transparent
  147. # Add Default Config Warning Label
  148. ${NSD_CreateLabel} 0 80u 100% 60u "Clicking `Install` will backup the \
  149. the existing minion config file and minion.d directories. The values \
  150. above will be used in the new default config.$\r$\n\
  151. $\r$\n\
  152. NOTE: If Master IP is set to `salt` and Minion Name is set to \
  153. `hostname` no changes will be made."
  154. Pop $WarningDefaultConfig
  155. CreateFont $0 "Arial" 10 500 /ITALIC
  156. SendMessage $WarningDefaultConfig ${WM_SETFONT} $0 1
  157. SetCtlColors $WarningDefaultConfig 0xBB0000 transparent
  158. # Add Custom Config File Selector and Warning Label
  159. ${NSD_CreateText} 26% 65u 64% 12u $CustomConfig_State
  160. Pop $CustomConfig
  161. ${NSD_CreateButton} 91% 65u 9% 12u "..."
  162. Pop $CustomConfig_btn
  163. ${NSD_OnClick} $CustomConfig_btn pageCustomConfigBtn_OnClick
  164. ${If} $ExistingConfigFound == 0
  165. ${NSD_CreateLabel} 0 80u 100% 60u "Values entered above will be used \
  166. in the custom config.$\r$\n\
  167. $\r$\n\
  168. NOTE: If Master IP is set to `salt` and Minion Name is set to \
  169. `hostname` no changes will be made."
  170. ${Else}
  171. ${NSD_CreateLabel} 0 80u 100% 60u "Clicking `Install` will backup the \
  172. the existing minion config file and minion.d directories. The \
  173. values above will be used in the custom config.$\r$\n\
  174. $\r$\n\
  175. NOTE: If Master IP is set to `salt` and Minion Name is set to \
  176. `hostname` no changes will be made."
  177. ${Endif}
  178. Pop $WarningCustomConfig
  179. CreateFont $0 "Arial" 10 500 /ITALIC
  180. SendMessage $WarningCustomConfig ${WM_SETFONT} $0 1
  181. SetCtlColors $WarningCustomConfig 0xBB0000 transparent
  182. # If existing config found, add the Existing Config option to the Drop List
  183. # If not, hide the Default Warning
  184. ${If} $ExistingConfigFound == 1
  185. ${NSD_CB_AddString} $ConfigType "Existing Config"
  186. ${Else}
  187. ShowWindow $WarningDefaultConfig ${SW_HIDE}
  188. ${Endif}
  189. ${NSD_CB_SelectString} $ConfigType $ConfigType_State
  190. ${NSD_SetText} $CustomConfig $CustomConfig_State
  191. Call pageMinionConfig_OnChange
  192. nsDialogs::Show
  193. FunctionEnd
  194. Function pageMinionConfig_OnChange
  195. # You have to pop the top handle to keep the stack clean
  196. Pop $R0
  197. # Assign the current checkbox state to the variable
  198. ${NSD_GetText} $ConfigType $ConfigType_State
  199. # Update Dialog
  200. ${Switch} $ConfigType_State
  201. ${Case} "Existing Config"
  202. # Enable Master/Minion and set values
  203. EnableWindow $MasterHost 0
  204. EnableWindow $MinionName 0
  205. ${NSD_SetText} $MasterHost $ConfigMasterHost
  206. ${NSD_SetText} $MinionName $ConfigMinionName
  207. # Hide Custom File Picker
  208. ShowWindow $CustomConfig ${SW_HIDE}
  209. ShowWindow $CustomConfig_btn ${SW_HIDE}
  210. # Hide Warnings
  211. ShowWindow $WarningDefaultConfig ${SW_HIDE}
  212. ShowWindow $WarningCustomConfig ${SW_HIDE}
  213. # Show Existing Warning
  214. ShowWindow $WarningExistingConfig ${SW_SHOW}
  215. ${Break}
  216. ${Case} "Custom Config"
  217. # Enable Master/Minion and set values
  218. EnableWindow $MasterHost 1
  219. EnableWindow $MinionName 1
  220. ${NSD_SetText} $MasterHost $MasterHost_State
  221. ${NSD_SetText} $MinionName $MinionName_State
  222. # Show Custom File Picker
  223. ShowWindow $CustomConfig ${SW_SHOW}
  224. ShowWindow $CustomConfig_btn ${SW_SHOW}
  225. # Hide Warnings
  226. ShowWindow $WarningDefaultConfig ${SW_HIDE}
  227. ShowWindow $WarningExistingConfig ${SW_HIDE}
  228. # Show Custom Warning
  229. ShowWindow $WarningCustomConfig ${SW_SHOW}
  230. ${Break}
  231. ${Case} "Default Config"
  232. # Enable Master/Minion and set values
  233. EnableWindow $MasterHost 1
  234. EnableWindow $MinionName 1
  235. ${NSD_SetText} $MasterHost $MasterHost_State
  236. ${NSD_SetText} $MinionName $MinionName_State
  237. # Hide Custom File Picker
  238. ShowWindow $CustomConfig ${SW_HIDE}
  239. ShowWindow $CustomConfig_btn ${SW_HIDE}
  240. # Hide Warnings
  241. ShowWindow $WarningExistingConfig ${SW_HIDE}
  242. ShowWindow $WarningCustomConfig ${SW_HIDE}
  243. # Show Default Warning, if there is an existing config
  244. ${If} $ExistingConfigFound == 1
  245. ShowWindow $WarningDefaultConfig ${SW_SHOW}
  246. ${Endif}
  247. ${Break}
  248. ${EndSwitch}
  249. FunctionEnd
  250. # File Picker Definitions
  251. !define OFN_FILEMUSTEXIST 0x00001000
  252. !define OFN_DONTADDTOREC 0x02000000
  253. !define OPENFILENAME_SIZE_VERSION_400 76
  254. !define OPENFILENAME 'i,i,i,i,i,i,i,i,i,i,i,i,i,i,&i2,&i2,i,i,i,i'
  255. Function pageCustomConfigBtn_OnClick
  256. Pop $0
  257. System::Call '*(&t${NSIS_MAX_STRLEN})i.s' # Allocate OPENFILENAME.lpstrFile buffer
  258. System::Call '*(${OPENFILENAME})i.r0' # Allocate OPENFILENAME struct
  259. System::Call '*$0(${OPENFILENAME})(${OPENFILENAME_SIZE_VERSION_400}, \
  260. $hwndparent, , , , , , sr1, ${NSIS_MAX_STRLEN} , , , , \
  261. t"Select Custom Config File", \
  262. ${OFN_FILEMUSTEXIST} | ${OFN_DONTADDTOREC})'
  263. # Populate file name field
  264. ${NSD_GetText} $CustomConfig $2
  265. System::Call "*$1(&t${NSIS_MAX_STRLEN}r2)" ; Set lpstrFile to the old path (if any)
  266. # Open the dialog
  267. System::Call 'COMDLG32::GetOpenFileName(ir0)i.r2'
  268. # Get file name field
  269. ${If} $2 <> 0
  270. System::Call "*$1(&t${NSIS_MAX_STRLEN}.r2)"
  271. ${NSD_SetText} $CustomConfig $2
  272. ${EndIf}
  273. # Free resources
  274. System::Free $1
  275. System::Free $0
  276. FunctionEnd
  277. Function pageMinionConfig_Leave
  278. # Save the State
  279. ${NSD_GetText} $MasterHost $MasterHost_State
  280. ${NSD_GetText} $MinionName $MinionName_State
  281. ${NSD_GetText} $ConfigType $ConfigType_State
  282. ${NSD_GetText} $CustomConfig $CustomConfig_State
  283. # Abort if config file not found
  284. ${If} $ConfigType_State == "Custom Config"
  285. IfFileExists "$CustomConfig_State" continue 0
  286. MessageBox MB_OK "File not found: $CustomConfig_State" /SD IDOK
  287. Abort
  288. ${EndIf}
  289. continue:
  290. Call BackupExistingConfig
  291. FunctionEnd
  292. ###############################################################################
  293. # Custom Finish Page
  294. ###############################################################################
  295. Function pageFinish_Show
  296. # Imports so the checkboxes will show up
  297. !define SWP_NOSIZE 0x0001
  298. !define SWP_NOMOVE 0x0002
  299. !define HWND_TOP 0x0000
  300. # Create Start Minion Checkbox
  301. ${NSD_CreateCheckbox} 120u 90u 100% 12u "&Start salt-minion"
  302. Pop $CheckBox_Minion_Start
  303. SetCtlColors $CheckBox_Minion_Start "" "ffffff"
  304. # This command required to bring the checkbox to the front
  305. System::Call "User32::SetWindowPos(i, i, i, i, i, i, i) b ($CheckBox_Minion_Start, ${HWND_TOP}, 0, 0, 0, 0, ${SWP_NOSIZE}|${SWP_NOMOVE})"
  306. # Create Start Minion Delayed ComboBox
  307. ${NSD_CreateCheckbox} 130u 102u 100% 12u "&Delayed Start"
  308. Pop $CheckBox_Minion_Start_Delayed
  309. SetCtlColors $CheckBox_Minion_Start_Delayed "" "ffffff"
  310. # This command required to bring the checkbox to the front
  311. System::Call "User32::SetWindowPos(i, i, i, i, i, i, i) b ($CheckBox_Minion_Start_Delayed, ${HWND_TOP}, 0, 0, 0, 0, ${SWP_NOSIZE}|${SWP_NOMOVE})"
  312. # Load current settings for Minion
  313. ${If} $StartMinion == 1
  314. ${NSD_Check} $CheckBox_Minion_Start
  315. ${EndIf}
  316. # Load current settings for Minion Delayed
  317. ${If} $StartMinionDelayed == 1
  318. ${NSD_Check} $CheckBox_Minion_Start_Delayed
  319. ${EndIf}
  320. FunctionEnd
  321. Function pageFinish_Leave
  322. # Assign the current checkbox states
  323. ${NSD_GetState} $CheckBox_Minion_Start $StartMinion
  324. ${NSD_GetState} $CheckBox_Minion_Start_Delayed $StartMinionDelayed
  325. FunctionEnd
  326. ###############################################################################
  327. # Installation Settings
  328. ###############################################################################
  329. Name "${PRODUCT_NAME} ${PRODUCT_VERSION} (Python ${PYTHON_VERSION})"
  330. OutFile "${OutFile}"
  331. InstallDir "c:\salt"
  332. InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
  333. ShowInstDetails show
  334. ShowUnInstDetails show
  335. Section -copy_prereqs
  336. # Copy prereqs to the Plugins Directory
  337. # These files are downloaded by build_pkg.bat
  338. # This directory gets removed upon completion
  339. SetOutPath "$PLUGINSDIR\"
  340. File /r "..\prereqs\"
  341. SectionEnd
  342. # Check if the Windows 10 Universal C Runtime (KB2999226) is installed
  343. # Python 3 needs the updated ucrt on Windows 8.1 / 2012R2 and lower
  344. # They are installed via KB2999226, but we're not going to patch the system here
  345. # Instead, we're going to copy the .dll files to the \salt\bin directory
  346. Section -install_ucrt
  347. Var /GLOBAL UcrtFileName
  348. # Get the Major.Minor version Number
  349. # Windows 10 introduced CurrentMajorVersionNumber
  350. ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" \
  351. CurrentMajorVersionNumber
  352. # Windows 10/2016 will return a value here, skip to the end if returned
  353. StrCmp $R0 '' lbl_needs_ucrt 0
  354. # Found Windows 10
  355. detailPrint "KB2999226 does not apply to this machine"
  356. goto lbl_done
  357. lbl_needs_ucrt:
  358. # UCRT only needed on Windows Server 2012R2/Windows 8.1 and below
  359. # The first ReadRegStr command above should have skipped to lbl_done if on
  360. # Windows 10 box
  361. # Is the update already installed
  362. ClearErrors
  363. # Use WMI to check if it's installed
  364. detailPrint "Checking for existing UCRT (KB2999226) installation"
  365. nsExec::ExecToStack 'cmd /q /c wmic qfe get hotfixid | findstr "^KB2999226"'
  366. # Clean up the stack
  367. Pop $R0 # Gets the ErrorCode
  368. Pop $R1 # Gets the stdout, which should be KB2999226 if it's installed
  369. # If it returned KB2999226 it's already installed
  370. StrCmp $R1 'KB2999226' lbl_done
  371. detailPrint "UCRT (KB2999226) not found"
  372. # Use RunningX64 here to get the Architecture for the system running the installer
  373. # CPUARCH is defined when the installer is built and is based on the machine that
  374. # built the installer, not the target system as we need here.
  375. ${If} ${RunningX64}
  376. StrCpy $UcrtFileName "ucrt_x64.zip"
  377. ${Else}
  378. StrCpy $UcrtFileName "ucrt_x86.zip"
  379. ${EndIf}
  380. ClearErrors
  381. detailPrint "Unzipping UCRT dll files to $INSTDIR\bin"
  382. CreateDirectory $INSTDIR\bin
  383. nsisunz::UnzipToLog "$PLUGINSDIR\$UcrtFileName" "$INSTDIR\bin"
  384. # Clean up the stack
  385. Pop $R0 # Get Error
  386. ${IfNot} $R0 == "success"
  387. detailPrint "error: $R0"
  388. Sleep 3000
  389. ${Else}
  390. detailPrint "UCRT dll files copied successfully"
  391. ${EndIf}
  392. lbl_done:
  393. SectionEnd
  394. # Check and install Visual C++ redist 2013 packages
  395. # Hidden section (-) to install VCRedist
  396. Section -install_vcredist_2013
  397. Var /GLOBAL VcRedistName
  398. Var /GLOBAL VcRedistGuid
  399. Var /GLOBAL NeedVcRedist
  400. # GUIDs can be found by installing them and then running the following command:
  401. # wmic product where "Name like '%2013%minimum runtime%'" get Name, Version, IdentifyingNumber
  402. !define VCREDIST_X86_NAME "vcredist_x86_2013"
  403. !define VCREDIST_X86_GUID "{8122DAB1-ED4D-3676-BB0A-CA368196543E}"
  404. !define VCREDIST_X64_NAME "vcredist_x64_2013"
  405. !define VCREDIST_X64_GUID "{53CF6934-A98D-3D84-9146-FC4EDF3D5641}"
  406. # Only install 64bit VCRedist on 64bit machines
  407. ${If} ${CPUARCH} == "AMD64"
  408. StrCpy $VcRedistName ${VCREDIST_X64_NAME}
  409. StrCpy $VcRedistGuid ${VCREDIST_X64_GUID}
  410. Call InstallVCRedist
  411. ${Else}
  412. # Install 32bit VCRedist on all machines
  413. StrCpy $VcRedistName ${VCREDIST_X86_NAME}
  414. StrCpy $VcRedistGuid ${VCREDIST_X86_GUID}
  415. Call InstallVCRedist
  416. ${EndIf}
  417. SectionEnd
  418. Function InstallVCRedist
  419. # Check to see if it's already installed
  420. Call MsiQueryProductState
  421. ${If} $NeedVcRedist == "True"
  422. detailPrint "System requires $VcRedistName"
  423. MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 \
  424. "$VcRedistName is currently not installed. Would you like to install?" \
  425. /SD IDYES IDNO endVCRedist
  426. # If an output variable is specified ($0 in the case below),
  427. # ExecWait sets the variable with the exit code (and only sets the
  428. # error flag if an error occurs; if an error occurs, the contents
  429. # of the user variable are undefined).
  430. # http://nsis.sourceforge.net/Reference/ExecWait
  431. ClearErrors
  432. detailPrint "Installing $VcRedistName..."
  433. ExecWait '"$PLUGINSDIR\$VcRedistName.exe" /install /quiet /norestart' $0
  434. IfErrors 0 CheckVcRedistErrorCode
  435. MessageBox MB_OK \
  436. "$VcRedistName failed to install. Try installing the package manually." \
  437. /SD IDOK
  438. detailPrint "An error occurred during installation of $VcRedistName"
  439. CheckVcRedistErrorCode:
  440. # Check for Reboot Error Code (3010)
  441. ${If} $0 == 3010
  442. MessageBox MB_OK \
  443. "$VcRedistName installed but requires a restart to complete." \
  444. /SD IDOK
  445. detailPrint "Reboot and run Salt install again"
  446. # Check for any other errors
  447. ${ElseIfNot} $0 == 0
  448. MessageBox MB_OK \
  449. "$VcRedistName failed with ErrorCode: $0. Try installing the package manually." \
  450. /SD IDOK
  451. detailPrint "An error occurred during installation of $VcRedistName"
  452. detailPrint "Error: $0"
  453. ${EndIf}
  454. endVCRedist:
  455. ${EndIf}
  456. FunctionEnd
  457. Section "MainSection" SEC01
  458. SetOutPath "$INSTDIR\"
  459. SetOverwrite off
  460. CreateDirectory $INSTDIR\conf\pki\minion
  461. CreateDirectory $INSTDIR\conf\minion.d
  462. File /r "..\buildenv\"
  463. nsExec::Exec 'icacls c:\salt /inheritance:r /grant:r "*S-1-5-32-544":(OI)(CI)F /grant:r "*S-1-5-18":(OI)(CI)F'
  464. SectionEnd
  465. Function .onInit
  466. InitPluginsDir
  467. Call parseCommandLineSwitches
  468. # Uninstall msi-installed salt
  469. # Source https://nsis-dev.github.io/NSIS-Forums/html/t-303468.html
  470. !define upgradecode {FC6FB3A2-65DE-41A9-AD91-D10A402BD641} ;Salt upgrade code
  471. StrCpy $0 0
  472. loop:
  473. System::Call 'MSI::MsiEnumRelatedProducts(t "${upgradecode}",i0,i r0,t.r1)i.r2'
  474. ${If} $2 = 0
  475. # Now $1 contains the product code
  476. DetailPrint product:$1
  477. push $R0
  478. StrCpy $R0 $1
  479. Call UninstallMSI
  480. pop $R0
  481. IntOp $0 $0 + 1
  482. goto loop
  483. ${Endif}
  484. # If custom config passed, verify its existence before continuing so we
  485. # don't uninstall an existing installation and then fail
  486. ${If} $ConfigType_State == "Custom Config"
  487. IfFileExists "$CustomConfig_State" customConfigExists 0
  488. Abort
  489. ${EndIf}
  490. customConfigExists:
  491. # Check for existing installation
  492. ReadRegStr $R0 HKLM \
  493. "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
  494. "UninstallString"
  495. StrCmp $R0 "" checkOther
  496. # Found existing installation, prompt to uninstall
  497. MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
  498. "${PRODUCT_NAME} is already installed.$\n$\n\
  499. Click `OK` to remove the existing installation." \
  500. /SD IDOK IDOK uninst
  501. Abort
  502. checkOther:
  503. # Check for existing installation of full salt
  504. ReadRegStr $R0 HKLM \
  505. "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME_OTHER}" \
  506. "UninstallString"
  507. StrCmp $R0 "" skipUninstall
  508. # Found existing installation, prompt to uninstall
  509. MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
  510. "${PRODUCT_NAME_OTHER} is already installed.$\n$\n\
  511. Click `OK` to remove the existing installation." \
  512. /SD IDOK IDOK uninst
  513. Abort
  514. uninst:
  515. # Get current Silent status
  516. StrCpy $R0 0
  517. ${If} ${Silent}
  518. StrCpy $R0 1
  519. ${EndIf}
  520. # Turn on Silent mode
  521. SetSilent silent
  522. # Don't remove all directories
  523. StrCpy $DeleteInstallDir 0
  524. # Uninstall silently
  525. Call uninstallSalt
  526. # Set it back to Normal mode, if that's what it was before
  527. ${If} $R0 == 0
  528. SetSilent normal
  529. ${EndIf}
  530. skipUninstall:
  531. Call getExistingMinionConfig
  532. ${If} $ExistingConfigFound == 0
  533. ${AndIf} $ConfigType_State == "Existing Config"
  534. StrCpy $ConfigType_State "Default Config"
  535. ${EndIf}
  536. IfSilent 0 +2
  537. Call BackupExistingConfig
  538. FunctionEnd
  539. # Time Stamp Definition
  540. !define /date TIME_STAMP "%Y-%m-%d-%H-%M-%S"
  541. Function BackupExistingConfig
  542. ${If} $ExistingConfigFound == 1 # If existing config found
  543. ${AndIfNot} $ConfigType_State == "Existing Config" # If not using Existing Config
  544. # Backup the minion config
  545. Rename "$INSTDIR\conf\minion" "$INSTDIR\conf\minion-${TIME_STAMP}.bak"
  546. IfFileExists "$INSTDIR\conf\minion.d" 0 +2
  547. Rename "$INSTDIR\conf\minion.d" "$INSTDIR\conf\minion.d-${TIME_STAMP}.bak"
  548. ${EndIf}
  549. # By this point there should be no existing config
  550. # It was either backed up or wasn't there to begin with
  551. ${If} $ConfigType_State == "Custom Config" # If we're using Custom Config
  552. ${AndIfNot} $CustomConfig_State == "" # If a custom config is passed
  553. # Check for a file name
  554. # Named file should be in the same directory as the installer
  555. CreateDirectory "$INSTDIR\conf"
  556. IfFileExists "$EXEDIR\$CustomConfig_State" 0 checkFullPath
  557. CopyFiles /SILENT /FILESONLY "$EXEDIR\$CustomConfig_State" "$INSTDIR\conf\minion"
  558. goto finished
  559. # Maybe it was a full path to a file
  560. checkFullPath:
  561. IfFileExists "$CustomConfig_State" 0 finished
  562. CopyFiles /SILENT /FILESONLY "$CustomConfig_State" "$INSTDIR\conf\minion"
  563. finished:
  564. ${EndIf}
  565. FunctionEnd
  566. Section -Post
  567. WriteUninstaller "$INSTDIR\uninst.exe"
  568. # Uninstall Registry Entries
  569. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
  570. "DisplayName" "$(^Name)"
  571. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
  572. "UninstallString" "$INSTDIR\uninst.exe"
  573. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
  574. "DisplayIcon" "$INSTDIR\salt.ico"
  575. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
  576. "DisplayVersion" "${PRODUCT_VERSION}"
  577. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
  578. "URLInfoAbout" "${PRODUCT_WEB_SITE}"
  579. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
  580. "Publisher" "${PRODUCT_PUBLISHER}"
  581. WriteRegStr HKLM "SYSTEM\CurrentControlSet\services\salt-minion" \
  582. "DependOnService" "nsi"
  583. # Set the estimated size
  584. ${GetSize} "$INSTDIR\bin" "/S=OK" $0 $1 $2
  585. IntFmt $0 "0x%08X" $0
  586. WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
  587. "EstimatedSize" "$0"
  588. # Commandline Registry Entries
  589. WriteRegStr HKLM "${PRODUCT_CALL_REGKEY}" "" "$INSTDIR\salt-call.bat"
  590. WriteRegStr HKLM "${PRODUCT_CALL_REGKEY}" "Path" "$INSTDIR\bin\"
  591. WriteRegStr HKLM "${PRODUCT_MINION_REGKEY}" "" "$INSTDIR\salt-minion.bat"
  592. WriteRegStr HKLM "${PRODUCT_MINION_REGKEY}" "Path" "$INSTDIR\bin\"
  593. # Register the Salt-Minion Service
  594. nsExec::Exec "$INSTDIR\bin\ssm.exe install salt-minion $INSTDIR\bin\python.exe -E -s $INSTDIR\bin\Scripts\salt-minion -c $INSTDIR\conf -l quiet"
  595. nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion Description Salt Minion from saltstack.com"
  596. nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion Start SERVICE_AUTO_START"
  597. nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion AppStopMethodConsole 24000"
  598. nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion AppStopMethodWindow 2000"
  599. nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion AppRestartDelay 60000"
  600. ${IfNot} $ConfigType_State == "Existing Config" # If not using Existing Config
  601. Call updateMinionConfig
  602. ${EndIf}
  603. # Add $INSTDIR in the Path
  604. EnVar::SetHKLM
  605. EnVar::AddValue Path "$INSTDIR"
  606. SectionEnd
  607. Function .onInstSuccess
  608. # If StartMinionDelayed is 1, then set the service to start delayed
  609. ${If} $StartMinionDelayed == 1
  610. nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion Start SERVICE_DELAYED_AUTO_START"
  611. ${EndIf}
  612. # If start-minion is 1, then start the service
  613. ${If} $StartMinion == 1
  614. nsExec::Exec 'net start salt-minion'
  615. ${EndIf}
  616. FunctionEnd
  617. Function un.onInit
  618. # Load the parameters
  619. ${GetParameters} $R0
  620. # Uninstaller: Remove Installation Directory
  621. ClearErrors
  622. ${GetOptions} $R0 "/delete-install-dir" $R1
  623. IfErrors delete_install_dir_not_found
  624. StrCpy $DeleteInstallDir 1
  625. delete_install_dir_not_found:
  626. MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 \
  627. "Are you sure you want to completely remove $(^Name) and all of its components?" \
  628. /SD IDYES IDYES +2
  629. Abort
  630. FunctionEnd
  631. Section Uninstall
  632. Call un.uninstallSalt
  633. # Remove $INSTDIR from the Path
  634. EnVar::SetHKLM
  635. EnVar::DeleteValue Path "$INSTDIR"
  636. SectionEnd
  637. !macro uninstallSalt un
  638. Function ${un}uninstallSalt
  639. # Make sure we're in the right directory
  640. ${If} $INSTDIR == "c:\salt\bin\Scripts"
  641. StrCpy $INSTDIR "C:\salt"
  642. ${EndIf}
  643. # Stop and Remove salt-minion service
  644. nsExec::Exec 'net stop salt-minion'
  645. nsExec::Exec 'sc delete salt-minion'
  646. # Stop and remove the salt-master service
  647. nsExec::Exec 'net stop salt-master'
  648. nsExec::Exec 'sc delete salt-master'
  649. # Remove files
  650. Delete "$INSTDIR\uninst.exe"
  651. Delete "$INSTDIR\ssm.exe"
  652. Delete "$INSTDIR\salt*"
  653. Delete "$INSTDIR\vcredist.exe"
  654. RMDir /r "$INSTDIR\bin"
  655. # Remove Registry entries
  656. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
  657. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY_OTHER}"
  658. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_CALL_REGKEY}"
  659. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_CP_REGKEY}"
  660. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_KEY_REGKEY}"
  661. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_MASTER_REGKEY}"
  662. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_MINION_REGKEY}"
  663. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_RUN_REGKEY}"
  664. # Automatically close when finished
  665. SetAutoClose true
  666. # Prompt to remove the Installation directory
  667. ${IfNot} $DeleteInstallDir == 1
  668. MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 \
  669. "Would you like to completely remove $INSTDIR and all of its contents?" \
  670. /SD IDNO IDNO finished
  671. ${EndIf}
  672. # Make sure you're not removing Program Files
  673. ${If} $INSTDIR != 'Program Files'
  674. ${AndIf} $INSTDIR != 'Program Files (x86)'
  675. RMDir /r "$INSTDIR"
  676. ${EndIf}
  677. finished:
  678. FunctionEnd
  679. !macroend
  680. !insertmacro uninstallSalt ""
  681. !insertmacro uninstallSalt "un."
  682. Function un.onUninstSuccess
  683. HideWindow
  684. MessageBox MB_ICONINFORMATION|MB_OK \
  685. "$(^Name) was successfully removed from your computer." \
  686. /SD IDOK
  687. FunctionEnd
  688. ###############################################################################
  689. # Helper Functions
  690. ###############################################################################
  691. Function MsiQueryProductState
  692. # Used for detecting VCRedist Installation
  693. !define INSTALLSTATE_DEFAULT "5"
  694. StrCpy $NeedVcRedist "False"
  695. System::Call "msi::MsiQueryProductStateA(t '$VcRedistGuid') i.r0"
  696. StrCmp $0 ${INSTALLSTATE_DEFAULT} +2 0
  697. StrCpy $NeedVcRedist "True"
  698. FunctionEnd
  699. #------------------------------------------------------------------------------
  700. # Trim Function
  701. # - Trim whitespace from the beginning and end of a string
  702. # - Trims spaces, \r, \n, \t
  703. #
  704. # Usage:
  705. # Push " some string " ; String to Trim
  706. # Call Trim
  707. # Pop $0 ; Trimmed String: "some string"
  708. #
  709. # or
  710. #
  711. # ${Trim} $0 $1 ; Trimmed String, String to Trim
  712. #------------------------------------------------------------------------------
  713. Function Trim
  714. Exch $R1 # Original string
  715. Push $R2
  716. Loop:
  717. StrCpy $R2 "$R1" 1
  718. StrCmp "$R2" " " TrimLeft
  719. StrCmp "$R2" "$\r" TrimLeft
  720. StrCmp "$R2" "$\n" TrimLeft
  721. StrCmp "$R2" "$\t" TrimLeft
  722. GoTo Loop2
  723. TrimLeft:
  724. StrCpy $R1 "$R1" "" 1
  725. Goto Loop
  726. Loop2:
  727. StrCpy $R2 "$R1" 1 -1
  728. StrCmp "$R2" " " TrimRight
  729. StrCmp "$R2" "$\r" TrimRight
  730. StrCmp "$R2" "$\n" TrimRight
  731. StrCmp "$R2" "$\t" TrimRight
  732. GoTo Done
  733. TrimRight:
  734. StrCpy $R1 "$R1" -1
  735. Goto Loop2
  736. Done:
  737. Pop $R2
  738. Exch $R1
  739. FunctionEnd
  740. #------------------------------------------------------------------------------
  741. # Explode Function
  742. # - Splits a string based off the passed separator
  743. # - Each item in the string is pushed to the stack
  744. # - The last item pushed to the stack is the length of the array
  745. #
  746. # Usage:
  747. # Push "," ; Separator
  748. # Push "string,to,separate" ; String to explode
  749. # Call Explode
  750. # Pop $0 ; Number of items in the array
  751. #
  752. # or
  753. #
  754. # ${Explode} $0 $1 $2 ; Length, Separator, String
  755. #------------------------------------------------------------------------------
  756. Function Explode
  757. # Initialize variables
  758. Var /GLOBAL explString
  759. Var /GLOBAL explSeparator
  760. Var /GLOBAL explStrLen
  761. Var /GLOBAL explSepLen
  762. Var /GLOBAL explOffset
  763. Var /GLOBAL explTmp
  764. Var /GLOBAL explTmp2
  765. Var /GLOBAL explTmp3
  766. Var /GLOBAL explArrCount
  767. # Get input from user
  768. Pop $explString
  769. Pop $explSeparator
  770. # Calculates initial values
  771. StrLen $explStrLen $explString
  772. StrLen $explSepLen $explSeparator
  773. StrCpy $explArrCount 1
  774. ${If} $explStrLen <= 1 # If we got a single character
  775. ${OrIf} $explSepLen > $explStrLen # or separator is larger than the string,
  776. Push $explString # then we return initial string with no change
  777. Push 1 # and set array's length to 1
  778. Return
  779. ${EndIf}
  780. # Set offset to the last symbol of the string
  781. StrCpy $explOffset $explStrLen
  782. IntOp $explOffset $explOffset - 1
  783. # Clear temp string to exclude the possibility of appearance of occasional data
  784. StrCpy $explTmp ""
  785. StrCpy $explTmp2 ""
  786. StrCpy $explTmp3 ""
  787. # Loop until the offset becomes negative
  788. ${Do}
  789. # If offset becomes negative, it is time to leave the function
  790. ${IfThen} $explOffset == -1 ${|} ${ExitDo} ${|}
  791. # Remove everything before and after the searched part ("TempStr")
  792. StrCpy $explTmp $explString $explSepLen $explOffset
  793. ${If} $explTmp == $explSeparator
  794. # Calculating offset to start copy from
  795. IntOp $explTmp2 $explOffset + $explSepLen # Offset equals to the current offset plus length of separator
  796. StrCpy $explTmp3 $explString "" $explTmp2
  797. Push $explTmp3 # Throwing array item to the stack
  798. IntOp $explArrCount $explArrCount + 1 # Increasing array's counter
  799. StrCpy $explString $explString $explOffset 0 # Cutting all characters beginning with the separator entry
  800. StrLen $explStrLen $explString
  801. ${EndIf}
  802. ${If} $explOffset = 0 # If the beginning of the line met and there is no separator,
  803. # copying the rest of the string
  804. ${If} $explSeparator == "" # Fix for the empty separator
  805. IntOp $explArrCount $explArrCount - 1
  806. ${Else}
  807. Push $explString
  808. ${EndIf}
  809. ${EndIf}
  810. IntOp $explOffset $explOffset - 1
  811. ${Loop}
  812. Push $explArrCount
  813. FunctionEnd
  814. #------------------------------------------------------------------------------
  815. # UninstallMSI Function
  816. # - Uninstalls MSI by product code
  817. #
  818. # Usage:
  819. # Push product code
  820. # Call UninstallMSI
  821. #
  822. # Source:
  823. # https://nsis.sourceforge.io/Uninstalling_a_previous_MSI_(Windows_installer_package)
  824. #------------------------------------------------------------------------------
  825. Function UninstallMSI
  826. ; $R0 === product code
  827. MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
  828. "${PRODUCT_NAME} is already installed via MSI.$\n$\n\
  829. Click `OK` to remove the existing installation." \
  830. /SD IDOK IDOK UninstallMSI
  831. Abort
  832. UninstallMSI:
  833. ExecWait '"msiexec.exe" /x $R0 /qb /quiet /norestart'
  834. FunctionEnd
  835. ###############################################################################
  836. # Specialty Functions
  837. ###############################################################################
  838. Function getExistingMinionConfig
  839. # Set Config Found Default Value
  840. StrCpy $ExistingConfigFound 0
  841. confFind:
  842. IfFileExists "$INSTDIR\conf\minion" confFound confNotFound
  843. confNotFound:
  844. ${If} $INSTDIR == "c:\salt\bin\Scripts"
  845. StrCpy $INSTDIR "C:\salt"
  846. goto confFind
  847. ${Else}
  848. goto confReallyNotFound
  849. ${EndIf}
  850. confFound:
  851. StrCpy $ExistingConfigFound 1
  852. FileOpen $0 "$INSTDIR\conf\minion" r
  853. confLoop:
  854. ClearErrors # clear Errors
  855. FileRead $0 $1 # read the next line
  856. IfErrors EndOfFile # error is probably EOF
  857. ${StrLoc} $2 $1 "master:" ">" # find `master:` starting at the beginning
  858. ${If} $2 == 0 # if it found it in the first position, then it is defined
  859. ${StrStrAdv} $2 $1 "master: " ">" ">" "0" "0" "0" # read everything after `master: `
  860. ${Trim} $2 $2 # trim white space
  861. ${If} $2 == "" # if it's empty, it's probably a list of masters
  862. masterLoop:
  863. ClearErrors # clear Errors
  864. FileRead $0 $1 # read the next line
  865. IfErrors EndOfFile # error is probably EOF
  866. ${StrStrAdv} $2 $1 "- " ">" ">" "0" "0" "0" # read everything after `- `
  867. ${Trim} $2 $2 # trim white space
  868. ${IfNot} $2 == "" # if the line is not empty, we found something
  869. ${If} $ConfigMasterHost == "" # if the config setting is empty
  870. StrCpy $ConfigMasterHost $2 # make the first item the new entry
  871. ${Else}
  872. StrCpy $ConfigMasterHost "$ConfigMasterHost,$2" # Append the new master, comma separated
  873. ${EndIf}
  874. Goto masterLoop # check the next one
  875. ${EndIf}
  876. ${Else}
  877. StrCpy $ConfigMasterHost $2 # a single master entry
  878. ${EndIf}
  879. ${EndIf}
  880. ${StrLoc} $2 $1 "id:" ">"
  881. ${If} $2 == 0
  882. ${StrStrAdv} $2 $1 "id: " ">" ">" "0" "0" "0"
  883. ${Trim} $2 $2
  884. StrCpy $ConfigMinionName $2
  885. ${EndIf}
  886. Goto confLoop
  887. EndOfFile:
  888. FileClose $0
  889. confReallyNotFound:
  890. # Set Default Config Values if not found
  891. ${If} $ConfigMasterHost == ""
  892. StrCpy $ConfigMasterHost "salt"
  893. ${EndIf}
  894. ${If} $ConfigMinionName == ""
  895. StrCpy $ConfigMinionName "hostname"
  896. ${EndIf}
  897. FunctionEnd
  898. Var cfg_line
  899. Var chk_line
  900. Var lst_check
  901. Function updateMinionConfig
  902. ClearErrors
  903. FileOpen $0 "$INSTDIR\conf\minion" "r" # open target file for reading
  904. GetTempFileName $R0 # get new temp file name
  905. FileOpen $1 $R0 "w" # open temp file for writing
  906. StrCpy $ConfigWriteMaster 1 # write the master config value
  907. StrCpy $ConfigWriteMinion 1 # write the minion config value
  908. loop: # loop through each line
  909. FileRead $0 $cfg_line # read line from target file
  910. IfErrors done # end if errors are encountered (end of line)
  911. loop_after_read:
  912. StrCpy $lst_check 0 # list check not performed
  913. ${If} $MasterHost_State == "" # if master is empty
  914. ${OrIf} $MasterHost_State == "salt" # or if master is 'salt'
  915. StrCpy $ConfigWriteMaster 0 # no need to write master config
  916. ${EndIf} # close if statement
  917. ${If} $MinionName_State == "" # if minion is empty
  918. ${OrIf} $MinionName_State == "hostname" # and if minion is not 'hostname'
  919. StrCpy $ConfigWriteMinion 0 # no need to write minion config
  920. ${EndIf} # close if statement
  921. ${If} $ConfigWriteMaster == 1 # if we need to write master config
  922. ${StrLoc} $3 $cfg_line "master:" ">" # where is 'master:' in this line
  923. ${If} $3 == 0 # is it in the first...
  924. ${OrIf} $3 == 1 # or second position (account for comments)
  925. ${Explode} $9 "," $MasterHost_state # Split the hostname on commas, $9 is the number of items found
  926. ${If} $9 == 1 # 1 means only a single master was passed
  927. StrCpy $cfg_line "master: $MasterHost_State$\r$\n" # write the master
  928. ${Else} # make a multi-master entry
  929. StrCpy $cfg_line "master:" # make the first line "master:"
  930. loop_explode: # start a loop to go through the list in the config
  931. pop $8 # pop the next item off the stack
  932. ${Trim} $8 $8 # trim any whitespace
  933. StrCpy $cfg_line "$cfg_line$\r$\n - $8" # add it to the master variable ($2)
  934. IntOp $9 $9 - 1 # decrement the list count
  935. ${If} $9 >= 1 # if it's not 0
  936. Goto loop_explode # do it again
  937. ${EndIf} # close if statement
  938. StrCpy $cfg_line "$cfg_line$\r$\n" # Make sure there's a new line at the end
  939. # Remove remaining items in list
  940. ${While} $lst_check == 0 # while list item found
  941. FileRead $0 $chk_line # read line from target file
  942. IfErrors done # end if errors are encountered (end of line)
  943. ${StrLoc} $3 $chk_line " - " ">" # where is 'master:' in this line
  944. ${If} $3 == "" # is it in the first...
  945. StrCpy $lst_check 1 # list check performed and finished
  946. ${EndIf}
  947. ${EndWhile}
  948. ${EndIf} # close if statement
  949. StrCpy $ConfigWriteMaster 0 # master value written to config
  950. ${EndIf} # close if statement
  951. ${EndIf} # close if statement
  952. ${If} $ConfigWriteMinion == 1 # if we need to write minion config
  953. ${StrLoc} $3 $cfg_line "id:" ">" # where is 'id:' in this line
  954. ${If} $3 == 0 # is it in the first...
  955. ${OrIf} $3 == 1 # or the second position (account for comments)
  956. StrCpy $cfg_line "id: $MinionName_State$\r$\n" # write the minion config setting
  957. StrCpy $ConfigWriteMinion 0 # minion value written to config
  958. ${EndIf} # close if statement
  959. ${EndIf} # close if statement
  960. FileWrite $1 $cfg_line # write changed or unchanged line to temp file
  961. ${If} $lst_check == 1 # master not written to the config
  962. StrCpy $cfg_line $chk_line
  963. Goto loop_after_read # A loop was performed, skip the next read
  964. ${EndIf} # close if statement
  965. Goto loop # check the next line in the config file
  966. done:
  967. ClearErrors
  968. # Does master config still need to be written
  969. ${If} $ConfigWriteMaster == 1 # master not written to the config
  970. ${Explode} $9 "," $MasterHost_state # split the hostname on commas, $9 is the number of items found
  971. ${If} $9 == 1 # 1 means only a single master was passed
  972. StrCpy $cfg_line "master: $MasterHost_State" # write the master
  973. ${Else} # make a multi-master entry
  974. StrCpy $cfg_line "master:" # make the first line "master:"
  975. loop_explode_2: # start a loop to go through the list in the config
  976. pop $8 # pop the next item off the stack
  977. ${Trim} $8 $8 # trim any whitespace
  978. StrCpy $cfg_line "$cfg_line$\r$\n - $8" # add it to the master variable ($2)
  979. IntOp $9 $9 - 1 # decrement the list count
  980. ${If} $9 >= 1 # if it's not 0
  981. Goto loop_explode_2 # do it again
  982. ${EndIf} # close if statement
  983. ${EndIf} # close if statement
  984. FileWrite $1 $cfg_line # write changed or unchanged line to temp file
  985. ${EndIf} # close if statement
  986. ${If} $ConfigWriteMinion == 1 # minion ID not written to the config
  987. StrCpy $cfg_line "$\r$\nid: $MinionName_State" # write the minion config setting
  988. FileWrite $1 $cfg_line # write changed or unchanged line to temp file
  989. ${EndIf} # close if statement
  990. FileClose $0 # close target file
  991. FileClose $1 # close temp file
  992. Delete "$INSTDIR\conf\minion" # delete target file
  993. CopyFiles /SILENT $R0 "$INSTDIR\conf\minion" # copy temp file to target file
  994. Delete $R0 # delete temp file
  995. FunctionEnd
  996. Function parseCommandLineSwitches
  997. # Load the parameters
  998. ${GetParameters} $R0
  999. # Display Help
  1000. ClearErrors
  1001. ${GetOptions} $R0 "/?" $R1
  1002. IfErrors display_help_not_found
  1003. System::Call 'kernel32::GetStdHandle(i -11)i.r0'
  1004. System::Call 'kernel32::AttachConsole(i -1)i.r1'
  1005. ${If} $0 = 0
  1006. ${OrIf} $1 = 0
  1007. System::Call 'kernel32::AllocConsole()'
  1008. System::Call 'kernel32::GetStdHandle(i -11)i.r0'
  1009. ${EndIf}
  1010. FileWrite $0 "$\n"
  1011. FileWrite $0 "$\n"
  1012. FileWrite $0 "Help for Salt Minion installation$\n"
  1013. FileWrite $0 "===============================================================================$\n"
  1014. FileWrite $0 "$\n"
  1015. FileWrite $0 "/minion-name=$\t$\tA string value to set the minion name. Default value is$\n"
  1016. FileWrite $0 "$\t$\t$\t'hostname'. Setting the minion name causes the installer$\n"
  1017. FileWrite $0 "$\t$\t$\tto use the default config or a custom config if defined$\n"
  1018. FileWrite $0 "$\n"
  1019. FileWrite $0 "/master=$\t$\tA string value to set the IP address or hostname of the$\n"
  1020. FileWrite $0 "$\t$\t$\tmaster. Default value is 'salt'. You may pass a single$\n"
  1021. FileWrite $0 "$\t$\t$\tmaster or a comma-separated list of masters. Setting$\n"
  1022. FileWrite $0 "$\t$\t$\tthe master will cause the installer to use the default$\n"
  1023. FileWrite $0 "$\t$\t$\tconfig or a custom config if defined$\n"
  1024. FileWrite $0 "$\n"
  1025. FileWrite $0 "/start-minion=$\t$\t1 will start the minion service, 0 will not.$\n"
  1026. FileWrite $0 "$\t$\t$\tDefault is 1$\n"
  1027. FileWrite $0 "$\n"
  1028. FileWrite $0 "/start-minion-delayed$\tSet the minion start type to 'Automatic (Delayed Start)'$\n"
  1029. FileWrite $0 "$\n"
  1030. FileWrite $0 "/default-config$\t$\tOverwrite the existing config if present with the$\n"
  1031. FileWrite $0 "$\t$\t$\tdefault config for salt. Default is to use the existing$\n"
  1032. FileWrite $0 "$\t$\t$\tconfig if present. If /master and/or /minion-name is$\n"
  1033. FileWrite $0 "$\t$\t$\tpassed, those values will be used to update the new$\n"
  1034. FileWrite $0 "$\t$\t$\tdefault config$\n"
  1035. FileWrite $0 "$\n"
  1036. FileWrite $0 "$\t$\t$\tAny existing config will be backed up by appending$\n"
  1037. FileWrite $0 "$\t$\t$\ta timestamp and a .bak extension. That includes\n"
  1038. FileWrite $0 "$\t$\t$\tthe minion file and the minion.d directory$\n"
  1039. FileWrite $0 "$\n"
  1040. FileWrite $0 "/custom-config=$\t$\tA string value specifying the name of a custom config$\n"
  1041. FileWrite $0 "$\t$\t$\tfile in the same path as the installer or the full path$\n"
  1042. FileWrite $0 "$\t$\t$\tto a custom config file. If /master and/or /minion-name$\n"
  1043. FileWrite $0 "$\t$\t$\tis passed, those values will be used to update the new$\n"
  1044. FileWrite $0 "$\t$\t$\tcustom config$\n"
  1045. FileWrite $0 "$\n"
  1046. FileWrite $0 "$\t$\t$\tAny existing config will be backed up by appending$\n"
  1047. FileWrite $0 "$\t$\t$\ta timestamp and a .bak extension. That includes\n"
  1048. FileWrite $0 "$\t$\t$\tthe minion file and the minion.d directory$\n"
  1049. FileWrite $0 "$\n"
  1050. FileWrite $0 "/S$\t$\t$\tInstall Salt silently$\n"
  1051. FileWrite $0 "$\n"
  1052. FileWrite $0 "/?$\t$\t$\tDisplay this help screen$\n"
  1053. FileWrite $0 "$\n"
  1054. FileWrite $0 "-------------------------------------------------------------------------------$\n"
  1055. FileWrite $0 "$\n"
  1056. FileWrite $0 "Examples:$\n"
  1057. FileWrite $0 "$\n"
  1058. FileWrite $0 "${OutFile} /S$\n"
  1059. FileWrite $0 "$\n"
  1060. FileWrite $0 "${OutFile} /S /minion-name=myminion /master=master.mydomain.com /start-minion-delayed$\n"
  1061. FileWrite $0 "$\n"
  1062. FileWrite $0 "===============================================================================$\n"
  1063. FileWrite $0 "$\n"
  1064. System::Free $0
  1065. System::Free $1
  1066. System::Call 'kernel32::FreeConsole()'
  1067. # Give the user back the prompt
  1068. !define VK_RETURN 0x0D ; Enter Key
  1069. !define KEYEVENTF_EXTENDEDKEY 0x0001
  1070. !define KEYEVENTF_KEYUP 0x0002
  1071. System::Call "user32::keybd_event(i${VK_RETURN}, i0x45, i${KEYEVENTF_EXTENDEDKEY}|0, i0)"
  1072. System::Call "user32::keybd_event(i${VK_RETURN}, i0x45, i${KEYEVENTF_EXTENDEDKEY}|${KEYEVENTF_KEYUP}, i0)"
  1073. Abort
  1074. display_help_not_found:
  1075. # Set default value for Use Existing Config
  1076. StrCpy $ConfigType_State "Existing Config"
  1077. # Check for start-minion switches
  1078. # /start-service is to be deprecated, so we must check for both
  1079. ${GetOptions} $R0 "/start-service=" $R1
  1080. ${GetOptions} $R0 "/start-minion=" $R2
  1081. # Service: Start Salt Minion
  1082. ${IfNot} $R2 == ""
  1083. # If start-minion was passed something, then set it
  1084. StrCpy $StartMinion $R2
  1085. ${ElseIfNot} $R1 == ""
  1086. # If start-service was passed something, then set StartMinion to that
  1087. StrCpy $StartMinion $R1
  1088. ${Else}
  1089. # Otherwise default to 1
  1090. StrCpy $StartMinion 1
  1091. ${EndIf}
  1092. # Service: Minion Startup Type Delayed
  1093. ClearErrors
  1094. ${GetOptions} $R0 "/start-minion-delayed" $R1
  1095. IfErrors start_minion_delayed_not_found
  1096. StrCpy $StartMinionDelayed 1
  1097. start_minion_delayed_not_found:
  1098. # Minion Config: Master IP/Name
  1099. # If setting master, we don't want to use existing config
  1100. ${GetOptions} $R0 "/master=" $R1
  1101. ${IfNot} $R1 == ""
  1102. StrCpy $MasterHost_State $R1
  1103. StrCpy $ConfigType_State "Default Config"
  1104. ${ElseIf} $MasterHost_State == ""
  1105. StrCpy $MasterHost_State "salt"
  1106. ${EndIf}
  1107. # Minion Config: Minion ID
  1108. # If setting minion id, we don't want to use existing config
  1109. ${GetOptions} $R0 "/minion-name=" $R1
  1110. ${IfNot} $R1 == ""
  1111. StrCpy $MinionName_State $R1
  1112. StrCpy $ConfigType_State "Default Config"
  1113. ${ElseIf} $MinionName_State == ""
  1114. StrCpy $MinionName_State "hostname"
  1115. ${EndIf}
  1116. # Use Default Config
  1117. ${GetOptions} $R0 "/default-config" $R1
  1118. IfErrors default_config_not_found
  1119. StrCpy $ConfigType_State "Default Config"
  1120. default_config_not_found:
  1121. # Use Custom Config
  1122. # Set default value for Use Custom Config
  1123. StrCpy $CustomConfig_State ""
  1124. # Existing config will get a `.bak` extension
  1125. ${GetOptions} $R0 "/custom-config=" $R1
  1126. ${IfNot} $R1 == ""
  1127. # Custom Config was passed something, set it
  1128. StrCpy $CustomConfig_State $R1
  1129. StrCpy $ConfigType_State "Custom Config"
  1130. ${EndIf}
  1131. FunctionEnd