1
0

Salt-Minion-Setup.nsi 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623
  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 "2"
  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. # This entire if block can be removed for the Sodium release... including the !define MUI_WELCOMEPAGE_TEXT
  67. # NSIS will just use the default like it does for Python 3, which should be the same test
  68. !if "${PYTHON_VERSION}" == "2"
  69. !define MUI_WELCOMEPAGE_TEXT "\
  70. WARNING: Python 2 Support will be discontinued in Sodium. Salt will only ship Python 3 \
  71. installers starting with the Sodium release.$\r$\n\
  72. $\r$\n\
  73. Setup will guide you through the installation of ${PRODUCT_NAME} ${PRODUCT_VERSION}.$\r$\n\
  74. $\r$\n\
  75. It is recommended that you close all other applications before starting Setup. This will make it possible to \
  76. update relevant system files without having to reboot your computer.$\r$\n\
  77. $\r$\n\
  78. Click Next to continue."
  79. !endif
  80. # Welcome page
  81. !insertmacro MUI_PAGE_WELCOME
  82. # License page
  83. !insertmacro MUI_PAGE_LICENSE "LICENSE.txt"
  84. # Configure Minion page
  85. Page custom pageMinionConfig pageMinionConfig_Leave
  86. # Instfiles page
  87. !insertmacro MUI_PAGE_INSTFILES
  88. # Finish page (Customized)
  89. !define MUI_PAGE_CUSTOMFUNCTION_SHOW pageFinish_Show
  90. !define MUI_PAGE_CUSTOMFUNCTION_LEAVE pageFinish_Leave
  91. !insertmacro MUI_PAGE_FINISH
  92. # Uninstaller pages
  93. !insertmacro MUI_UNPAGE_INSTFILES
  94. # Language files
  95. !insertmacro MUI_LANGUAGE "English"
  96. ###############################################################################
  97. # Custom Dialog Box Variables
  98. ###############################################################################
  99. Var Dialog
  100. Var Label
  101. Var CheckBox_Minion_Start
  102. Var CheckBox_Minion_Start_Delayed
  103. Var ConfigMasterHost
  104. Var MasterHost
  105. Var MasterHost_State
  106. Var ConfigMinionName
  107. Var MinionName
  108. Var MinionName_State
  109. Var ExistingConfigFound
  110. Var ConfigType
  111. Var ConfigType_State
  112. Var CustomConfig
  113. Var CustomConfig_btn
  114. Var CustomConfig_State
  115. Var WarningCustomConfig
  116. Var WarningExistingConfig
  117. Var WarningDefaultConfig
  118. Var StartMinion
  119. Var StartMinionDelayed
  120. Var DeleteInstallDir
  121. Var ConfigWriteMinion
  122. Var ConfigWriteMaster
  123. ###############################################################################
  124. # Minion Settings Dialog Box
  125. ###############################################################################
  126. Function pageMinionConfig
  127. # Set Page Title and Description
  128. !insertmacro MUI_HEADER_TEXT "Minion Settings" "Set the Minion Master and ID"
  129. nsDialogs::Create 1018
  130. Pop $Dialog
  131. ${If} $Dialog == error
  132. Abort
  133. ${EndIf}
  134. # Master IP or Hostname Dialog Control
  135. ${NSD_CreateLabel} 0 0 100% 12u "Master IP or Hostname:"
  136. Pop $Label
  137. ${NSD_CreateText} 0 13u 100% 12u $MasterHost_State
  138. Pop $MasterHost
  139. # Minion ID Dialog Control
  140. ${NSD_CreateLabel} 0 30u 100% 12u "Minion Name:"
  141. Pop $Label
  142. ${NSD_CreateText} 0 43u 100% 12u $MinionName_State
  143. Pop $MinionName
  144. # Config Drop List
  145. ${NSD_CreateDropList} 0 65u 25% 36u ""
  146. Pop $ConfigType
  147. ${NSD_CB_AddString} $ConfigType "Default Config"
  148. ${NSD_CB_AddString} $ConfigType "Custom Config"
  149. ${NSD_OnChange} $ConfigType pageMinionConfig_OnChange
  150. # Add Existing Config Warning Label
  151. ${NSD_CreateLabel} 0 80u 100% 60u "The values above are taken from an \
  152. existing configuration found in `c:\salt\conf\minion`. Configuration \
  153. settings defined in the `minion.d` directories, if they exist, are not \
  154. shown here.$\r$\n\
  155. $\r$\n\
  156. Clicking `Install` will leave the existing config unchanged."
  157. Pop $WarningExistingConfig
  158. CreateFont $0 "Arial" 10 500 /ITALIC
  159. SendMessage $WarningExistingConfig ${WM_SETFONT} $0 1
  160. SetCtlColors $WarningExistingConfig 0xBB0000 transparent
  161. # Add Default Config Warning Label
  162. ${NSD_CreateLabel} 0 80u 100% 60u "Clicking `Install` will backup the \
  163. the existing minion config file and minion.d directories. The values \
  164. above will be used in the new default config.$\r$\n\
  165. $\r$\n\
  166. NOTE: If Master IP is set to `salt` and Minion Name is set to \
  167. `hostname` no changes will be made."
  168. Pop $WarningDefaultConfig
  169. CreateFont $0 "Arial" 10 500 /ITALIC
  170. SendMessage $WarningDefaultConfig ${WM_SETFONT} $0 1
  171. SetCtlColors $WarningDefaultConfig 0xBB0000 transparent
  172. # Add Custom Config File Selector and Warning Label
  173. ${NSD_CreateText} 26% 65u 64% 12u $CustomConfig_State
  174. Pop $CustomConfig
  175. ${NSD_CreateButton} 91% 65u 9% 12u "..."
  176. Pop $CustomConfig_btn
  177. ${NSD_OnClick} $CustomConfig_btn pageCustomConfigBtn_OnClick
  178. ${If} $ExistingConfigFound == 0
  179. ${NSD_CreateLabel} 0 80u 100% 60u "Values entered above will be used \
  180. in the custom config.$\r$\n\
  181. $\r$\n\
  182. NOTE: If Master IP is set to `salt` and Minion Name is set to \
  183. `hostname` no changes will be made."
  184. ${Else}
  185. ${NSD_CreateLabel} 0 80u 100% 60u "Clicking `Install` will backup the \
  186. the existing minion config file and minion.d directories. The \
  187. values above will be used in the custom config.$\r$\n\
  188. $\r$\n\
  189. NOTE: If Master IP is set to `salt` and Minion Name is set to \
  190. `hostname` no changes will be made."
  191. ${Endif}
  192. Pop $WarningCustomConfig
  193. CreateFont $0 "Arial" 10 500 /ITALIC
  194. SendMessage $WarningCustomConfig ${WM_SETFONT} $0 1
  195. SetCtlColors $WarningCustomConfig 0xBB0000 transparent
  196. # If existing config found, add the Existing Config option to the Drop List
  197. # If not, hide the Default Warning
  198. ${If} $ExistingConfigFound == 1
  199. ${NSD_CB_AddString} $ConfigType "Existing Config"
  200. ${Else}
  201. ShowWindow $WarningDefaultConfig ${SW_HIDE}
  202. ${Endif}
  203. ${NSD_CB_SelectString} $ConfigType $ConfigType_State
  204. ${NSD_SetText} $CustomConfig $CustomConfig_State
  205. Call pageMinionConfig_OnChange
  206. nsDialogs::Show
  207. FunctionEnd
  208. Function pageMinionConfig_OnChange
  209. # You have to pop the top handle to keep the stack clean
  210. Pop $R0
  211. # Assign the current checkbox state to the variable
  212. ${NSD_GetText} $ConfigType $ConfigType_State
  213. # Update Dialog
  214. ${Switch} $ConfigType_State
  215. ${Case} "Existing Config"
  216. # Enable Master/Minion and set values
  217. EnableWindow $MasterHost 0
  218. EnableWindow $MinionName 0
  219. ${NSD_SetText} $MasterHost $ConfigMasterHost
  220. ${NSD_SetText} $MinionName $ConfigMinionName
  221. # Hide Custom File Picker
  222. ShowWindow $CustomConfig ${SW_HIDE}
  223. ShowWindow $CustomConfig_btn ${SW_HIDE}
  224. # Hide Warnings
  225. ShowWindow $WarningDefaultConfig ${SW_HIDE}
  226. ShowWindow $WarningCustomConfig ${SW_HIDE}
  227. # Show Existing Warning
  228. ShowWindow $WarningExistingConfig ${SW_SHOW}
  229. ${Break}
  230. ${Case} "Custom Config"
  231. # Enable Master/Minion and set values
  232. EnableWindow $MasterHost 1
  233. EnableWindow $MinionName 1
  234. ${NSD_SetText} $MasterHost $MasterHost_State
  235. ${NSD_SetText} $MinionName $MinionName_State
  236. # Show Custom File Picker
  237. ShowWindow $CustomConfig ${SW_SHOW}
  238. ShowWindow $CustomConfig_btn ${SW_SHOW}
  239. # Hide Warnings
  240. ShowWindow $WarningDefaultConfig ${SW_HIDE}
  241. ShowWindow $WarningExistingConfig ${SW_HIDE}
  242. # Show Custom Warning
  243. ShowWindow $WarningCustomConfig ${SW_SHOW}
  244. ${Break}
  245. ${Case} "Default Config"
  246. # Enable Master/Minion and set values
  247. EnableWindow $MasterHost 1
  248. EnableWindow $MinionName 1
  249. ${NSD_SetText} $MasterHost $MasterHost_State
  250. ${NSD_SetText} $MinionName $MinionName_State
  251. # Hide Custom File Picker
  252. ShowWindow $CustomConfig ${SW_HIDE}
  253. ShowWindow $CustomConfig_btn ${SW_HIDE}
  254. # Hide Warnings
  255. ShowWindow $WarningExistingConfig ${SW_HIDE}
  256. ShowWindow $WarningCustomConfig ${SW_HIDE}
  257. # Show Default Warning, if there is an existing config
  258. ${If} $ExistingConfigFound == 1
  259. ShowWindow $WarningDefaultConfig ${SW_SHOW}
  260. ${Endif}
  261. ${Break}
  262. ${EndSwitch}
  263. FunctionEnd
  264. # File Picker Definitions
  265. !define OFN_FILEMUSTEXIST 0x00001000
  266. !define OFN_DONTADDTOREC 0x02000000
  267. !define OPENFILENAME_SIZE_VERSION_400 76
  268. !define OPENFILENAME 'i,i,i,i,i,i,i,i,i,i,i,i,i,i,&i2,&i2,i,i,i,i'
  269. Function pageCustomConfigBtn_OnClick
  270. Pop $0
  271. System::Call '*(&t${NSIS_MAX_STRLEN})i.s' # Allocate OPENFILENAME.lpstrFile buffer
  272. System::Call '*(${OPENFILENAME})i.r0' # Allocate OPENFILENAME struct
  273. System::Call '*$0(${OPENFILENAME})(${OPENFILENAME_SIZE_VERSION_400}, \
  274. $hwndparent, , , , , , sr1, ${NSIS_MAX_STRLEN} , , , , \
  275. t"Select Custom Config File", \
  276. ${OFN_FILEMUSTEXIST} | ${OFN_DONTADDTOREC})'
  277. # Populate file name field
  278. ${NSD_GetText} $CustomConfig $2
  279. System::Call "*$1(&t${NSIS_MAX_STRLEN}r2)" ; Set lpstrFile to the old path (if any)
  280. # Open the dialog
  281. System::Call 'COMDLG32::GetOpenFileName(ir0)i.r2'
  282. # Get file name field
  283. ${If} $2 <> 0
  284. System::Call "*$1(&t${NSIS_MAX_STRLEN}.r2)"
  285. ${NSD_SetText} $CustomConfig $2
  286. ${EndIf}
  287. # Free resources
  288. System::Free $1
  289. System::Free $0
  290. FunctionEnd
  291. Function pageMinionConfig_Leave
  292. # Save the State
  293. ${NSD_GetText} $MasterHost $MasterHost_State
  294. ${NSD_GetText} $MinionName $MinionName_State
  295. ${NSD_GetText} $ConfigType $ConfigType_State
  296. ${NSD_GetText} $CustomConfig $CustomConfig_State
  297. # Abort if config file not found
  298. ${If} $ConfigType_State == "Custom Config"
  299. IfFileExists "$CustomConfig_State" continue 0
  300. MessageBox MB_OK "File not found: $CustomConfig_State" /SD IDOK
  301. Abort
  302. ${EndIf}
  303. continue:
  304. Call BackupExistingConfig
  305. FunctionEnd
  306. ###############################################################################
  307. # Custom Finish Page
  308. ###############################################################################
  309. Function pageFinish_Show
  310. # Imports so the checkboxes will show up
  311. !define SWP_NOSIZE 0x0001
  312. !define SWP_NOMOVE 0x0002
  313. !define HWND_TOP 0x0000
  314. # Create Start Minion Checkbox
  315. ${NSD_CreateCheckbox} 120u 90u 100% 12u "&Start salt-minion"
  316. Pop $CheckBox_Minion_Start
  317. SetCtlColors $CheckBox_Minion_Start "" "ffffff"
  318. # This command required to bring the checkbox to the front
  319. 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})"
  320. # Create Start Minion Delayed ComboBox
  321. ${NSD_CreateCheckbox} 130u 102u 100% 12u "&Delayed Start"
  322. Pop $CheckBox_Minion_Start_Delayed
  323. SetCtlColors $CheckBox_Minion_Start_Delayed "" "ffffff"
  324. # This command required to bring the checkbox to the front
  325. 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})"
  326. # Load current settings for Minion
  327. ${If} $StartMinion == 1
  328. ${NSD_Check} $CheckBox_Minion_Start
  329. ${EndIf}
  330. # Load current settings for Minion Delayed
  331. ${If} $StartMinionDelayed == 1
  332. ${NSD_Check} $CheckBox_Minion_Start_Delayed
  333. ${EndIf}
  334. FunctionEnd
  335. Function pageFinish_Leave
  336. # Assign the current checkbox states
  337. ${NSD_GetState} $CheckBox_Minion_Start $StartMinion
  338. ${NSD_GetState} $CheckBox_Minion_Start_Delayed $StartMinionDelayed
  339. FunctionEnd
  340. ###############################################################################
  341. # Installation Settings
  342. ###############################################################################
  343. !if ${PYTHON_VERSION} == 3
  344. Name "${PRODUCT_NAME} ${PRODUCT_VERSION} (Python ${PYTHON_VERSION})"
  345. !else
  346. Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
  347. !endif
  348. OutFile "${OutFile}"
  349. InstallDir "c:\salt"
  350. InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
  351. ShowInstDetails show
  352. ShowUnInstDetails show
  353. Section -copy_prereqs
  354. # Copy prereqs to the Plugins Directory
  355. # These files will be vcredist 2008 and KB2999226 for Win8.1 and below
  356. # These files are downloaded by build_pkg.bat
  357. # This directory gets removed upon completion
  358. SetOutPath "$PLUGINSDIR\"
  359. File /r "..\prereqs\"
  360. SectionEnd
  361. # Check and install the Windows 10 Universal C Runtime (KB2999226)
  362. # ucrt is needed on Windows 8.1 and lower
  363. # They are installed as a Microsoft Update package (.msu)
  364. # ucrt for Windows 8.1 RT is only available via Windows Update
  365. Section -install_ucrt
  366. Var /GLOBAL MsuPrefix
  367. Var /GLOBAL MsuFileName
  368. # UCRT only needs to be installed for Python 3
  369. StrCmp ${PYTHON_VERSION} 2 lbl_done
  370. # Get the Major.Minor version Number
  371. # Windows 10 introduced CurrentMajorVersionNumber
  372. ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" \
  373. CurrentMajorVersionNumber
  374. # Windows 10/2016 will return a value here, skip to the end if returned
  375. StrCmp $R0 '' lbl_needs_ucrt 0
  376. # Found Windows 10
  377. detailPrint "KB2999226 does not apply to this machine"
  378. goto lbl_done
  379. lbl_needs_ucrt:
  380. # UCRT only needed on Windows Server 2012R2/Windows 8.1 and below
  381. # The first ReadRegStr command above should have skipped to lbl_done if on
  382. # Windows 10 box
  383. # Is the update already installed
  384. ClearErrors
  385. # Use WMI to check if it's installed
  386. detailPrint "Checking for existing KB2999226 installation"
  387. nsExec::ExecToStack 'cmd /q /c wmic qfe get hotfixid | findstr "^KB2999226"'
  388. # Clean up the stack
  389. Pop $R0 # Gets the ErrorCode
  390. Pop $R1 # Gets the stdout, which should be KB2999226 if it's installed
  391. # If it returned KB2999226 it's already installed
  392. StrCmp $R1 'KB2999226' lbl_done
  393. detailPrint "KB2999226 not found"
  394. # All lower versions of Windows
  395. ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" \
  396. CurrentVersion
  397. # Get the name of the .msu file based on the value of $R0
  398. ${Switch} "$R0"
  399. ${Case} "6.3"
  400. StrCpy $MsuPrefix "Windows8.1"
  401. ${break}
  402. ${Case} "6.2"
  403. StrCpy $MsuPrefix "Windows8-RT"
  404. ${break}
  405. ${Case} "6.1"
  406. StrCpy $MsuPrefix "Windows6.1"
  407. ${break}
  408. ${Case} "6.0"
  409. StrCpy $MsuPrefix "Windows6.0"
  410. ${break}
  411. ${EndSwitch}
  412. # Use RunningX64 here to get the Architecture for the system running the installer
  413. # CPUARCH is defined when the installer is built and is based on the machine that
  414. # built the installer, not the target system as we need here.
  415. ${If} ${RunningX64}
  416. StrCpy $MsuFileName "$MsuPrefix-KB2999226-x64.msu"
  417. ${Else}
  418. StrCpy $MsuFileName "$MsuPrefix-KB2999226-x86.msu"
  419. ${EndIf}
  420. ClearErrors
  421. detailPrint "Installing KB2999226 using file $MsuFileName"
  422. nsExec::ExecToStack 'cmd /c wusa "$PLUGINSDIR\$MsuFileName" /quiet /norestart'
  423. # Clean up the stack
  424. Pop $R0 # Get Error
  425. Pop $R1 # Get stdout
  426. ${IfNot} $R0 == 0
  427. detailPrint "error: $R0"
  428. detailPrint "output: $R2"
  429. Sleep 3000
  430. ${Else}
  431. detailPrint "KB2999226 installed successfully"
  432. ${EndIf}
  433. lbl_done:
  434. SectionEnd
  435. # Check and install Visual C++ redist packages
  436. # See http://blogs.msdn.com/b/astebner/archive/2009/01/29/9384143.aspx for more info
  437. # Hidden section (-) to install VCRedist
  438. Section -install_vcredist
  439. Var /GLOBAL VcRedistName
  440. Var /GLOBAL VcRedistGuid
  441. Var /GLOBAL NeedVcRedist
  442. Var /GLOBAL CheckVcRedist
  443. StrCpy $CheckVcRedist "False"
  444. # Visual C++ 2008 SP1 MFC Security Update redist packages
  445. !define PY2_VC_REDIST_NAME "VC_Redist_2008_SP1_MFC"
  446. !define PY2_VC_REDIST_X64_GUID "{5FCE6D76-F5DC-37AB-B2B8-22AB8CEDB1D4}"
  447. !define PY2_VC_REDIST_X86_GUID "{9BE518E6-ECC6-35A9-88E4-87755C07200F}"
  448. # VCRedist only needs to be installed for Python 2
  449. ${If} ${PYTHON_VERSION} == 2
  450. StrCpy $VcRedistName ${PY2_VC_REDIST_NAME}
  451. ${If} ${CPUARCH} == "AMD64"
  452. StrCpy $VcRedistGuid ${PY2_VC_REDIST_X64_GUID}
  453. ${Else}
  454. StrCpy $VcRedistGuid ${PY2_VC_REDIST_X86_GUID}
  455. ${EndIf}
  456. # VCRedist 2008 only needed on Windows Server 2008R2/Windows 7 and below
  457. ${If} ${AtMostWin2008R2}
  458. StrCpy $CheckVcRedist "True"
  459. ${EndIf}
  460. ${EndIf}
  461. ${If} $CheckVcRedist == "True"
  462. Push $VcRedistGuid
  463. Call MsiQueryProductState
  464. ${If} $NeedVcRedist == "True"
  465. MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 \
  466. "$VcRedistName is currently not installed. Would you like to install?" \
  467. /SD IDYES IDNO endVcRedist
  468. # If an output variable is specified ($0 in the case below),
  469. # ExecWait sets the variable with the exit code (and only sets the
  470. # error flag if an error occurs; if an error occurs, the contents
  471. # of the user variable are undefined).
  472. # http://nsis.sourceforge.net/Reference/ExecWait
  473. ClearErrors
  474. ExecWait '"$PLUGINSDIR\vcredist.exe" /q' $0
  475. IfErrors 0 CheckVcRedistErrorCode
  476. MessageBox MB_OK \
  477. "$VcRedistName failed to install. Try installing the package manually." \
  478. /SD IDOK
  479. Goto endVcRedist
  480. CheckVcRedistErrorCode:
  481. # Check for Reboot Error Code (3010)
  482. ${If} $0 == 3010
  483. MessageBox MB_OK \
  484. "$VcRedistName installed but requires a restart to complete." \
  485. /SD IDOK
  486. # Check for any other errors
  487. ${ElseIfNot} $0 == 0
  488. MessageBox MB_OK \
  489. "$VcRedistName failed with ErrorCode: $0. Try installing the package manually." \
  490. /SD IDOK
  491. ${EndIf}
  492. endVcRedist:
  493. ${EndIf}
  494. ${EndIf}
  495. SectionEnd
  496. Section "MainSection" SEC01
  497. SetOutPath "$INSTDIR\"
  498. SetOverwrite off
  499. CreateDirectory $INSTDIR\conf\pki\minion
  500. CreateDirectory $INSTDIR\conf\minion.d
  501. File /r "..\buildenv\"
  502. 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'
  503. SectionEnd
  504. Function .onInit
  505. Call parseCommandLineSwitches
  506. # If custom config passed, verify its existence before continuing so we
  507. # don't uninstall an existing installation and then fail
  508. ${If} $ConfigType_State == "Custom Config"
  509. IfFileExists "$CustomConfig_State" customConfigExists 0
  510. Abort
  511. ${EndIf}
  512. customConfigExists:
  513. # Check for existing installation
  514. ReadRegStr $R0 HKLM \
  515. "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
  516. "UninstallString"
  517. StrCmp $R0 "" checkOther
  518. # Found existing installation, prompt to uninstall
  519. MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
  520. "${PRODUCT_NAME} is already installed.$\n$\n\
  521. Click `OK` to remove the existing installation." \
  522. /SD IDOK IDOK uninst
  523. Abort
  524. checkOther:
  525. # Check for existing installation of full salt
  526. ReadRegStr $R0 HKLM \
  527. "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME_OTHER}" \
  528. "UninstallString"
  529. StrCmp $R0 "" skipUninstall
  530. # Found existing installation, prompt to uninstall
  531. MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
  532. "${PRODUCT_NAME_OTHER} is already installed.$\n$\n\
  533. Click `OK` to remove the existing installation." \
  534. /SD IDOK IDOK uninst
  535. Abort
  536. uninst:
  537. # Get current Silent status
  538. StrCpy $R0 0
  539. ${If} ${Silent}
  540. StrCpy $R0 1
  541. ${EndIf}
  542. # Turn on Silent mode
  543. SetSilent silent
  544. # Don't remove all directories
  545. StrCpy $DeleteInstallDir 0
  546. # Uninstall silently
  547. Call uninstallSalt
  548. # Set it back to Normal mode, if that's what it was before
  549. ${If} $R0 == 0
  550. SetSilent normal
  551. ${EndIf}
  552. skipUninstall:
  553. Call getExistingMinionConfig
  554. ${If} $ExistingConfigFound == 0
  555. ${AndIf} $ConfigType_State == "Existing Config"
  556. StrCpy $ConfigType_State "Default Config"
  557. ${EndIf}
  558. IfSilent 0 +2
  559. Call BackupExistingConfig
  560. FunctionEnd
  561. # Time Stamp Definition
  562. !define /date TIME_STAMP "%Y-%m-%d-%H-%M-%S"
  563. Function BackupExistingConfig
  564. ${If} $ExistingConfigFound == 1 # If existing config found
  565. ${AndIfNot} $ConfigType_State == "Existing Config" # If not using Existing Config
  566. # Backup the minion config
  567. Rename "$INSTDIR\conf\minion" "$INSTDIR\conf\minion-${TIME_STAMP}.bak"
  568. IfFileExists "$INSTDIR\conf\minion.d" 0 +2
  569. Rename "$INSTDIR\conf\minion.d" "$INSTDIR\conf\minion.d-${TIME_STAMP}.bak"
  570. ${EndIf}
  571. # By this point there should be no existing config
  572. # It was either backed up or wasn't there to begin with
  573. ${If} $ConfigType_State == "Custom Config" # If we're using Custom Config
  574. ${AndIfNot} $CustomConfig_State == "" # If a custom config is passed
  575. # Check for a file name
  576. # Named file should be in the same directory as the installer
  577. CreateDirectory "$INSTDIR\conf"
  578. IfFileExists "$EXEDIR\$CustomConfig_State" 0 checkFullPath
  579. CopyFiles /SILENT /FILESONLY "$EXEDIR\$CustomConfig_State" "$INSTDIR\conf\minion"
  580. goto finished
  581. # Maybe it was a full path to a file
  582. checkFullPath:
  583. IfFileExists "$CustomConfig_State" 0 finished
  584. CopyFiles /SILENT /FILESONLY "$CustomConfig_State" "$INSTDIR\conf\minion"
  585. finished:
  586. ${EndIf}
  587. FunctionEnd
  588. Section -Post
  589. WriteUninstaller "$INSTDIR\uninst.exe"
  590. # Uninstall Registry Entries
  591. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
  592. "DisplayName" "$(^Name)"
  593. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
  594. "UninstallString" "$INSTDIR\uninst.exe"
  595. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
  596. "DisplayIcon" "$INSTDIR\salt.ico"
  597. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
  598. "DisplayVersion" "${PRODUCT_VERSION}"
  599. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
  600. "URLInfoAbout" "${PRODUCT_WEB_SITE}"
  601. WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
  602. "Publisher" "${PRODUCT_PUBLISHER}"
  603. WriteRegStr HKLM "SYSTEM\CurrentControlSet\services\salt-minion" \
  604. "DependOnService" "nsi"
  605. # Set the estimated size
  606. ${GetSize} "$INSTDIR\bin" "/S=OK" $0 $1 $2
  607. IntFmt $0 "0x%08X" $0
  608. WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
  609. "EstimatedSize" "$0"
  610. # Commandline Registry Entries
  611. WriteRegStr HKLM "${PRODUCT_CALL_REGKEY}" "" "$INSTDIR\salt-call.bat"
  612. WriteRegStr HKLM "${PRODUCT_CALL_REGKEY}" "Path" "$INSTDIR\bin\"
  613. WriteRegStr HKLM "${PRODUCT_MINION_REGKEY}" "" "$INSTDIR\salt-minion.bat"
  614. WriteRegStr HKLM "${PRODUCT_MINION_REGKEY}" "Path" "$INSTDIR\bin\"
  615. # Register the Salt-Minion Service
  616. 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"
  617. nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion Description Salt Minion from saltstack.com"
  618. nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion Start SERVICE_AUTO_START"
  619. nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion AppStopMethodConsole 24000"
  620. nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion AppStopMethodWindow 2000"
  621. ${IfNot} $ConfigType_State == "Existing Config" # If not using Existing Config
  622. Call updateMinionConfig
  623. ${EndIf}
  624. Push "C:\salt"
  625. Call AddToPath
  626. SectionEnd
  627. Function .onInstSuccess
  628. # If StartMinionDelayed is 1, then set the service to start delayed
  629. ${If} $StartMinionDelayed == 1
  630. nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion Start SERVICE_DELAYED_AUTO_START"
  631. ${EndIf}
  632. # If start-minion is 1, then start the service
  633. ${If} $StartMinion == 1
  634. nsExec::Exec 'net start salt-minion'
  635. ${EndIf}
  636. FunctionEnd
  637. Function un.onInit
  638. # Load the parameters
  639. ${GetParameters} $R0
  640. # Uninstaller: Remove Installation Directory
  641. ClearErrors
  642. ${GetOptions} $R0 "/delete-install-dir" $R1
  643. IfErrors delete_install_dir_not_found
  644. StrCpy $DeleteInstallDir 1
  645. delete_install_dir_not_found:
  646. MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 \
  647. "Are you sure you want to completely remove $(^Name) and all of its components?" \
  648. /SD IDYES IDYES +2
  649. Abort
  650. FunctionEnd
  651. Section Uninstall
  652. Call un.uninstallSalt
  653. # Remove C:\salt from the Path
  654. Push "C:\salt"
  655. Call un.RemoveFromPath
  656. SectionEnd
  657. !macro uninstallSalt un
  658. Function ${un}uninstallSalt
  659. # Make sure we're in the right directory
  660. ${If} $INSTDIR == "c:\salt\bin\Scripts"
  661. StrCpy $INSTDIR "C:\salt"
  662. ${EndIf}
  663. # Stop and Remove salt-minion service
  664. nsExec::Exec 'net stop salt-minion'
  665. nsExec::Exec 'sc delete salt-minion'
  666. # Stop and remove the salt-master service
  667. nsExec::Exec 'net stop salt-master'
  668. nsExec::Exec 'sc delete salt-master'
  669. # Remove files
  670. Delete "$INSTDIR\uninst.exe"
  671. Delete "$INSTDIR\ssm.exe"
  672. Delete "$INSTDIR\salt*"
  673. Delete "$INSTDIR\vcredist.exe"
  674. RMDir /r "$INSTDIR\bin"
  675. # Remove Registry entries
  676. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
  677. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY_OTHER}"
  678. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_CALL_REGKEY}"
  679. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_CP_REGKEY}"
  680. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_KEY_REGKEY}"
  681. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_MASTER_REGKEY}"
  682. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_MINION_REGKEY}"
  683. DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_RUN_REGKEY}"
  684. # Automatically close when finished
  685. SetAutoClose true
  686. # Prompt to remove the Installation directory
  687. ${IfNot} $DeleteInstallDir == 1
  688. MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 \
  689. "Would you like to completely remove $INSTDIR and all of its contents?" \
  690. /SD IDNO IDNO finished
  691. ${EndIf}
  692. # Make sure you're not removing Program Files
  693. ${If} $INSTDIR != 'Program Files'
  694. ${AndIf} $INSTDIR != 'Program Files (x86)'
  695. RMDir /r "$INSTDIR"
  696. ${EndIf}
  697. finished:
  698. FunctionEnd
  699. !macroend
  700. !insertmacro uninstallSalt ""
  701. !insertmacro uninstallSalt "un."
  702. Function un.onUninstSuccess
  703. HideWindow
  704. MessageBox MB_ICONINFORMATION|MB_OK \
  705. "$(^Name) was successfully removed from your computer." \
  706. /SD IDOK
  707. FunctionEnd
  708. ###############################################################################
  709. # Helper Functions
  710. ###############################################################################
  711. Function MsiQueryProductState
  712. # Used for detecting VCRedist Installation
  713. !define INSTALLSTATE_DEFAULT "5"
  714. Pop $R0
  715. StrCpy $NeedVcRedist "False"
  716. System::Call "msi::MsiQueryProductStateA(t '$R0') i.r0"
  717. StrCmp $0 ${INSTALLSTATE_DEFAULT} +2 0
  718. StrCpy $NeedVcRedist "True"
  719. FunctionEnd
  720. #------------------------------------------------------------------------------
  721. # Trim Function
  722. # - Trim whitespace from the beginning and end of a string
  723. # - Trims spaces, \r, \n, \t
  724. #
  725. # Usage:
  726. # Push " some string " ; String to Trim
  727. # Call Trim
  728. # Pop $0 ; Trimmed String: "some string"
  729. #
  730. # or
  731. #
  732. # ${Trim} $0 $1 ; Trimmed String, String to Trim
  733. #------------------------------------------------------------------------------
  734. Function Trim
  735. Exch $R1 # Original string
  736. Push $R2
  737. Loop:
  738. StrCpy $R2 "$R1" 1
  739. StrCmp "$R2" " " TrimLeft
  740. StrCmp "$R2" "$\r" TrimLeft
  741. StrCmp "$R2" "$\n" TrimLeft
  742. StrCmp "$R2" "$\t" TrimLeft
  743. GoTo Loop2
  744. TrimLeft:
  745. StrCpy $R1 "$R1" "" 1
  746. Goto Loop
  747. Loop2:
  748. StrCpy $R2 "$R1" 1 -1
  749. StrCmp "$R2" " " TrimRight
  750. StrCmp "$R2" "$\r" TrimRight
  751. StrCmp "$R2" "$\n" TrimRight
  752. StrCmp "$R2" "$\t" TrimRight
  753. GoTo Done
  754. TrimRight:
  755. StrCpy $R1 "$R1" -1
  756. Goto Loop2
  757. Done:
  758. Pop $R2
  759. Exch $R1
  760. FunctionEnd
  761. #------------------------------------------------------------------------------
  762. # Explode Function
  763. # - Splits a string based off the passed separator
  764. # - Each item in the string is pushed to the stack
  765. # - The last item pushed to the stack is the length of the array
  766. #
  767. # Usage:
  768. # Push "," ; Separator
  769. # Push "string,to,separate" ; String to explode
  770. # Call Explode
  771. # Pop $0 ; Number of items in the array
  772. #
  773. # or
  774. #
  775. # ${Explode} $0 $1 $2 ; Length, Separator, String
  776. #------------------------------------------------------------------------------
  777. Function Explode
  778. # Initialize variables
  779. Var /GLOBAL explString
  780. Var /GLOBAL explSeparator
  781. Var /GLOBAL explStrLen
  782. Var /GLOBAL explSepLen
  783. Var /GLOBAL explOffset
  784. Var /GLOBAL explTmp
  785. Var /GLOBAL explTmp2
  786. Var /GLOBAL explTmp3
  787. Var /GLOBAL explArrCount
  788. # Get input from user
  789. Pop $explString
  790. Pop $explSeparator
  791. # Calculates initial values
  792. StrLen $explStrLen $explString
  793. StrLen $explSepLen $explSeparator
  794. StrCpy $explArrCount 1
  795. ${If} $explStrLen <= 1 # If we got a single character
  796. ${OrIf} $explSepLen > $explStrLen # or separator is larger than the string,
  797. Push $explString # then we return initial string with no change
  798. Push 1 # and set array's length to 1
  799. Return
  800. ${EndIf}
  801. # Set offset to the last symbol of the string
  802. StrCpy $explOffset $explStrLen
  803. IntOp $explOffset $explOffset - 1
  804. # Clear temp string to exclude the possibility of appearance of occasional data
  805. StrCpy $explTmp ""
  806. StrCpy $explTmp2 ""
  807. StrCpy $explTmp3 ""
  808. # Loop until the offset becomes negative
  809. ${Do}
  810. # If offset becomes negative, it is time to leave the function
  811. ${IfThen} $explOffset == -1 ${|} ${ExitDo} ${|}
  812. # Remove everything before and after the searched part ("TempStr")
  813. StrCpy $explTmp $explString $explSepLen $explOffset
  814. ${If} $explTmp == $explSeparator
  815. # Calculating offset to start copy from
  816. IntOp $explTmp2 $explOffset + $explSepLen # Offset equals to the current offset plus length of separator
  817. StrCpy $explTmp3 $explString "" $explTmp2
  818. Push $explTmp3 # Throwing array item to the stack
  819. IntOp $explArrCount $explArrCount + 1 # Increasing array's counter
  820. StrCpy $explString $explString $explOffset 0 # Cutting all characters beginning with the separator entry
  821. StrLen $explStrLen $explString
  822. ${EndIf}
  823. ${If} $explOffset = 0 # If the beginning of the line met and there is no separator,
  824. # copying the rest of the string
  825. ${If} $explSeparator == "" # Fix for the empty separator
  826. IntOp $explArrCount $explArrCount - 1
  827. ${Else}
  828. Push $explString
  829. ${EndIf}
  830. ${EndIf}
  831. IntOp $explOffset $explOffset - 1
  832. ${Loop}
  833. Push $explArrCount
  834. FunctionEnd
  835. #------------------------------------------------------------------------------
  836. # StrStr Function
  837. # - find substring in a string
  838. #
  839. # Usage:
  840. # Push "this is some string"
  841. # Push "some"
  842. # Call StrStr
  843. # Pop $0 # "some string"
  844. #------------------------------------------------------------------------------
  845. !macro StrStr un
  846. Function ${un}StrStr
  847. Exch $R1 # $R1=substring, stack=[old$R1,string,...]
  848. Exch # stack=[string,old$R1,...]
  849. Exch $R2 # $R2=string, stack=[old$R2,old$R1,...]
  850. Push $R3 # $R3=strlen(substring)
  851. Push $R4 # $R4=count
  852. Push $R5 # $R5=tmp
  853. StrLen $R3 $R1 # Get the length of the Search String
  854. StrCpy $R4 0 # Set the counter to 0
  855. loop:
  856. StrCpy $R5 $R2 $R3 $R4 # Create a moving window of the string that is
  857. # the size of the length of the search string
  858. StrCmp $R5 $R1 done # Is the contents of the window the same as
  859. # search string, then done
  860. StrCmp $R5 "" done # Is the window empty, then done
  861. IntOp $R4 $R4 + 1 # Shift the windows one character
  862. Goto loop # Repeat
  863. done:
  864. StrCpy $R1 $R2 "" $R4
  865. Pop $R5
  866. Pop $R4
  867. Pop $R3
  868. Pop $R2
  869. Exch $R1 # $R1=old$R1, stack=[result,...]
  870. FunctionEnd
  871. !macroend
  872. !insertmacro StrStr ""
  873. !insertmacro StrStr "un."
  874. #------------------------------------------------------------------------------
  875. # AddToPath Function
  876. # - Adds item to Path for All Users
  877. # - Overcomes NSIS ReadRegStr limitation of 1024 characters by using Native
  878. # Windows Commands
  879. #
  880. # Usage:
  881. # Push "C:\path\to\add"
  882. # Call AddToPath
  883. #------------------------------------------------------------------------------
  884. !define Environ 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
  885. Function AddToPath
  886. Exch $0 # Path to add
  887. Push $1 # Current Path
  888. Push $2 # Results of StrStr / Length of Path + Path to Add
  889. Push $3 # Handle to Reg / Length of Path
  890. Push $4 # Result of Registry Call
  891. # Open a handle to the key in the registry, handle in $3, Error in $4
  892. System::Call "advapi32::RegOpenKey(i 0x80000002, t'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', *i.r3) i.r4"
  893. # Make sure registry handle opened successfully (returned 0)
  894. IntCmp $4 0 0 done done
  895. # Load the contents of path into $1, Error Code into $4, Path length into $2
  896. System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i ${NSIS_MAX_STRLEN} r2) i.r4"
  897. # Close the handle to the registry ($3)
  898. System::Call "advapi32::RegCloseKey(i $3)"
  899. # Check for Error Code 234, Path too long for the variable
  900. IntCmp $4 234 0 +4 +4 # $4 == ERROR_MORE_DATA
  901. DetailPrint "AddToPath Failed: original length $2 > ${NSIS_MAX_STRLEN}"
  902. MessageBox MB_OK \
  903. "You may add C:\salt to the %PATH% for convenience when issuing local salt commands from the command line." \
  904. /SD IDOK
  905. Goto done
  906. # If no error, continue
  907. IntCmp $4 0 +5 # $4 != NO_ERROR
  908. # Error 2 means the Key was not found
  909. IntCmp $4 2 +3 # $4 != ERROR_FILE_NOT_FOUND
  910. DetailPrint "AddToPath: unexpected error code $4"
  911. Goto done
  912. StrCpy $1 ""
  913. # Check if already in PATH
  914. Push "$1;" # The string to search
  915. Push "$0;" # The string to find
  916. Call StrStr
  917. Pop $2 # The result of the search
  918. StrCmp $2 "" 0 done # String not found, try again with ';' at the end
  919. # Otherwise, it's already in the path
  920. Push "$1;" # The string to search
  921. Push "$0\;" # The string to find
  922. Call StrStr
  923. Pop $2 # The result
  924. StrCmp $2 "" 0 done # String not found, continue (add)
  925. # Otherwise, it's already in the path
  926. # Prevent NSIS string overflow
  927. StrLen $2 $0 # Length of path to add ($2)
  928. StrLen $3 $1 # Length of current path ($3)
  929. IntOp $2 $2 + $3 # Length of current path + path to add ($2)
  930. IntOp $2 $2 + 2 # Account for the additional ';'
  931. # $2 = strlen(dir) + strlen(PATH) + sizeof(";")
  932. # Make sure the new length isn't over the NSIS_MAX_STRLEN
  933. IntCmp $2 ${NSIS_MAX_STRLEN} +4 +4 0
  934. DetailPrint "AddToPath Failed: new length $2 > ${NSIS_MAX_STRLEN}"
  935. MessageBox MB_OK \
  936. "You may add C:\salt to the %PATH% for convenience when issuing local salt commands from the command line." \
  937. /SD IDOK
  938. Goto done
  939. # Append dir to PATH
  940. DetailPrint "Add to PATH: $0"
  941. StrCpy $2 $1 1 -1 # Copy the last character of the existing path
  942. StrCmp $2 ";" 0 +2 # Check for trailing ';'
  943. StrCpy $1 $1 -1 # remove trailing ';'
  944. StrCmp $1 "" +2 # Make sure Path is not empty
  945. StrCpy $0 "$1;$0" # Append new path at the end ($0)
  946. # We can use the NSIS command here. Only 'ReadRegStr' is affected
  947. WriteRegExpandStr ${Environ} "PATH" $0
  948. # Broadcast registry change to open programs
  949. SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
  950. done:
  951. Pop $4
  952. Pop $3
  953. Pop $2
  954. Pop $1
  955. Pop $0
  956. FunctionEnd
  957. #------------------------------------------------------------------------------
  958. # RemoveFromPath Function
  959. # - Removes item from Path for All Users
  960. # - Overcomes NSIS ReadRegStr limitation of 1024 characters by using Native
  961. # Windows Commands
  962. #
  963. # Usage:
  964. # Push "C:\path\to\add"
  965. # Call un.RemoveFromPath
  966. #------------------------------------------------------------------------------
  967. Function un.RemoveFromPath
  968. Exch $0
  969. Push $1
  970. Push $2
  971. Push $3
  972. Push $4
  973. Push $5
  974. Push $6
  975. # Open a handle to the key in the registry, handle in $3, Error in $4
  976. System::Call "advapi32::RegOpenKey(i 0x80000002, t'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', *i.r3) i.r4"
  977. # Make sure registry handle opened successfully (returned 0)
  978. IntCmp $4 0 0 done done
  979. # Load the contents of path into $1, Error Code into $4, Path length into $2
  980. System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i ${NSIS_MAX_STRLEN} r2) i.r4"
  981. # Close the handle to the registry ($3)
  982. System::Call "advapi32::RegCloseKey(i $3)"
  983. # Check for Error Code 234, Path too long for the variable
  984. IntCmp $4 234 0 +4 +4 # $4 == ERROR_MORE_DATA
  985. DetailPrint "AddToPath: original length $2 > ${NSIS_MAX_STRLEN}"
  986. Goto done
  987. # If no error, continue
  988. IntCmp $4 0 +5 # $4 != NO_ERROR
  989. # Error 2 means the Key was not found
  990. IntCmp $4 2 +3 # $4 != ERROR_FILE_NOT_FOUND
  991. DetailPrint "AddToPath: unexpected error code $4"
  992. Goto done
  993. StrCpy $1 ""
  994. # Ensure there's a trailing ';'
  995. StrCpy $5 $1 1 -1 # Copy the last character of the path
  996. StrCmp $5 ";" +2 # Check for trailing ';', if found continue
  997. StrCpy $1 "$1;" # ensure trailing ';'
  998. # Check for our directory inside the path
  999. Push $1 # String to Search
  1000. Push "$0;" # Dir to Find
  1001. Call un.StrStr
  1002. Pop $2 # The results of the search
  1003. StrCmp $2 "" done # If results are empty, we're done, otherwise continue
  1004. # Remove our Directory from the Path
  1005. DetailPrint "Remove from PATH: $0"
  1006. StrLen $3 "$0;" # Get the length of our dir ($3)
  1007. StrLen $4 $2 # Get the length of the return from StrStr ($4)
  1008. StrCpy $5 $1 -$4 # $5 is now the part before the path to remove
  1009. StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove
  1010. StrCpy $3 "$5$6" # Combine $5 and $6
  1011. # Check for Trailing ';'
  1012. StrCpy $5 $3 1 -1 # Load the last character of the string
  1013. StrCmp $5 ";" 0 +2 # Check for ';'
  1014. StrCpy $3 $3 -1 # remove trailing ';'
  1015. # Write the new path to the registry
  1016. WriteRegExpandStr ${Environ} "PATH" $3
  1017. # Broadcast the change to all open applications
  1018. SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
  1019. done:
  1020. Pop $6
  1021. Pop $5
  1022. Pop $4
  1023. Pop $3
  1024. Pop $2
  1025. Pop $1
  1026. Pop $0
  1027. FunctionEnd
  1028. ###############################################################################
  1029. # Specialty Functions
  1030. ###############################################################################
  1031. Function getExistingMinionConfig
  1032. # Set Config Found Default Value
  1033. StrCpy $ExistingConfigFound 0
  1034. confFind:
  1035. IfFileExists "$INSTDIR\conf\minion" confFound confNotFound
  1036. confNotFound:
  1037. ${If} $INSTDIR == "c:\salt\bin\Scripts"
  1038. StrCpy $INSTDIR "C:\salt"
  1039. goto confFind
  1040. ${Else}
  1041. goto confReallyNotFound
  1042. ${EndIf}
  1043. confFound:
  1044. StrCpy $ExistingConfigFound 1
  1045. FileOpen $0 "$INSTDIR\conf\minion" r
  1046. confLoop:
  1047. ClearErrors # clear Errors
  1048. FileRead $0 $1 # read the next line
  1049. IfErrors EndOfFile # error is probably EOF
  1050. ${StrLoc} $2 $1 "master:" ">" # find `master:` starting at the beginning
  1051. ${If} $2 == 0 # if it found it in the first position, then it is defined
  1052. ${StrStrAdv} $2 $1 "master: " ">" ">" "0" "0" "0" # read everything after `master: `
  1053. ${Trim} $2 $2 # trim white space
  1054. ${If} $2 == "" # if it's empty, it's probably a list of masters
  1055. masterLoop:
  1056. ClearErrors # clear Errors
  1057. FileRead $0 $1 # read the next line
  1058. IfErrors EndOfFile # error is probably EOF
  1059. ${StrStrAdv} $2 $1 "- " ">" ">" "0" "0" "0" # read everything after `- `
  1060. ${Trim} $2 $2 # trim white space
  1061. ${IfNot} $2 == "" # if the line is not empty, we found something
  1062. ${If} $ConfigMasterHost == "" # if the config setting is empty
  1063. StrCpy $ConfigMasterHost $2 # make the first item the new entry
  1064. ${Else}
  1065. StrCpy $ConfigMasterHost "$ConfigMasterHost,$2" # Append the new master, comma separated
  1066. ${EndIf}
  1067. Goto masterLoop # check the next one
  1068. ${EndIf}
  1069. ${Else}
  1070. StrCpy $ConfigMasterHost $2 # a single master entry
  1071. ${EndIf}
  1072. ${EndIf}
  1073. ${StrLoc} $2 $1 "id:" ">"
  1074. ${If} $2 == 0
  1075. ${StrStrAdv} $2 $1 "id: " ">" ">" "0" "0" "0"
  1076. ${Trim} $2 $2
  1077. StrCpy $ConfigMinionName $2
  1078. ${EndIf}
  1079. Goto confLoop
  1080. EndOfFile:
  1081. FileClose $0
  1082. confReallyNotFound:
  1083. # Set Default Config Values if not found
  1084. ${If} $ConfigMasterHost == ""
  1085. StrCpy $ConfigMasterHost "salt"
  1086. ${EndIf}
  1087. ${If} $ConfigMinionName == ""
  1088. StrCpy $ConfigMinionName "hostname"
  1089. ${EndIf}
  1090. FunctionEnd
  1091. Var cfg_line
  1092. Var chk_line
  1093. Var lst_check
  1094. Function updateMinionConfig
  1095. ClearErrors
  1096. FileOpen $0 "$INSTDIR\conf\minion" "r" # open target file for reading
  1097. GetTempFileName $R0 # get new temp file name
  1098. FileOpen $1 $R0 "w" # open temp file for writing
  1099. StrCpy $ConfigWriteMaster 1 # write the master config value
  1100. StrCpy $ConfigWriteMinion 1 # write the minion config value
  1101. loop: # loop through each line
  1102. FileRead $0 $cfg_line # read line from target file
  1103. IfErrors done # end if errors are encountered (end of line)
  1104. loop_after_read:
  1105. StrCpy $lst_check 0 # list check not performed
  1106. ${If} $MasterHost_State == "" # if master is empty
  1107. ${OrIf} $MasterHost_State == "salt" # or if master is 'salt'
  1108. StrCpy $ConfigWriteMaster 0 # no need to write master config
  1109. ${EndIf} # close if statement
  1110. ${If} $MinionName_State == "" # if minion is empty
  1111. ${OrIf} $MinionName_State == "hostname" # and if minion is not 'hostname'
  1112. StrCpy $ConfigWriteMinion 0 # no need to write minion config
  1113. ${EndIf} # close if statement
  1114. ${If} $ConfigWriteMaster == 1 # if we need to write master config
  1115. ${StrLoc} $3 $cfg_line "master:" ">" # where is 'master:' in this line
  1116. ${If} $3 == 0 # is it in the first...
  1117. ${OrIf} $3 == 1 # or second position (account for comments)
  1118. ${Explode} $9 "," $MasterHost_state # Split the hostname on commas, $9 is the number of items found
  1119. ${If} $9 == 1 # 1 means only a single master was passed
  1120. StrCpy $cfg_line "master: $MasterHost_State$\r$\n" # write the master
  1121. ${Else} # make a multi-master entry
  1122. StrCpy $cfg_line "master:" # make the first line "master:"
  1123. loop_explode: # start a loop to go through the list in the config
  1124. pop $8 # pop the next item off the stack
  1125. ${Trim} $8 $8 # trim any whitespace
  1126. StrCpy $cfg_line "$cfg_line$\r$\n - $8" # add it to the master variable ($2)
  1127. IntOp $9 $9 - 1 # decrement the list count
  1128. ${If} $9 >= 1 # if it's not 0
  1129. Goto loop_explode # do it again
  1130. ${EndIf} # close if statement
  1131. StrCpy $cfg_line "$cfg_line$\r$\n" # Make sure there's a new line at the end
  1132. # Remove remaining items in list
  1133. ${While} $lst_check == 0 # while list item found
  1134. FileRead $0 $chk_line # read line from target file
  1135. IfErrors done # end if errors are encountered (end of line)
  1136. ${StrLoc} $3 $chk_line " - " ">" # where is 'master:' in this line
  1137. ${If} $3 == "" # is it in the first...
  1138. StrCpy $lst_check 1 # list check performed and finished
  1139. ${EndIf}
  1140. ${EndWhile}
  1141. ${EndIf} # close if statement
  1142. StrCpy $ConfigWriteMaster 0 # master value written to config
  1143. ${EndIf} # close if statement
  1144. ${EndIf} # close if statement
  1145. ${If} $ConfigWriteMinion == 1 # if we need to write minion config
  1146. ${StrLoc} $3 $cfg_line "id:" ">" # where is 'id:' in this line
  1147. ${If} $3 == 0 # is it in the first...
  1148. ${OrIf} $3 == 1 # or the second position (account for comments)
  1149. StrCpy $cfg_line "id: $MinionName_State$\r$\n" # write the minion config setting
  1150. StrCpy $ConfigWriteMinion 0 # minion value written to config
  1151. ${EndIf} # close if statement
  1152. ${EndIf} # close if statement
  1153. FileWrite $1 $cfg_line # write changed or unchanged line to temp file
  1154. ${If} $lst_check == 1 # master not written to the config
  1155. StrCpy $cfg_line $chk_line
  1156. Goto loop_after_read # A loop was performed, skip the next read
  1157. ${EndIf} # close if statement
  1158. Goto loop # check the next line in the config file
  1159. done:
  1160. ClearErrors
  1161. # Does master config still need to be written
  1162. ${If} $ConfigWriteMaster == 1 # master not written to the config
  1163. ${Explode} $9 "," $MasterHost_state # split the hostname on commas, $9 is the number of items found
  1164. ${If} $9 == 1 # 1 means only a single master was passed
  1165. StrCpy $cfg_line "master: $MasterHost_State" # write the master
  1166. ${Else} # make a multi-master entry
  1167. StrCpy $cfg_line "master:" # make the first line "master:"
  1168. loop_explode_2: # start a loop to go through the list in the config
  1169. pop $8 # pop the next item off the stack
  1170. ${Trim} $8 $8 # trim any whitespace
  1171. StrCpy $cfg_line "$cfg_line$\r$\n - $8" # add it to the master variable ($2)
  1172. IntOp $9 $9 - 1 # decrement the list count
  1173. ${If} $9 >= 1 # if it's not 0
  1174. Goto loop_explode_2 # do it again
  1175. ${EndIf} # close if statement
  1176. ${EndIf} # close if statement
  1177. FileWrite $1 $cfg_line # write changed or unchanged line to temp file
  1178. ${EndIf} # close if statement
  1179. ${If} $ConfigWriteMinion == 1 # minion ID not written to the config
  1180. StrCpy $cfg_line "$\r$\nid: $MinionName_State" # write the minion config setting
  1181. FileWrite $1 $cfg_line # write changed or unchanged line to temp file
  1182. ${EndIf} # close if statement
  1183. FileClose $0 # close target file
  1184. FileClose $1 # close temp file
  1185. Delete "$INSTDIR\conf\minion" # delete target file
  1186. CopyFiles /SILENT $R0 "$INSTDIR\conf\minion" # copy temp file to target file
  1187. Delete $R0 # delete temp file
  1188. FunctionEnd
  1189. Function parseCommandLineSwitches
  1190. # Load the parameters
  1191. ${GetParameters} $R0
  1192. # Display Help
  1193. ClearErrors
  1194. ${GetOptions} $R0 "/?" $R1
  1195. IfErrors display_help_not_found
  1196. System::Call 'kernel32::GetStdHandle(i -11)i.r0'
  1197. System::Call 'kernel32::AttachConsole(i -1)i.r1'
  1198. ${If} $0 = 0
  1199. ${OrIf} $1 = 0
  1200. System::Call 'kernel32::AllocConsole()'
  1201. System::Call 'kernel32::GetStdHandle(i -11)i.r0'
  1202. ${EndIf}
  1203. FileWrite $0 "$\n"
  1204. FileWrite $0 "$\n"
  1205. FileWrite $0 "Help for Salt Minion installation$\n"
  1206. FileWrite $0 "===============================================================================$\n"
  1207. FileWrite $0 "$\n"
  1208. FileWrite $0 "/minion-name=$\t$\tA string value to set the minion name. Default value is$\n"
  1209. FileWrite $0 "$\t$\t$\t'hostname'. Setting the minion name causes the installer$\n"
  1210. FileWrite $0 "$\t$\t$\tto use the default config or a custom config if defined$\n"
  1211. FileWrite $0 "$\n"
  1212. FileWrite $0 "/master=$\t$\tA string value to set the IP address or hostname of the$\n"
  1213. FileWrite $0 "$\t$\t$\tmaster. Default value is 'salt'. You may pass a single$\n"
  1214. FileWrite $0 "$\t$\t$\tmaster or a comma-separated list of masters. Setting$\n"
  1215. FileWrite $0 "$\t$\t$\tthe master will cause the installer to use the default$\n"
  1216. FileWrite $0 "$\t$\t$\tconfig or a custom config if defined$\n"
  1217. FileWrite $0 "$\n"
  1218. FileWrite $0 "/start-minion=$\t$\t1 will start the minion service, 0 will not.$\n"
  1219. FileWrite $0 "$\t$\t$\tDefault is 1$\n"
  1220. FileWrite $0 "$\n"
  1221. FileWrite $0 "/start-minion-delayed$\tSet the minion start type to 'Automatic (Delayed Start)'$\n"
  1222. FileWrite $0 "$\n"
  1223. FileWrite $0 "/default-config$\t$\tOverwrite the existing config if present with the$\n"
  1224. FileWrite $0 "$\t$\t$\tdefault config for salt. Default is to use the existing$\n"
  1225. FileWrite $0 "$\t$\t$\tconfig if present. If /master and/or /minion-name is$\n"
  1226. FileWrite $0 "$\t$\t$\tpassed, those values will be used to update the new$\n"
  1227. FileWrite $0 "$\t$\t$\tdefault config$\n"
  1228. FileWrite $0 "$\n"
  1229. FileWrite $0 "$\t$\t$\tAny existing config will be backed up by appending$\n"
  1230. FileWrite $0 "$\t$\t$\ta timestamp and a .bak extension. That includes\n"
  1231. FileWrite $0 "$\t$\t$\tthe minion file and the minion.d directory$\n"
  1232. FileWrite $0 "$\n"
  1233. FileWrite $0 "/custom-config=$\t$\tA string value specifying the name of a custom config$\n"
  1234. FileWrite $0 "$\t$\t$\tfile in the same path as the installer or the full path$\n"
  1235. FileWrite $0 "$\t$\t$\tto a custom config file. If /master and/or /minion-name$\n"
  1236. FileWrite $0 "$\t$\t$\tis passed, those values will be used to update the new$\n"
  1237. FileWrite $0 "$\t$\t$\tcustom config$\n"
  1238. FileWrite $0 "$\n"
  1239. FileWrite $0 "$\t$\t$\tAny existing config will be backed up by appending$\n"
  1240. FileWrite $0 "$\t$\t$\ta timestamp and a .bak extension. That includes\n"
  1241. FileWrite $0 "$\t$\t$\tthe minion file and the minion.d directory$\n"
  1242. FileWrite $0 "$\n"
  1243. FileWrite $0 "/S$\t$\t$\tInstall Salt silently$\n"
  1244. FileWrite $0 "$\n"
  1245. FileWrite $0 "/?$\t$\t$\tDisplay this help screen$\n"
  1246. FileWrite $0 "$\n"
  1247. FileWrite $0 "-------------------------------------------------------------------------------$\n"
  1248. FileWrite $0 "$\n"
  1249. FileWrite $0 "Examples:$\n"
  1250. FileWrite $0 "$\n"
  1251. FileWrite $0 "${OutFile} /S$\n"
  1252. FileWrite $0 "$\n"
  1253. FileWrite $0 "${OutFile} /S /minion-name=myminion /master=master.mydomain.com /start-minion-delayed$\n"
  1254. FileWrite $0 "$\n"
  1255. FileWrite $0 "===============================================================================$\n"
  1256. FileWrite $0 "$\n"
  1257. System::Free $0
  1258. System::Free $1
  1259. System::Call 'kernel32::FreeConsole()'
  1260. # Give the user back the prompt
  1261. !define VK_RETURN 0x0D ; Enter Key
  1262. !define KEYEVENTF_EXTENDEDKEY 0x0001
  1263. !define KEYEVENTF_KEYUP 0x0002
  1264. System::Call "user32::keybd_event(i${VK_RETURN}, i0x45, i${KEYEVENTF_EXTENDEDKEY}|0, i0)"
  1265. System::Call "user32::keybd_event(i${VK_RETURN}, i0x45, i${KEYEVENTF_EXTENDEDKEY}|${KEYEVENTF_KEYUP}, i0)"
  1266. Abort
  1267. display_help_not_found:
  1268. # Set default value for Use Existing Config
  1269. StrCpy $ConfigType_State "Existing Config"
  1270. # Check for start-minion switches
  1271. # /start-service is to be deprecated, so we must check for both
  1272. ${GetOptions} $R0 "/start-service=" $R1
  1273. ${GetOptions} $R0 "/start-minion=" $R2
  1274. # Service: Start Salt Minion
  1275. ${IfNot} $R2 == ""
  1276. # If start-minion was passed something, then set it
  1277. StrCpy $StartMinion $R2
  1278. ${ElseIfNot} $R1 == ""
  1279. # If start-service was passed something, then set StartMinion to that
  1280. StrCpy $StartMinion $R1
  1281. ${Else}
  1282. # Otherwise default to 1
  1283. StrCpy $StartMinion 1
  1284. ${EndIf}
  1285. # Service: Minion Startup Type Delayed
  1286. ClearErrors
  1287. ${GetOptions} $R0 "/start-minion-delayed" $R1
  1288. IfErrors start_minion_delayed_not_found
  1289. StrCpy $StartMinionDelayed 1
  1290. start_minion_delayed_not_found:
  1291. # Minion Config: Master IP/Name
  1292. # If setting master, we don't want to use existing config
  1293. ${GetOptions} $R0 "/master=" $R1
  1294. ${IfNot} $R1 == ""
  1295. StrCpy $MasterHost_State $R1
  1296. StrCpy $ConfigType_State "Default Config"
  1297. ${ElseIf} $MasterHost_State == ""
  1298. StrCpy $MasterHost_State "salt"
  1299. ${EndIf}
  1300. # Minion Config: Minion ID
  1301. # If setting minion id, we don't want to use existing config
  1302. ${GetOptions} $R0 "/minion-name=" $R1
  1303. ${IfNot} $R1 == ""
  1304. StrCpy $MinionName_State $R1
  1305. StrCpy $ConfigType_State "Default Config"
  1306. ${ElseIf} $MinionName_State == ""
  1307. StrCpy $MinionName_State "hostname"
  1308. ${EndIf}
  1309. # Use Default Config
  1310. ${GetOptions} $R0 "/default-config" $R1
  1311. IfErrors default_config_not_found
  1312. StrCpy $ConfigType_State "Default Config"
  1313. default_config_not_found:
  1314. # Use Custom Config
  1315. # Set default value for Use Custom Config
  1316. StrCpy $CustomConfig_State ""
  1317. # Existing config will get a `.bak` extension
  1318. ${GetOptions} $R0 "/custom-config=" $R1
  1319. ${IfNot} $R1 == ""
  1320. # Custom Config was passed something, set it
  1321. StrCpy $CustomConfig_State $R1
  1322. StrCpy $ConfigType_State "Custom Config"
  1323. ${EndIf}
  1324. FunctionEnd