1
0

Salt-Minion-Setup.nsi 52 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436
  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. ${IfNot} $ConfigType_State == "Existing Config" # If not using Existing Config
  600. Call updateMinionConfig
  601. ${EndIf}
  602. # Add $INSTDIR in the Path
  603. EnVar::SetHKLM
  604. EnVar::AddValue Path "$INSTDIR"
  605. SectionEnd
  606. Function .onInstSuccess
  607. # If StartMinionDelayed is 1, then set the service to start delayed
  608. ${If} $StartMinionDelayed == 1
  609. nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion Start SERVICE_DELAYED_AUTO_START"
  610. ${EndIf}
  611. # If start-minion is 1, then start the service
  612. ${If} $StartMinion == 1
  613. nsExec::Exec 'net start salt-minion'
  614. ${EndIf}
  615. FunctionEnd
  616. Function un.onInit
  617. # Load the parameters
  618. ${GetParameters} $R0
  619. # Uninstaller: Remove Installation Directory
  620. ClearErrors
  621. ${GetOptions} $R0 "/delete-install-dir" $R1
  622. IfErrors delete_install_dir_not_found
  623. StrCpy $DeleteInstallDir 1
  624. delete_install_dir_not_found:
  625. MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 \
  626. "Are you sure you want to completely remove $(^Name) and all of its components?" \
  627. /SD IDYES IDYES +2
  628. Abort
  629. FunctionEnd
  630. Section Uninstall
  631. Call un.uninstallSalt
  632. # Remove $INSTDIR from the Path
  633. EnVar::SetHKLM
  634. EnVar::DeleteValue Path "$INSTDIR"
  635. SectionEnd
  636. !macro uninstallSalt un
  637. Function ${un}uninstallSalt
  638. # Make sure we're in the right directory
  639. ${If} $INSTDIR == "c:\salt\bin\Scripts"
  640. StrCpy $INSTDIR "C:\salt"
  641. ${EndIf}
  642. # Stop and Remove salt-minion service
  643. nsExec::Exec 'net stop salt-minion'
  644. nsExec::Exec 'sc delete salt-minion'
  645. # Stop and remove the salt-master service
  646. nsExec::Exec 'net stop salt-master'
  647. nsExec::Exec 'sc delete salt-master'
  648. # Remove files
  649. Delete "$INSTDIR\uninst.exe"
  650. Delete "$INSTDIR\ssm.exe"
  651. Delete "$INSTDIR\salt*"
  652. Delete "$INSTDIR\vcredist.exe"
  653. RMDir /r "$INSTDIR\bin"
  654. # Remove Registry entries
  655. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
  656. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY_OTHER}"
  657. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_CALL_REGKEY}"
  658. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_CP_REGKEY}"
  659. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_KEY_REGKEY}"
  660. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_MASTER_REGKEY}"
  661. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_MINION_REGKEY}"
  662. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_RUN_REGKEY}"
  663. # Automatically close when finished
  664. SetAutoClose true
  665. # Prompt to remove the Installation directory
  666. ${IfNot} $DeleteInstallDir == 1
  667. MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 \
  668. "Would you like to completely remove $INSTDIR and all of its contents?" \
  669. /SD IDNO IDNO finished
  670. ${EndIf}
  671. # Make sure you're not removing Program Files
  672. ${If} $INSTDIR != 'Program Files'
  673. ${AndIf} $INSTDIR != 'Program Files (x86)'
  674. RMDir /r "$INSTDIR"
  675. ${EndIf}
  676. finished:
  677. FunctionEnd
  678. !macroend
  679. !insertmacro uninstallSalt ""
  680. !insertmacro uninstallSalt "un."
  681. Function un.onUninstSuccess
  682. HideWindow
  683. MessageBox MB_ICONINFORMATION|MB_OK \
  684. "$(^Name) was successfully removed from your computer." \
  685. /SD IDOK
  686. FunctionEnd
  687. ###############################################################################
  688. # Helper Functions
  689. ###############################################################################
  690. Function MsiQueryProductState
  691. # Used for detecting VCRedist Installation
  692. !define INSTALLSTATE_DEFAULT "5"
  693. StrCpy $NeedVcRedist "False"
  694. System::Call "msi::MsiQueryProductStateA(t '$VcRedistGuid') i.r0"
  695. StrCmp $0 ${INSTALLSTATE_DEFAULT} +2 0
  696. StrCpy $NeedVcRedist "True"
  697. FunctionEnd
  698. #------------------------------------------------------------------------------
  699. # Trim Function
  700. # - Trim whitespace from the beginning and end of a string
  701. # - Trims spaces, \r, \n, \t
  702. #
  703. # Usage:
  704. # Push " some string " ; String to Trim
  705. # Call Trim
  706. # Pop $0 ; Trimmed String: "some string"
  707. #
  708. # or
  709. #
  710. # ${Trim} $0 $1 ; Trimmed String, String to Trim
  711. #------------------------------------------------------------------------------
  712. Function Trim
  713. Exch $R1 # Original string
  714. Push $R2
  715. Loop:
  716. StrCpy $R2 "$R1" 1
  717. StrCmp "$R2" " " TrimLeft
  718. StrCmp "$R2" "$\r" TrimLeft
  719. StrCmp "$R2" "$\n" TrimLeft
  720. StrCmp "$R2" "$\t" TrimLeft
  721. GoTo Loop2
  722. TrimLeft:
  723. StrCpy $R1 "$R1" "" 1
  724. Goto Loop
  725. Loop2:
  726. StrCpy $R2 "$R1" 1 -1
  727. StrCmp "$R2" " " TrimRight
  728. StrCmp "$R2" "$\r" TrimRight
  729. StrCmp "$R2" "$\n" TrimRight
  730. StrCmp "$R2" "$\t" TrimRight
  731. GoTo Done
  732. TrimRight:
  733. StrCpy $R1 "$R1" -1
  734. Goto Loop2
  735. Done:
  736. Pop $R2
  737. Exch $R1
  738. FunctionEnd
  739. #------------------------------------------------------------------------------
  740. # Explode Function
  741. # - Splits a string based off the passed separator
  742. # - Each item in the string is pushed to the stack
  743. # - The last item pushed to the stack is the length of the array
  744. #
  745. # Usage:
  746. # Push "," ; Separator
  747. # Push "string,to,separate" ; String to explode
  748. # Call Explode
  749. # Pop $0 ; Number of items in the array
  750. #
  751. # or
  752. #
  753. # ${Explode} $0 $1 $2 ; Length, Separator, String
  754. #------------------------------------------------------------------------------
  755. Function Explode
  756. # Initialize variables
  757. Var /GLOBAL explString
  758. Var /GLOBAL explSeparator
  759. Var /GLOBAL explStrLen
  760. Var /GLOBAL explSepLen
  761. Var /GLOBAL explOffset
  762. Var /GLOBAL explTmp
  763. Var /GLOBAL explTmp2
  764. Var /GLOBAL explTmp3
  765. Var /GLOBAL explArrCount
  766. # Get input from user
  767. Pop $explString
  768. Pop $explSeparator
  769. # Calculates initial values
  770. StrLen $explStrLen $explString
  771. StrLen $explSepLen $explSeparator
  772. StrCpy $explArrCount 1
  773. ${If} $explStrLen <= 1 # If we got a single character
  774. ${OrIf} $explSepLen > $explStrLen # or separator is larger than the string,
  775. Push $explString # then we return initial string with no change
  776. Push 1 # and set array's length to 1
  777. Return
  778. ${EndIf}
  779. # Set offset to the last symbol of the string
  780. StrCpy $explOffset $explStrLen
  781. IntOp $explOffset $explOffset - 1
  782. # Clear temp string to exclude the possibility of appearance of occasional data
  783. StrCpy $explTmp ""
  784. StrCpy $explTmp2 ""
  785. StrCpy $explTmp3 ""
  786. # Loop until the offset becomes negative
  787. ${Do}
  788. # If offset becomes negative, it is time to leave the function
  789. ${IfThen} $explOffset == -1 ${|} ${ExitDo} ${|}
  790. # Remove everything before and after the searched part ("TempStr")
  791. StrCpy $explTmp $explString $explSepLen $explOffset
  792. ${If} $explTmp == $explSeparator
  793. # Calculating offset to start copy from
  794. IntOp $explTmp2 $explOffset + $explSepLen # Offset equals to the current offset plus length of separator
  795. StrCpy $explTmp3 $explString "" $explTmp2
  796. Push $explTmp3 # Throwing array item to the stack
  797. IntOp $explArrCount $explArrCount + 1 # Increasing array's counter
  798. StrCpy $explString $explString $explOffset 0 # Cutting all characters beginning with the separator entry
  799. StrLen $explStrLen $explString
  800. ${EndIf}
  801. ${If} $explOffset = 0 # If the beginning of the line met and there is no separator,
  802. # copying the rest of the string
  803. ${If} $explSeparator == "" # Fix for the empty separator
  804. IntOp $explArrCount $explArrCount - 1
  805. ${Else}
  806. Push $explString
  807. ${EndIf}
  808. ${EndIf}
  809. IntOp $explOffset $explOffset - 1
  810. ${Loop}
  811. Push $explArrCount
  812. FunctionEnd
  813. #------------------------------------------------------------------------------
  814. # StrStr Function
  815. # - find substring in a string
  816. #
  817. # Usage:
  818. # Push "this is some string"
  819. # Push "some"
  820. # Call StrStr
  821. # Pop $0 # "some string"
  822. #------------------------------------------------------------------------------
  823. !macro StrStr un
  824. Function ${un}StrStr
  825. Exch $R1 # $R1=substring, stack=[old$R1,string,...]
  826. Exch # stack=[string,old$R1,...]
  827. Exch $R2 # $R2=string, stack=[old$R2,old$R1,...]
  828. Push $R3 # $R3=strlen(substring)
  829. Push $R4 # $R4=count
  830. Push $R5 # $R5=tmp
  831. StrLen $R3 $R1 # Get the length of the Search String
  832. StrCpy $R4 0 # Set the counter to 0
  833. loop:
  834. StrCpy $R5 $R2 $R3 $R4 # Create a moving window of the string that is
  835. # the size of the length of the search string
  836. StrCmp $R5 $R1 done # Is the contents of the window the same as
  837. # search string, then done
  838. StrCmp $R5 "" done # Is the window empty, then done
  839. IntOp $R4 $R4 + 1 # Shift the windows one character
  840. Goto loop # Repeat
  841. done:
  842. StrCpy $R1 $R2 "" $R4
  843. Pop $R5
  844. Pop $R4
  845. Pop $R3
  846. Pop $R2
  847. Exch $R1 # $R1=old$R1, stack=[result,...]
  848. FunctionEnd
  849. !macroend
  850. !insertmacro StrStr ""
  851. !insertmacro StrStr "un."
  852. #------------------------------------------------------------------------------
  853. # UninstallMSI Function
  854. # - Uninstalls MSI by product code
  855. #
  856. # Usage:
  857. # Push product code
  858. # Call UninstallMSI
  859. #
  860. # Source:
  861. # https://nsis.sourceforge.io/Uninstalling_a_previous_MSI_(Windows_installer_package)
  862. #------------------------------------------------------------------------------
  863. Function UninstallMSI
  864. ; $R0 === product code
  865. MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
  866. "${PRODUCT_NAME} is already installed via MSI.$\n$\n\
  867. Click `OK` to remove the existing installation." \
  868. /SD IDOK IDOK UninstallMSI
  869. Abort
  870. UninstallMSI:
  871. ExecWait '"msiexec.exe" /x $R0 /qb /quiet /norestart'
  872. FunctionEnd
  873. ###############################################################################
  874. # Specialty Functions
  875. ###############################################################################
  876. Function getExistingMinionConfig
  877. # Set Config Found Default Value
  878. StrCpy $ExistingConfigFound 0
  879. confFind:
  880. IfFileExists "$INSTDIR\conf\minion" confFound confNotFound
  881. confNotFound:
  882. ${If} $INSTDIR == "c:\salt\bin\Scripts"
  883. StrCpy $INSTDIR "C:\salt"
  884. goto confFind
  885. ${Else}
  886. goto confReallyNotFound
  887. ${EndIf}
  888. confFound:
  889. StrCpy $ExistingConfigFound 1
  890. FileOpen $0 "$INSTDIR\conf\minion" r
  891. confLoop:
  892. ClearErrors # clear Errors
  893. FileRead $0 $1 # read the next line
  894. IfErrors EndOfFile # error is probably EOF
  895. ${StrLoc} $2 $1 "master:" ">" # find `master:` starting at the beginning
  896. ${If} $2 == 0 # if it found it in the first position, then it is defined
  897. ${StrStrAdv} $2 $1 "master: " ">" ">" "0" "0" "0" # read everything after `master: `
  898. ${Trim} $2 $2 # trim white space
  899. ${If} $2 == "" # if it's empty, it's probably a list of masters
  900. masterLoop:
  901. ClearErrors # clear Errors
  902. FileRead $0 $1 # read the next line
  903. IfErrors EndOfFile # error is probably EOF
  904. ${StrStrAdv} $2 $1 "- " ">" ">" "0" "0" "0" # read everything after `- `
  905. ${Trim} $2 $2 # trim white space
  906. ${IfNot} $2 == "" # if the line is not empty, we found something
  907. ${If} $ConfigMasterHost == "" # if the config setting is empty
  908. StrCpy $ConfigMasterHost $2 # make the first item the new entry
  909. ${Else}
  910. StrCpy $ConfigMasterHost "$ConfigMasterHost,$2" # Append the new master, comma separated
  911. ${EndIf}
  912. Goto masterLoop # check the next one
  913. ${EndIf}
  914. ${Else}
  915. StrCpy $ConfigMasterHost $2 # a single master entry
  916. ${EndIf}
  917. ${EndIf}
  918. ${StrLoc} $2 $1 "id:" ">"
  919. ${If} $2 == 0
  920. ${StrStrAdv} $2 $1 "id: " ">" ">" "0" "0" "0"
  921. ${Trim} $2 $2
  922. StrCpy $ConfigMinionName $2
  923. ${EndIf}
  924. Goto confLoop
  925. EndOfFile:
  926. FileClose $0
  927. confReallyNotFound:
  928. # Set Default Config Values if not found
  929. ${If} $ConfigMasterHost == ""
  930. StrCpy $ConfigMasterHost "salt"
  931. ${EndIf}
  932. ${If} $ConfigMinionName == ""
  933. StrCpy $ConfigMinionName "hostname"
  934. ${EndIf}
  935. FunctionEnd
  936. Var cfg_line
  937. Var chk_line
  938. Var lst_check
  939. Function updateMinionConfig
  940. ClearErrors
  941. FileOpen $0 "$INSTDIR\conf\minion" "r" # open target file for reading
  942. GetTempFileName $R0 # get new temp file name
  943. FileOpen $1 $R0 "w" # open temp file for writing
  944. StrCpy $ConfigWriteMaster 1 # write the master config value
  945. StrCpy $ConfigWriteMinion 1 # write the minion config value
  946. loop: # loop through each line
  947. FileRead $0 $cfg_line # read line from target file
  948. IfErrors done # end if errors are encountered (end of line)
  949. loop_after_read:
  950. StrCpy $lst_check 0 # list check not performed
  951. ${If} $MasterHost_State == "" # if master is empty
  952. ${OrIf} $MasterHost_State == "salt" # or if master is 'salt'
  953. StrCpy $ConfigWriteMaster 0 # no need to write master config
  954. ${EndIf} # close if statement
  955. ${If} $MinionName_State == "" # if minion is empty
  956. ${OrIf} $MinionName_State == "hostname" # and if minion is not 'hostname'
  957. StrCpy $ConfigWriteMinion 0 # no need to write minion config
  958. ${EndIf} # close if statement
  959. ${If} $ConfigWriteMaster == 1 # if we need to write master config
  960. ${StrLoc} $3 $cfg_line "master:" ">" # where is 'master:' in this line
  961. ${If} $3 == 0 # is it in the first...
  962. ${OrIf} $3 == 1 # or second position (account for comments)
  963. ${Explode} $9 "," $MasterHost_state # Split the hostname on commas, $9 is the number of items found
  964. ${If} $9 == 1 # 1 means only a single master was passed
  965. StrCpy $cfg_line "master: $MasterHost_State$\r$\n" # write the master
  966. ${Else} # make a multi-master entry
  967. StrCpy $cfg_line "master:" # make the first line "master:"
  968. loop_explode: # start a loop to go through the list in the config
  969. pop $8 # pop the next item off the stack
  970. ${Trim} $8 $8 # trim any whitespace
  971. StrCpy $cfg_line "$cfg_line$\r$\n - $8" # add it to the master variable ($2)
  972. IntOp $9 $9 - 1 # decrement the list count
  973. ${If} $9 >= 1 # if it's not 0
  974. Goto loop_explode # do it again
  975. ${EndIf} # close if statement
  976. StrCpy $cfg_line "$cfg_line$\r$\n" # Make sure there's a new line at the end
  977. # Remove remaining items in list
  978. ${While} $lst_check == 0 # while list item found
  979. FileRead $0 $chk_line # read line from target file
  980. IfErrors done # end if errors are encountered (end of line)
  981. ${StrLoc} $3 $chk_line " - " ">" # where is 'master:' in this line
  982. ${If} $3 == "" # is it in the first...
  983. StrCpy $lst_check 1 # list check performed and finished
  984. ${EndIf}
  985. ${EndWhile}
  986. ${EndIf} # close if statement
  987. StrCpy $ConfigWriteMaster 0 # master value written to config
  988. ${EndIf} # close if statement
  989. ${EndIf} # close if statement
  990. ${If} $ConfigWriteMinion == 1 # if we need to write minion config
  991. ${StrLoc} $3 $cfg_line "id:" ">" # where is 'id:' in this line
  992. ${If} $3 == 0 # is it in the first...
  993. ${OrIf} $3 == 1 # or the second position (account for comments)
  994. StrCpy $cfg_line "id: $MinionName_State$\r$\n" # write the minion config setting
  995. StrCpy $ConfigWriteMinion 0 # minion value written to config
  996. ${EndIf} # close if statement
  997. ${EndIf} # close if statement
  998. FileWrite $1 $cfg_line # write changed or unchanged line to temp file
  999. ${If} $lst_check == 1 # master not written to the config
  1000. StrCpy $cfg_line $chk_line
  1001. Goto loop_after_read # A loop was performed, skip the next read
  1002. ${EndIf} # close if statement
  1003. Goto loop # check the next line in the config file
  1004. done:
  1005. ClearErrors
  1006. # Does master config still need to be written
  1007. ${If} $ConfigWriteMaster == 1 # master not written to the config
  1008. ${Explode} $9 "," $MasterHost_state # split the hostname on commas, $9 is the number of items found
  1009. ${If} $9 == 1 # 1 means only a single master was passed
  1010. StrCpy $cfg_line "master: $MasterHost_State" # write the master
  1011. ${Else} # make a multi-master entry
  1012. StrCpy $cfg_line "master:" # make the first line "master:"
  1013. loop_explode_2: # start a loop to go through the list in the config
  1014. pop $8 # pop the next item off the stack
  1015. ${Trim} $8 $8 # trim any whitespace
  1016. StrCpy $cfg_line "$cfg_line$\r$\n - $8" # add it to the master variable ($2)
  1017. IntOp $9 $9 - 1 # decrement the list count
  1018. ${If} $9 >= 1 # if it's not 0
  1019. Goto loop_explode_2 # do it again
  1020. ${EndIf} # close if statement
  1021. ${EndIf} # close if statement
  1022. FileWrite $1 $cfg_line # write changed or unchanged line to temp file
  1023. ${EndIf} # close if statement
  1024. ${If} $ConfigWriteMinion == 1 # minion ID not written to the config
  1025. StrCpy $cfg_line "$\r$\nid: $MinionName_State" # write the minion config setting
  1026. FileWrite $1 $cfg_line # write changed or unchanged line to temp file
  1027. ${EndIf} # close if statement
  1028. FileClose $0 # close target file
  1029. FileClose $1 # close temp file
  1030. Delete "$INSTDIR\conf\minion" # delete target file
  1031. CopyFiles /SILENT $R0 "$INSTDIR\conf\minion" # copy temp file to target file
  1032. Delete $R0 # delete temp file
  1033. FunctionEnd
  1034. Function parseCommandLineSwitches
  1035. # Load the parameters
  1036. ${GetParameters} $R0
  1037. # Display Help
  1038. ClearErrors
  1039. ${GetOptions} $R0 "/?" $R1
  1040. IfErrors display_help_not_found
  1041. System::Call 'kernel32::GetStdHandle(i -11)i.r0'
  1042. System::Call 'kernel32::AttachConsole(i -1)i.r1'
  1043. ${If} $0 = 0
  1044. ${OrIf} $1 = 0
  1045. System::Call 'kernel32::AllocConsole()'
  1046. System::Call 'kernel32::GetStdHandle(i -11)i.r0'
  1047. ${EndIf}
  1048. FileWrite $0 "$\n"
  1049. FileWrite $0 "$\n"
  1050. FileWrite $0 "Help for Salt Minion installation$\n"
  1051. FileWrite $0 "===============================================================================$\n"
  1052. FileWrite $0 "$\n"
  1053. FileWrite $0 "/minion-name=$\t$\tA string value to set the minion name. Default value is$\n"
  1054. FileWrite $0 "$\t$\t$\t'hostname'. Setting the minion name causes the installer$\n"
  1055. FileWrite $0 "$\t$\t$\tto use the default config or a custom config if defined$\n"
  1056. FileWrite $0 "$\n"
  1057. FileWrite $0 "/master=$\t$\tA string value to set the IP address or hostname of the$\n"
  1058. FileWrite $0 "$\t$\t$\tmaster. Default value is 'salt'. You may pass a single$\n"
  1059. FileWrite $0 "$\t$\t$\tmaster or a comma-separated list of masters. Setting$\n"
  1060. FileWrite $0 "$\t$\t$\tthe master will cause the installer to use the default$\n"
  1061. FileWrite $0 "$\t$\t$\tconfig or a custom config if defined$\n"
  1062. FileWrite $0 "$\n"
  1063. FileWrite $0 "/start-minion=$\t$\t1 will start the minion service, 0 will not.$\n"
  1064. FileWrite $0 "$\t$\t$\tDefault is 1$\n"
  1065. FileWrite $0 "$\n"
  1066. FileWrite $0 "/start-minion-delayed$\tSet the minion start type to 'Automatic (Delayed Start)'$\n"
  1067. FileWrite $0 "$\n"
  1068. FileWrite $0 "/default-config$\t$\tOverwrite the existing config if present with the$\n"
  1069. FileWrite $0 "$\t$\t$\tdefault config for salt. Default is to use the existing$\n"
  1070. FileWrite $0 "$\t$\t$\tconfig if present. If /master and/or /minion-name is$\n"
  1071. FileWrite $0 "$\t$\t$\tpassed, those values will be used to update the new$\n"
  1072. FileWrite $0 "$\t$\t$\tdefault config$\n"
  1073. FileWrite $0 "$\n"
  1074. FileWrite $0 "$\t$\t$\tAny existing config will be backed up by appending$\n"
  1075. FileWrite $0 "$\t$\t$\ta timestamp and a .bak extension. That includes\n"
  1076. FileWrite $0 "$\t$\t$\tthe minion file and the minion.d directory$\n"
  1077. FileWrite $0 "$\n"
  1078. FileWrite $0 "/custom-config=$\t$\tA string value specifying the name of a custom config$\n"
  1079. FileWrite $0 "$\t$\t$\tfile in the same path as the installer or the full path$\n"
  1080. FileWrite $0 "$\t$\t$\tto a custom config file. If /master and/or /minion-name$\n"
  1081. FileWrite $0 "$\t$\t$\tis passed, those values will be used to update the new$\n"
  1082. FileWrite $0 "$\t$\t$\tcustom config$\n"
  1083. FileWrite $0 "$\n"
  1084. FileWrite $0 "$\t$\t$\tAny existing config will be backed up by appending$\n"
  1085. FileWrite $0 "$\t$\t$\ta timestamp and a .bak extension. That includes\n"
  1086. FileWrite $0 "$\t$\t$\tthe minion file and the minion.d directory$\n"
  1087. FileWrite $0 "$\n"
  1088. FileWrite $0 "/S$\t$\t$\tInstall Salt silently$\n"
  1089. FileWrite $0 "$\n"
  1090. FileWrite $0 "/?$\t$\t$\tDisplay this help screen$\n"
  1091. FileWrite $0 "$\n"
  1092. FileWrite $0 "-------------------------------------------------------------------------------$\n"
  1093. FileWrite $0 "$\n"
  1094. FileWrite $0 "Examples:$\n"
  1095. FileWrite $0 "$\n"
  1096. FileWrite $0 "${OutFile} /S$\n"
  1097. FileWrite $0 "$\n"
  1098. FileWrite $0 "${OutFile} /S /minion-name=myminion /master=master.mydomain.com /start-minion-delayed$\n"
  1099. FileWrite $0 "$\n"
  1100. FileWrite $0 "===============================================================================$\n"
  1101. FileWrite $0 "$\n"
  1102. System::Free $0
  1103. System::Free $1
  1104. System::Call 'kernel32::FreeConsole()'
  1105. # Give the user back the prompt
  1106. !define VK_RETURN 0x0D ; Enter Key
  1107. !define KEYEVENTF_EXTENDEDKEY 0x0001
  1108. !define KEYEVENTF_KEYUP 0x0002
  1109. System::Call "user32::keybd_event(i${VK_RETURN}, i0x45, i${KEYEVENTF_EXTENDEDKEY}|0, i0)"
  1110. System::Call "user32::keybd_event(i${VK_RETURN}, i0x45, i${KEYEVENTF_EXTENDEDKEY}|${KEYEVENTF_KEYUP}, i0)"
  1111. Abort
  1112. display_help_not_found:
  1113. # Set default value for Use Existing Config
  1114. StrCpy $ConfigType_State "Existing Config"
  1115. # Check for start-minion switches
  1116. # /start-service is to be deprecated, so we must check for both
  1117. ${GetOptions} $R0 "/start-service=" $R1
  1118. ${GetOptions} $R0 "/start-minion=" $R2
  1119. # Service: Start Salt Minion
  1120. ${IfNot} $R2 == ""
  1121. # If start-minion was passed something, then set it
  1122. StrCpy $StartMinion $R2
  1123. ${ElseIfNot} $R1 == ""
  1124. # If start-service was passed something, then set StartMinion to that
  1125. StrCpy $StartMinion $R1
  1126. ${Else}
  1127. # Otherwise default to 1
  1128. StrCpy $StartMinion 1
  1129. ${EndIf}
  1130. # Service: Minion Startup Type Delayed
  1131. ClearErrors
  1132. ${GetOptions} $R0 "/start-minion-delayed" $R1
  1133. IfErrors start_minion_delayed_not_found
  1134. StrCpy $StartMinionDelayed 1
  1135. start_minion_delayed_not_found:
  1136. # Minion Config: Master IP/Name
  1137. # If setting master, we don't want to use existing config
  1138. ${GetOptions} $R0 "/master=" $R1
  1139. ${IfNot} $R1 == ""
  1140. StrCpy $MasterHost_State $R1
  1141. StrCpy $ConfigType_State "Default Config"
  1142. ${ElseIf} $MasterHost_State == ""
  1143. StrCpy $MasterHost_State "salt"
  1144. ${EndIf}
  1145. # Minion Config: Minion ID
  1146. # If setting minion id, we don't want to use existing config
  1147. ${GetOptions} $R0 "/minion-name=" $R1
  1148. ${IfNot} $R1 == ""
  1149. StrCpy $MinionName_State $R1
  1150. StrCpy $ConfigType_State "Default Config"
  1151. ${ElseIf} $MinionName_State == ""
  1152. StrCpy $MinionName_State "hostname"
  1153. ${EndIf}
  1154. # Use Default Config
  1155. ${GetOptions} $R0 "/default-config" $R1
  1156. IfErrors default_config_not_found
  1157. StrCpy $ConfigType_State "Default Config"
  1158. default_config_not_found:
  1159. # Use Custom Config
  1160. # Set default value for Use Custom Config
  1161. StrCpy $CustomConfig_State ""
  1162. # Existing config will get a `.bak` extension
  1163. ${GetOptions} $R0 "/custom-config=" $R1
  1164. ${IfNot} $R1 == ""
  1165. # Custom Config was passed something, set it
  1166. StrCpy $CustomConfig_State $R1
  1167. StrCpy $ConfigType_State "Custom Config"
  1168. ${EndIf}
  1169. FunctionEnd