123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392 |
- !define PRODUCT_NAME "Salt Minion"
- !define PRODUCT_NAME_OTHER "Salt"
- !define PRODUCT_PUBLISHER "SaltStack, Inc"
- !define PRODUCT_WEB_SITE "http://saltstack.org"
- !define PRODUCT_CALL_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\salt-call.exe"
- !define PRODUCT_CP_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\salt-cp.exe"
- !define PRODUCT_KEY_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\salt-key.exe"
- !define PRODUCT_MASTER_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\salt-master.exe"
- !define PRODUCT_MINION_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\salt-minion.exe"
- !define PRODUCT_RUN_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\salt-run.exe"
- !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
- !define PRODUCT_UNINST_KEY_OTHER "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME_OTHER}"
- !define PRODUCT_UNINST_ROOT_KEY "HKLM"
- !define OUTFILE "Salt-Minion-${PRODUCT_VERSION}-Py${PYTHON_VERSION}-${CPUARCH}-Setup.exe"
- # Import Libraries
- !include "MUI2.nsh"
- !include "nsDialogs.nsh"
- !include "LogicLib.nsh"
- !include "FileFunc.nsh"
- !include "StrFunc.nsh"
- !include "x64.nsh"
- !include "WinMessages.nsh"
- !include "WinVer.nsh"
- ${StrLoc}
- ${StrStrAdv}
- !ifdef SaltVersion
- !define PRODUCT_VERSION "${SaltVersion}"
- !else
- !define PRODUCT_VERSION "Undefined Version"
- !endif
- !ifdef PythonVersion
- !define PYTHON_VERSION "${PythonVersion}"
- !else
- !define PYTHON_VERSION "3"
- !endif
- !if "$%PROCESSOR_ARCHITECTURE%" == "AMD64"
- !define CPUARCH "AMD64"
- !else if "$%PROCESSOR_ARCHITEW6432%" == "AMD64"
- !define CPUARCH "AMD64"
- !else
- !define CPUARCH "x86"
- !endif
- # Part of the Trim function for Strings
- !define Trim "!insertmacro Trim"
- !macro Trim ResultVar String
- Push "${String}"
- Call Trim
- Pop "${ResultVar}"
- !macroend
- # Part of the Explode function for Strings
- !define Explode "!insertmacro Explode"
- !macro Explode Length Separator String
- Push `${Separator}`
- Push `${String}`
- Call Explode
- Pop `${Length}`
- !macroend
- ###############################################################################
- # Configure Pages, Ordering, and Configuration
- ###############################################################################
- !define MUI_ABORTWARNING
- !define MUI_ICON "salt.ico"
- !define MUI_UNICON "salt.ico"
- !define MUI_WELCOMEFINISHPAGE_BITMAP "panel.bmp"
- !define MUI_UNWELCOMEFINISHPAGE_BITMAP "panel.bmp"
- # Welcome page
- !insertmacro MUI_PAGE_WELCOME
- # License page
- !insertmacro MUI_PAGE_LICENSE "LICENSE.txt"
- # Configure Minion page
- Page custom pageMinionConfig pageMinionConfig_Leave
- # Instfiles page
- !insertmacro MUI_PAGE_INSTFILES
- # Finish page (Customized)
- !define MUI_PAGE_CUSTOMFUNCTION_SHOW pageFinish_Show
- !define MUI_PAGE_CUSTOMFUNCTION_LEAVE pageFinish_Leave
- !insertmacro MUI_PAGE_FINISH
- # Uninstaller pages
- !insertmacro MUI_UNPAGE_INSTFILES
- # Language files
- !insertmacro MUI_LANGUAGE "English"
- ###############################################################################
- # Custom Dialog Box Variables
- ###############################################################################
- Var Dialog
- Var Label
- Var CheckBox_Minion_Start
- Var CheckBox_Minion_Start_Delayed
- Var ConfigMasterHost
- Var MasterHost
- Var MasterHost_State
- Var ConfigMinionName
- Var MinionName
- Var MinionName_State
- Var ExistingConfigFound
- Var ConfigType
- Var ConfigType_State
- Var CustomConfig
- Var CustomConfig_btn
- Var CustomConfig_State
- Var WarningCustomConfig
- Var WarningExistingConfig
- Var WarningDefaultConfig
- Var StartMinion
- Var StartMinionDelayed
- Var DeleteInstallDir
- Var ConfigWriteMinion
- Var ConfigWriteMaster
- ###############################################################################
- # Minion Settings Dialog Box
- ###############################################################################
- Function pageMinionConfig
- # Set Page Title and Description
- !insertmacro MUI_HEADER_TEXT "Minion Settings" "Set the Minion Master and ID"
- nsDialogs::Create 1018
- Pop $Dialog
- ${If} $Dialog == error
- Abort
- ${EndIf}
- # Master IP or Hostname Dialog Control
- ${NSD_CreateLabel} 0 0 100% 12u "Master IP or Hostname:"
- Pop $Label
- ${NSD_CreateText} 0 13u 100% 12u $MasterHost_State
- Pop $MasterHost
- # Minion ID Dialog Control
- ${NSD_CreateLabel} 0 30u 100% 12u "Minion Name:"
- Pop $Label
- ${NSD_CreateText} 0 43u 100% 12u $MinionName_State
- Pop $MinionName
- # Config Drop List
- ${NSD_CreateDropList} 0 65u 25% 36u ""
- Pop $ConfigType
- ${NSD_CB_AddString} $ConfigType "Default Config"
- ${NSD_CB_AddString} $ConfigType "Custom Config"
- ${NSD_OnChange} $ConfigType pageMinionConfig_OnChange
- # Add Existing Config Warning Label
- ${NSD_CreateLabel} 0 80u 100% 60u "The values above are taken from an \
- existing configuration found in `c:\salt\conf\minion`. Configuration \
- settings defined in the `minion.d` directories, if they exist, are not \
- shown here.$\r$\n\
- $\r$\n\
- Clicking `Install` will leave the existing config unchanged."
- Pop $WarningExistingConfig
- CreateFont $0 "Arial" 10 500 /ITALIC
- SendMessage $WarningExistingConfig ${WM_SETFONT} $0 1
- SetCtlColors $WarningExistingConfig 0xBB0000 transparent
- # Add Default Config Warning Label
- ${NSD_CreateLabel} 0 80u 100% 60u "Clicking `Install` will backup the \
- the existing minion config file and minion.d directories. The values \
- above will be used in the new default config.$\r$\n\
- $\r$\n\
- NOTE: If Master IP is set to `salt` and Minion Name is set to \
- `hostname` no changes will be made."
- Pop $WarningDefaultConfig
- CreateFont $0 "Arial" 10 500 /ITALIC
- SendMessage $WarningDefaultConfig ${WM_SETFONT} $0 1
- SetCtlColors $WarningDefaultConfig 0xBB0000 transparent
- # Add Custom Config File Selector and Warning Label
- ${NSD_CreateText} 26% 65u 64% 12u $CustomConfig_State
- Pop $CustomConfig
- ${NSD_CreateButton} 91% 65u 9% 12u "..."
- Pop $CustomConfig_btn
- ${NSD_OnClick} $CustomConfig_btn pageCustomConfigBtn_OnClick
- ${If} $ExistingConfigFound == 0
- ${NSD_CreateLabel} 0 80u 100% 60u "Values entered above will be used \
- in the custom config.$\r$\n\
- $\r$\n\
- NOTE: If Master IP is set to `salt` and Minion Name is set to \
- `hostname` no changes will be made."
- ${Else}
- ${NSD_CreateLabel} 0 80u 100% 60u "Clicking `Install` will backup the \
- the existing minion config file and minion.d directories. The \
- values above will be used in the custom config.$\r$\n\
- $\r$\n\
- NOTE: If Master IP is set to `salt` and Minion Name is set to \
- `hostname` no changes will be made."
- ${Endif}
- Pop $WarningCustomConfig
- CreateFont $0 "Arial" 10 500 /ITALIC
- SendMessage $WarningCustomConfig ${WM_SETFONT} $0 1
- SetCtlColors $WarningCustomConfig 0xBB0000 transparent
- # If existing config found, add the Existing Config option to the Drop List
- # If not, hide the Default Warning
- ${If} $ExistingConfigFound == 1
- ${NSD_CB_AddString} $ConfigType "Existing Config"
- ${Else}
- ShowWindow $WarningDefaultConfig ${SW_HIDE}
- ${Endif}
- ${NSD_CB_SelectString} $ConfigType $ConfigType_State
- ${NSD_SetText} $CustomConfig $CustomConfig_State
- Call pageMinionConfig_OnChange
- nsDialogs::Show
- FunctionEnd
- Function pageMinionConfig_OnChange
- # You have to pop the top handle to keep the stack clean
- Pop $R0
- # Assign the current checkbox state to the variable
- ${NSD_GetText} $ConfigType $ConfigType_State
- # Update Dialog
- ${Switch} $ConfigType_State
- ${Case} "Existing Config"
- # Enable Master/Minion and set values
- EnableWindow $MasterHost 0
- EnableWindow $MinionName 0
- ${NSD_SetText} $MasterHost $ConfigMasterHost
- ${NSD_SetText} $MinionName $ConfigMinionName
- # Hide Custom File Picker
- ShowWindow $CustomConfig ${SW_HIDE}
- ShowWindow $CustomConfig_btn ${SW_HIDE}
- # Hide Warnings
- ShowWindow $WarningDefaultConfig ${SW_HIDE}
- ShowWindow $WarningCustomConfig ${SW_HIDE}
- # Show Existing Warning
- ShowWindow $WarningExistingConfig ${SW_SHOW}
- ${Break}
- ${Case} "Custom Config"
- # Enable Master/Minion and set values
- EnableWindow $MasterHost 1
- EnableWindow $MinionName 1
- ${NSD_SetText} $MasterHost $MasterHost_State
- ${NSD_SetText} $MinionName $MinionName_State
- # Show Custom File Picker
- ShowWindow $CustomConfig ${SW_SHOW}
- ShowWindow $CustomConfig_btn ${SW_SHOW}
- # Hide Warnings
- ShowWindow $WarningDefaultConfig ${SW_HIDE}
- ShowWindow $WarningExistingConfig ${SW_HIDE}
- # Show Custom Warning
- ShowWindow $WarningCustomConfig ${SW_SHOW}
- ${Break}
- ${Case} "Default Config"
- # Enable Master/Minion and set values
- EnableWindow $MasterHost 1
- EnableWindow $MinionName 1
- ${NSD_SetText} $MasterHost $MasterHost_State
- ${NSD_SetText} $MinionName $MinionName_State
- # Hide Custom File Picker
- ShowWindow $CustomConfig ${SW_HIDE}
- ShowWindow $CustomConfig_btn ${SW_HIDE}
- # Hide Warnings
- ShowWindow $WarningExistingConfig ${SW_HIDE}
- ShowWindow $WarningCustomConfig ${SW_HIDE}
- # Show Default Warning, if there is an existing config
- ${If} $ExistingConfigFound == 1
- ShowWindow $WarningDefaultConfig ${SW_SHOW}
- ${Endif}
- ${Break}
- ${EndSwitch}
- FunctionEnd
- # File Picker Definitions
- !define OFN_FILEMUSTEXIST 0x00001000
- !define OFN_DONTADDTOREC 0x02000000
- !define OPENFILENAME_SIZE_VERSION_400 76
- !define OPENFILENAME 'i,i,i,i,i,i,i,i,i,i,i,i,i,i,&i2,&i2,i,i,i,i'
- Function pageCustomConfigBtn_OnClick
- Pop $0
- System::Call '*(&t${NSIS_MAX_STRLEN})i.s' # Allocate OPENFILENAME.lpstrFile buffer
- System::Call '*(${OPENFILENAME})i.r0' # Allocate OPENFILENAME struct
- System::Call '*$0(${OPENFILENAME})(${OPENFILENAME_SIZE_VERSION_400}, \
- $hwndparent, , , , , , sr1, ${NSIS_MAX_STRLEN} , , , , \
- t"Select Custom Config File", \
- ${OFN_FILEMUSTEXIST} | ${OFN_DONTADDTOREC})'
- # Populate file name field
- ${NSD_GetText} $CustomConfig $2
- System::Call "*$1(&t${NSIS_MAX_STRLEN}r2)" ; Set lpstrFile to the old path (if any)
- # Open the dialog
- System::Call 'COMDLG32::GetOpenFileName(ir0)i.r2'
- # Get file name field
- ${If} $2 <> 0
- System::Call "*$1(&t${NSIS_MAX_STRLEN}.r2)"
- ${NSD_SetText} $CustomConfig $2
- ${EndIf}
- # Free resources
- System::Free $1
- System::Free $0
- FunctionEnd
- Function pageMinionConfig_Leave
- # Save the State
- ${NSD_GetText} $MasterHost $MasterHost_State
- ${NSD_GetText} $MinionName $MinionName_State
- ${NSD_GetText} $ConfigType $ConfigType_State
- ${NSD_GetText} $CustomConfig $CustomConfig_State
- # Abort if config file not found
- ${If} $ConfigType_State == "Custom Config"
- IfFileExists "$CustomConfig_State" continue 0
- MessageBox MB_OK "File not found: $CustomConfig_State" /SD IDOK
- Abort
- ${EndIf}
- continue:
- Call BackupExistingConfig
- FunctionEnd
- ###############################################################################
- # Custom Finish Page
- ###############################################################################
- Function pageFinish_Show
- # Imports so the checkboxes will show up
- !define SWP_NOSIZE 0x0001
- !define SWP_NOMOVE 0x0002
- !define HWND_TOP 0x0000
- # Create Start Minion Checkbox
- ${NSD_CreateCheckbox} 120u 90u 100% 12u "&Start salt-minion"
- Pop $CheckBox_Minion_Start
- SetCtlColors $CheckBox_Minion_Start "" "ffffff"
- # This command required to bring the checkbox to the front
- 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})"
- # Create Start Minion Delayed ComboBox
- ${NSD_CreateCheckbox} 130u 102u 100% 12u "&Delayed Start"
- Pop $CheckBox_Minion_Start_Delayed
- SetCtlColors $CheckBox_Minion_Start_Delayed "" "ffffff"
- # This command required to bring the checkbox to the front
- 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})"
- # Load current settings for Minion
- ${If} $StartMinion == 1
- ${NSD_Check} $CheckBox_Minion_Start
- ${EndIf}
- # Load current settings for Minion Delayed
- ${If} $StartMinionDelayed == 1
- ${NSD_Check} $CheckBox_Minion_Start_Delayed
- ${EndIf}
- FunctionEnd
- Function pageFinish_Leave
- # Assign the current checkbox states
- ${NSD_GetState} $CheckBox_Minion_Start $StartMinion
- ${NSD_GetState} $CheckBox_Minion_Start_Delayed $StartMinionDelayed
- FunctionEnd
- ###############################################################################
- # Installation Settings
- ###############################################################################
- Name "${PRODUCT_NAME} ${PRODUCT_VERSION} (Python ${PYTHON_VERSION})"
- OutFile "${OutFile}"
- InstallDir "c:\salt"
- InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
- ShowInstDetails show
- ShowUnInstDetails show
- Section -copy_prereqs
- # Copy prereqs to the Plugins Directory
- # These files are downloaded by build_pkg.bat
- # This directory gets removed upon completion
- SetOutPath "$PLUGINSDIR\"
- File /r "..\prereqs\"
- SectionEnd
- # Check if the Windows 10 Universal C Runtime (KB2999226) is installed
- # Python 3 needs the updated ucrt on Windows 8.1 / 2012R2 and lower
- # They are installed via KB2999226, but we're not going to patch the system here
- # Instead, we're going to copy the .dll files to the \salt\bin directory
- Section -install_ucrt
- Var /GLOBAL UcrtFileName
- # Get the Major.Minor version Number
- # Windows 10 introduced CurrentMajorVersionNumber
- ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" \
- CurrentMajorVersionNumber
- # Windows 10/2016 will return a value here, skip to the end if returned
- StrCmp $R0 '' lbl_needs_ucrt 0
- # Found Windows 10
- detailPrint "KB2999226 does not apply to this machine"
- goto lbl_done
- lbl_needs_ucrt:
- # UCRT only needed on Windows Server 2012R2/Windows 8.1 and below
- # The first ReadRegStr command above should have skipped to lbl_done if on
- # Windows 10 box
- # Is the update already installed
- ClearErrors
- # Use WMI to check if it's installed
- detailPrint "Checking for existing UCRT (KB2999226) installation"
- nsExec::ExecToStack 'cmd /q /c wmic qfe get hotfixid | findstr "^KB2999226"'
- # Clean up the stack
- Pop $R0 # Gets the ErrorCode
- Pop $R1 # Gets the stdout, which should be KB2999226 if it's installed
- # If it returned KB2999226 it's already installed
- StrCmp $R1 'KB2999226' lbl_done
- detailPrint "UCRT (KB2999226) not found"
- # Use RunningX64 here to get the Architecture for the system running the installer
- # CPUARCH is defined when the installer is built and is based on the machine that
- # built the installer, not the target system as we need here.
- ${If} ${RunningX64}
- StrCpy $UcrtFileName "ucrt_x64.zip"
- ${Else}
- StrCpy $UcrtFileName "ucrt_x86.zip"
- ${EndIf}
- ClearErrors
- detailPrint "Unzipping UCRT dll files to $INSTDIR\bin"
- CreateDirectory $INSTDIR\bin
- nsisunz::UnzipToLog "$PLUGINSDIR\$UcrtFileName" "$INSTDIR\bin"
- # Clean up the stack
- Pop $R0 # Get Error
- ${IfNot} $R0 == "success"
- detailPrint "error: $R0"
- Sleep 3000
- ${Else}
- detailPrint "UCRT dll files copied successfully"
- ${EndIf}
- lbl_done:
- SectionEnd
- # Check and install Visual C++ redist 2013 packages
- # Hidden section (-) to install VCRedist
- Section -install_vcredist_2013
- Var /GLOBAL VcRedistName
- Var /GLOBAL VcRedistGuid
- Var /GLOBAL NeedVcRedist
- # GUIDs can be found by installing them and then running the following command:
- # wmic product where "Name like '%2013%minimum runtime%'" get Name, Version, IdentifyingNumber
- !define VCREDIST_X86_NAME "vcredist_x86_2013"
- !define VCREDIST_X86_GUID "{8122DAB1-ED4D-3676-BB0A-CA368196543E}"
- !define VCREDIST_X64_NAME "vcredist_x64_2013"
- !define VCREDIST_X64_GUID "{53CF6934-A98D-3D84-9146-FC4EDF3D5641}"
- # Only install 64bit VCRedist on 64bit machines
- ${If} ${CPUARCH} == "AMD64"
- StrCpy $VcRedistName ${VCREDIST_X64_NAME}
- StrCpy $VcRedistGuid ${VCREDIST_X64_GUID}
- Call InstallVCRedist
- ${Else}
- # Install 32bit VCRedist on all machines
- StrCpy $VcRedistName ${VCREDIST_X86_NAME}
- StrCpy $VcRedistGuid ${VCREDIST_X86_GUID}
- Call InstallVCRedist
- ${EndIf}
- SectionEnd
- Function InstallVCRedist
- # Check to see if it's already installed
- Call MsiQueryProductState
- ${If} $NeedVcRedist == "True"
- detailPrint "System requires $VcRedistName"
- MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 \
- "$VcRedistName is currently not installed. Would you like to install?" \
- /SD IDYES IDNO endVCRedist
- # If an output variable is specified ($0 in the case below),
- # ExecWait sets the variable with the exit code (and only sets the
- # error flag if an error occurs; if an error occurs, the contents
- # of the user variable are undefined).
- # http://nsis.sourceforge.net/Reference/ExecWait
- ClearErrors
- detailPrint "Installing $VcRedistName..."
- ExecWait '"$PLUGINSDIR\$VcRedistName.exe" /install /quiet /norestart' $0
- IfErrors 0 CheckVcRedistErrorCode
- MessageBox MB_OK \
- "$VcRedistName failed to install. Try installing the package manually." \
- /SD IDOK
- detailPrint "An error occurred during installation of $VcRedistName"
- CheckVcRedistErrorCode:
- # Check for Reboot Error Code (3010)
- ${If} $0 == 3010
- MessageBox MB_OK \
- "$VcRedistName installed but requires a restart to complete." \
- /SD IDOK
- detailPrint "Reboot and run Salt install again"
- # Check for any other errors
- ${ElseIfNot} $0 == 0
- MessageBox MB_OK \
- "$VcRedistName failed with ErrorCode: $0. Try installing the package manually." \
- /SD IDOK
- detailPrint "An error occurred during installation of $VcRedistName"
- detailPrint "Error: $0"
- ${EndIf}
- endVCRedist:
- ${EndIf}
- FunctionEnd
- Section "MainSection" SEC01
- SetOutPath "$INSTDIR\"
- SetOverwrite off
- CreateDirectory $INSTDIR\conf\pki\minion
- CreateDirectory $INSTDIR\conf\minion.d
- File /r "..\buildenv\"
- 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'
- SectionEnd
- Function .onInit
- InitPluginsDir
- Call parseCommandLineSwitches
- # Uninstall msi-installed salt
- # Source https://nsis-dev.github.io/NSIS-Forums/html/t-303468.html
- !define upgradecode {FC6FB3A2-65DE-41A9-AD91-D10A402BD641} ;Salt upgrade code
- StrCpy $0 0
- loop:
- System::Call 'MSI::MsiEnumRelatedProducts(t "${upgradecode}",i0,i r0,t.r1)i.r2'
- ${If} $2 = 0
- # Now $1 contains the product code
- DetailPrint product:$1
- push $R0
- StrCpy $R0 $1
- Call UninstallMSI
- pop $R0
- IntOp $0 $0 + 1
- goto loop
- ${Endif}
- # If custom config passed, verify its existence before continuing so we
- # don't uninstall an existing installation and then fail
- ${If} $ConfigType_State == "Custom Config"
- IfFileExists "$CustomConfig_State" customConfigExists 0
- Abort
- ${EndIf}
- customConfigExists:
- # Check for existing installation
- ReadRegStr $R0 HKLM \
- "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" \
- "UninstallString"
- StrCmp $R0 "" checkOther
- # Found existing installation, prompt to uninstall
- MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
- "${PRODUCT_NAME} is already installed.$\n$\n\
- Click `OK` to remove the existing installation." \
- /SD IDOK IDOK uninst
- Abort
- checkOther:
- # Check for existing installation of full salt
- ReadRegStr $R0 HKLM \
- "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME_OTHER}" \
- "UninstallString"
- StrCmp $R0 "" skipUninstall
- # Found existing installation, prompt to uninstall
- MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
- "${PRODUCT_NAME_OTHER} is already installed.$\n$\n\
- Click `OK` to remove the existing installation." \
- /SD IDOK IDOK uninst
- Abort
- uninst:
- # Get current Silent status
- StrCpy $R0 0
- ${If} ${Silent}
- StrCpy $R0 1
- ${EndIf}
- # Turn on Silent mode
- SetSilent silent
- # Don't remove all directories
- StrCpy $DeleteInstallDir 0
- # Uninstall silently
- Call uninstallSalt
- # Set it back to Normal mode, if that's what it was before
- ${If} $R0 == 0
- SetSilent normal
- ${EndIf}
- skipUninstall:
- Call getExistingMinionConfig
- ${If} $ExistingConfigFound == 0
- ${AndIf} $ConfigType_State == "Existing Config"
- StrCpy $ConfigType_State "Default Config"
- ${EndIf}
- IfSilent 0 +2
- Call BackupExistingConfig
- FunctionEnd
- # Time Stamp Definition
- !define /date TIME_STAMP "%Y-%m-%d-%H-%M-%S"
- Function BackupExistingConfig
- ${If} $ExistingConfigFound == 1 # If existing config found
- ${AndIfNot} $ConfigType_State == "Existing Config" # If not using Existing Config
- # Backup the minion config
- Rename "$INSTDIR\conf\minion" "$INSTDIR\conf\minion-${TIME_STAMP}.bak"
- IfFileExists "$INSTDIR\conf\minion.d" 0 +2
- Rename "$INSTDIR\conf\minion.d" "$INSTDIR\conf\minion.d-${TIME_STAMP}.bak"
- ${EndIf}
- # By this point there should be no existing config
- # It was either backed up or wasn't there to begin with
- ${If} $ConfigType_State == "Custom Config" # If we're using Custom Config
- ${AndIfNot} $CustomConfig_State == "" # If a custom config is passed
- # Check for a file name
- # Named file should be in the same directory as the installer
- CreateDirectory "$INSTDIR\conf"
- IfFileExists "$EXEDIR\$CustomConfig_State" 0 checkFullPath
- CopyFiles /SILENT /FILESONLY "$EXEDIR\$CustomConfig_State" "$INSTDIR\conf\minion"
- goto finished
- # Maybe it was a full path to a file
- checkFullPath:
- IfFileExists "$CustomConfig_State" 0 finished
- CopyFiles /SILENT /FILESONLY "$CustomConfig_State" "$INSTDIR\conf\minion"
- finished:
- ${EndIf}
- FunctionEnd
- Section -Post
- WriteUninstaller "$INSTDIR\uninst.exe"
- # Uninstall Registry Entries
- WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
- "DisplayName" "$(^Name)"
- WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
- "UninstallString" "$INSTDIR\uninst.exe"
- WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
- "DisplayIcon" "$INSTDIR\salt.ico"
- WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
- "DisplayVersion" "${PRODUCT_VERSION}"
- WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
- "URLInfoAbout" "${PRODUCT_WEB_SITE}"
- WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
- "Publisher" "${PRODUCT_PUBLISHER}"
- WriteRegStr HKLM "SYSTEM\CurrentControlSet\services\salt-minion" \
- "DependOnService" "nsi"
- # Set the estimated size
- ${GetSize} "$INSTDIR\bin" "/S=OK" $0 $1 $2
- IntFmt $0 "0x%08X" $0
- WriteRegDWORD ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" \
- "EstimatedSize" "$0"
- # Commandline Registry Entries
- WriteRegStr HKLM "${PRODUCT_CALL_REGKEY}" "" "$INSTDIR\salt-call.bat"
- WriteRegStr HKLM "${PRODUCT_CALL_REGKEY}" "Path" "$INSTDIR\bin\"
- WriteRegStr HKLM "${PRODUCT_MINION_REGKEY}" "" "$INSTDIR\salt-minion.bat"
- WriteRegStr HKLM "${PRODUCT_MINION_REGKEY}" "Path" "$INSTDIR\bin\"
- # Register the Salt-Minion Service
- 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"
- nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion Description Salt Minion from saltstack.com"
- nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion Start SERVICE_AUTO_START"
- nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion AppStopMethodConsole 24000"
- nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion AppStopMethodWindow 2000"
- nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion AppRestartDelay 60000"
- ${IfNot} $ConfigType_State == "Existing Config" # If not using Existing Config
- Call updateMinionConfig
- ${EndIf}
- # Add $INSTDIR in the Path
- EnVar::SetHKLM
- EnVar::AddValue Path "$INSTDIR"
- SectionEnd
- Function .onInstSuccess
- # If StartMinionDelayed is 1, then set the service to start delayed
- ${If} $StartMinionDelayed == 1
- nsExec::Exec "$INSTDIR\bin\ssm.exe set salt-minion Start SERVICE_DELAYED_AUTO_START"
- ${EndIf}
- # If start-minion is 1, then start the service
- ${If} $StartMinion == 1
- nsExec::Exec 'net start salt-minion'
- ${EndIf}
- FunctionEnd
- Function un.onInit
- # Load the parameters
- ${GetParameters} $R0
- # Uninstaller: Remove Installation Directory
- ClearErrors
- ${GetOptions} $R0 "/delete-install-dir" $R1
- IfErrors delete_install_dir_not_found
- StrCpy $DeleteInstallDir 1
- delete_install_dir_not_found:
- MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 \
- "Are you sure you want to completely remove $(^Name) and all of its components?" \
- /SD IDYES IDYES +2
- Abort
- FunctionEnd
- Section Uninstall
- Call un.uninstallSalt
- # Remove $INSTDIR from the Path
- EnVar::SetHKLM
- EnVar::DeleteValue Path "$INSTDIR"
- SectionEnd
- !macro uninstallSalt un
- Function ${un}uninstallSalt
- # Make sure we're in the right directory
- ${If} $INSTDIR == "c:\salt\bin\Scripts"
- StrCpy $INSTDIR "C:\salt"
- ${EndIf}
- # Stop and Remove salt-minion service
- nsExec::Exec 'net stop salt-minion'
- nsExec::Exec 'sc delete salt-minion'
- # Stop and remove the salt-master service
- nsExec::Exec 'net stop salt-master'
- nsExec::Exec 'sc delete salt-master'
- # Remove files
- Delete "$INSTDIR\uninst.exe"
- Delete "$INSTDIR\ssm.exe"
- Delete "$INSTDIR\salt*"
- Delete "$INSTDIR\vcredist.exe"
- RMDir /r "$INSTDIR\bin"
- # Remove Registry entries
- DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
- DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY_OTHER}"
- DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_CALL_REGKEY}"
- DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_CP_REGKEY}"
- DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_KEY_REGKEY}"
- DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_MASTER_REGKEY}"
- DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_MINION_REGKEY}"
- DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_RUN_REGKEY}"
- # Automatically close when finished
- SetAutoClose true
- # Prompt to remove the Installation directory
- ${IfNot} $DeleteInstallDir == 1
- MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 \
- "Would you like to completely remove $INSTDIR and all of its contents?" \
- /SD IDNO IDNO finished
- ${EndIf}
- # Make sure you're not removing Program Files
- ${If} $INSTDIR != 'Program Files'
- ${AndIf} $INSTDIR != 'Program Files (x86)'
- RMDir /r "$INSTDIR"
- ${EndIf}
- finished:
- FunctionEnd
- !macroend
- !insertmacro uninstallSalt ""
- !insertmacro uninstallSalt "un."
- Function un.onUninstSuccess
- HideWindow
- MessageBox MB_ICONINFORMATION|MB_OK \
- "$(^Name) was successfully removed from your computer." \
- /SD IDOK
- FunctionEnd
- ###############################################################################
- # Helper Functions
- ###############################################################################
- Function MsiQueryProductState
- # Used for detecting VCRedist Installation
- !define INSTALLSTATE_DEFAULT "5"
- StrCpy $NeedVcRedist "False"
- System::Call "msi::MsiQueryProductStateA(t '$VcRedistGuid') i.r0"
- StrCmp $0 ${INSTALLSTATE_DEFAULT} +2 0
- StrCpy $NeedVcRedist "True"
- FunctionEnd
- #------------------------------------------------------------------------------
- # Trim Function
- # - Trim whitespace from the beginning and end of a string
- # - Trims spaces, \r, \n, \t
- #
- # Usage:
- # Push " some string " ; String to Trim
- # Call Trim
- # Pop $0 ; Trimmed String: "some string"
- #
- # or
- #
- # ${Trim} $0 $1 ; Trimmed String, String to Trim
- #------------------------------------------------------------------------------
- Function Trim
- Exch $R1 # Original string
- Push $R2
- Loop:
- StrCpy $R2 "$R1" 1
- StrCmp "$R2" " " TrimLeft
- StrCmp "$R2" "$\r" TrimLeft
- StrCmp "$R2" "$\n" TrimLeft
- StrCmp "$R2" "$\t" TrimLeft
- GoTo Loop2
- TrimLeft:
- StrCpy $R1 "$R1" "" 1
- Goto Loop
- Loop2:
- StrCpy $R2 "$R1" 1 -1
- StrCmp "$R2" " " TrimRight
- StrCmp "$R2" "$\r" TrimRight
- StrCmp "$R2" "$\n" TrimRight
- StrCmp "$R2" "$\t" TrimRight
- GoTo Done
- TrimRight:
- StrCpy $R1 "$R1" -1
- Goto Loop2
- Done:
- Pop $R2
- Exch $R1
- FunctionEnd
- #------------------------------------------------------------------------------
- # Explode Function
- # - Splits a string based off the passed separator
- # - Each item in the string is pushed to the stack
- # - The last item pushed to the stack is the length of the array
- #
- # Usage:
- # Push "," ; Separator
- # Push "string,to,separate" ; String to explode
- # Call Explode
- # Pop $0 ; Number of items in the array
- #
- # or
- #
- # ${Explode} $0 $1 $2 ; Length, Separator, String
- #------------------------------------------------------------------------------
- Function Explode
- # Initialize variables
- Var /GLOBAL explString
- Var /GLOBAL explSeparator
- Var /GLOBAL explStrLen
- Var /GLOBAL explSepLen
- Var /GLOBAL explOffset
- Var /GLOBAL explTmp
- Var /GLOBAL explTmp2
- Var /GLOBAL explTmp3
- Var /GLOBAL explArrCount
- # Get input from user
- Pop $explString
- Pop $explSeparator
- # Calculates initial values
- StrLen $explStrLen $explString
- StrLen $explSepLen $explSeparator
- StrCpy $explArrCount 1
- ${If} $explStrLen <= 1 # If we got a single character
- ${OrIf} $explSepLen > $explStrLen # or separator is larger than the string,
- Push $explString # then we return initial string with no change
- Push 1 # and set array's length to 1
- Return
- ${EndIf}
- # Set offset to the last symbol of the string
- StrCpy $explOffset $explStrLen
- IntOp $explOffset $explOffset - 1
- # Clear temp string to exclude the possibility of appearance of occasional data
- StrCpy $explTmp ""
- StrCpy $explTmp2 ""
- StrCpy $explTmp3 ""
- # Loop until the offset becomes negative
- ${Do}
- # If offset becomes negative, it is time to leave the function
- ${IfThen} $explOffset == -1 ${|} ${ExitDo} ${|}
- # Remove everything before and after the searched part ("TempStr")
- StrCpy $explTmp $explString $explSepLen $explOffset
- ${If} $explTmp == $explSeparator
- # Calculating offset to start copy from
- IntOp $explTmp2 $explOffset + $explSepLen # Offset equals to the current offset plus length of separator
- StrCpy $explTmp3 $explString "" $explTmp2
- Push $explTmp3 # Throwing array item to the stack
- IntOp $explArrCount $explArrCount + 1 # Increasing array's counter
- StrCpy $explString $explString $explOffset 0 # Cutting all characters beginning with the separator entry
- StrLen $explStrLen $explString
- ${EndIf}
- ${If} $explOffset = 0 # If the beginning of the line met and there is no separator,
- # copying the rest of the string
- ${If} $explSeparator == "" # Fix for the empty separator
- IntOp $explArrCount $explArrCount - 1
- ${Else}
- Push $explString
- ${EndIf}
- ${EndIf}
- IntOp $explOffset $explOffset - 1
- ${Loop}
- Push $explArrCount
- FunctionEnd
- #------------------------------------------------------------------------------
- # UninstallMSI Function
- # - Uninstalls MSI by product code
- #
- # Usage:
- # Push product code
- # Call UninstallMSI
- #
- # Source:
- # https://nsis.sourceforge.io/Uninstalling_a_previous_MSI_(Windows_installer_package)
- #------------------------------------------------------------------------------
- Function UninstallMSI
- ; $R0 === product code
- MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION \
- "${PRODUCT_NAME} is already installed via MSI.$\n$\n\
- Click `OK` to remove the existing installation." \
- /SD IDOK IDOK UninstallMSI
- Abort
- UninstallMSI:
- ExecWait '"msiexec.exe" /x $R0 /qb /quiet /norestart'
- FunctionEnd
- ###############################################################################
- # Specialty Functions
- ###############################################################################
- Function getExistingMinionConfig
- # Set Config Found Default Value
- StrCpy $ExistingConfigFound 0
- confFind:
- IfFileExists "$INSTDIR\conf\minion" confFound confNotFound
- confNotFound:
- ${If} $INSTDIR == "c:\salt\bin\Scripts"
- StrCpy $INSTDIR "C:\salt"
- goto confFind
- ${Else}
- goto confReallyNotFound
- ${EndIf}
- confFound:
- StrCpy $ExistingConfigFound 1
- FileOpen $0 "$INSTDIR\conf\minion" r
- confLoop:
- ClearErrors # clear Errors
- FileRead $0 $1 # read the next line
- IfErrors EndOfFile # error is probably EOF
- ${StrLoc} $2 $1 "master:" ">" # find `master:` starting at the beginning
- ${If} $2 == 0 # if it found it in the first position, then it is defined
- ${StrStrAdv} $2 $1 "master: " ">" ">" "0" "0" "0" # read everything after `master: `
- ${Trim} $2 $2 # trim white space
- ${If} $2 == "" # if it's empty, it's probably a list of masters
- masterLoop:
- ClearErrors # clear Errors
- FileRead $0 $1 # read the next line
- IfErrors EndOfFile # error is probably EOF
- ${StrStrAdv} $2 $1 "- " ">" ">" "0" "0" "0" # read everything after `- `
- ${Trim} $2 $2 # trim white space
- ${IfNot} $2 == "" # if the line is not empty, we found something
- ${If} $ConfigMasterHost == "" # if the config setting is empty
- StrCpy $ConfigMasterHost $2 # make the first item the new entry
- ${Else}
- StrCpy $ConfigMasterHost "$ConfigMasterHost,$2" # Append the new master, comma separated
- ${EndIf}
- Goto masterLoop # check the next one
- ${EndIf}
- ${Else}
- StrCpy $ConfigMasterHost $2 # a single master entry
- ${EndIf}
- ${EndIf}
- ${StrLoc} $2 $1 "id:" ">"
- ${If} $2 == 0
- ${StrStrAdv} $2 $1 "id: " ">" ">" "0" "0" "0"
- ${Trim} $2 $2
- StrCpy $ConfigMinionName $2
- ${EndIf}
- Goto confLoop
- EndOfFile:
- FileClose $0
- confReallyNotFound:
- # Set Default Config Values if not found
- ${If} $ConfigMasterHost == ""
- StrCpy $ConfigMasterHost "salt"
- ${EndIf}
- ${If} $ConfigMinionName == ""
- StrCpy $ConfigMinionName "hostname"
- ${EndIf}
- FunctionEnd
- Var cfg_line
- Var chk_line
- Var lst_check
- Function updateMinionConfig
- ClearErrors
- FileOpen $0 "$INSTDIR\conf\minion" "r" # open target file for reading
- GetTempFileName $R0 # get new temp file name
- FileOpen $1 $R0 "w" # open temp file for writing
- StrCpy $ConfigWriteMaster 1 # write the master config value
- StrCpy $ConfigWriteMinion 1 # write the minion config value
- loop: # loop through each line
- FileRead $0 $cfg_line # read line from target file
- IfErrors done # end if errors are encountered (end of line)
- loop_after_read:
- StrCpy $lst_check 0 # list check not performed
- ${If} $MasterHost_State == "" # if master is empty
- ${OrIf} $MasterHost_State == "salt" # or if master is 'salt'
- StrCpy $ConfigWriteMaster 0 # no need to write master config
- ${EndIf} # close if statement
- ${If} $MinionName_State == "" # if minion is empty
- ${OrIf} $MinionName_State == "hostname" # and if minion is not 'hostname'
- StrCpy $ConfigWriteMinion 0 # no need to write minion config
- ${EndIf} # close if statement
- ${If} $ConfigWriteMaster == 1 # if we need to write master config
- ${StrLoc} $3 $cfg_line "master:" ">" # where is 'master:' in this line
- ${If} $3 == 0 # is it in the first...
- ${OrIf} $3 == 1 # or second position (account for comments)
- ${Explode} $9 "," $MasterHost_state # Split the hostname on commas, $9 is the number of items found
- ${If} $9 == 1 # 1 means only a single master was passed
- StrCpy $cfg_line "master: $MasterHost_State$\r$\n" # write the master
- ${Else} # make a multi-master entry
- StrCpy $cfg_line "master:" # make the first line "master:"
- loop_explode: # start a loop to go through the list in the config
- pop $8 # pop the next item off the stack
- ${Trim} $8 $8 # trim any whitespace
- StrCpy $cfg_line "$cfg_line$\r$\n - $8" # add it to the master variable ($2)
- IntOp $9 $9 - 1 # decrement the list count
- ${If} $9 >= 1 # if it's not 0
- Goto loop_explode # do it again
- ${EndIf} # close if statement
- StrCpy $cfg_line "$cfg_line$\r$\n" # Make sure there's a new line at the end
- # Remove remaining items in list
- ${While} $lst_check == 0 # while list item found
- FileRead $0 $chk_line # read line from target file
- IfErrors done # end if errors are encountered (end of line)
- ${StrLoc} $3 $chk_line " - " ">" # where is 'master:' in this line
- ${If} $3 == "" # is it in the first...
- StrCpy $lst_check 1 # list check performed and finished
- ${EndIf}
- ${EndWhile}
- ${EndIf} # close if statement
- StrCpy $ConfigWriteMaster 0 # master value written to config
- ${EndIf} # close if statement
- ${EndIf} # close if statement
- ${If} $ConfigWriteMinion == 1 # if we need to write minion config
- ${StrLoc} $3 $cfg_line "id:" ">" # where is 'id:' in this line
- ${If} $3 == 0 # is it in the first...
- ${OrIf} $3 == 1 # or the second position (account for comments)
- StrCpy $cfg_line "id: $MinionName_State$\r$\n" # write the minion config setting
- StrCpy $ConfigWriteMinion 0 # minion value written to config
- ${EndIf} # close if statement
- ${EndIf} # close if statement
- FileWrite $1 $cfg_line # write changed or unchanged line to temp file
- ${If} $lst_check == 1 # master not written to the config
- StrCpy $cfg_line $chk_line
- Goto loop_after_read # A loop was performed, skip the next read
- ${EndIf} # close if statement
- Goto loop # check the next line in the config file
- done:
- ClearErrors
- # Does master config still need to be written
- ${If} $ConfigWriteMaster == 1 # master not written to the config
- ${Explode} $9 "," $MasterHost_state # split the hostname on commas, $9 is the number of items found
- ${If} $9 == 1 # 1 means only a single master was passed
- StrCpy $cfg_line "master: $MasterHost_State" # write the master
- ${Else} # make a multi-master entry
- StrCpy $cfg_line "master:" # make the first line "master:"
- loop_explode_2: # start a loop to go through the list in the config
- pop $8 # pop the next item off the stack
- ${Trim} $8 $8 # trim any whitespace
- StrCpy $cfg_line "$cfg_line$\r$\n - $8" # add it to the master variable ($2)
- IntOp $9 $9 - 1 # decrement the list count
- ${If} $9 >= 1 # if it's not 0
- Goto loop_explode_2 # do it again
- ${EndIf} # close if statement
- ${EndIf} # close if statement
- FileWrite $1 $cfg_line # write changed or unchanged line to temp file
- ${EndIf} # close if statement
- ${If} $ConfigWriteMinion == 1 # minion ID not written to the config
- StrCpy $cfg_line "$\r$\nid: $MinionName_State" # write the minion config setting
- FileWrite $1 $cfg_line # write changed or unchanged line to temp file
- ${EndIf} # close if statement
- FileClose $0 # close target file
- FileClose $1 # close temp file
- Delete "$INSTDIR\conf\minion" # delete target file
- CopyFiles /SILENT $R0 "$INSTDIR\conf\minion" # copy temp file to target file
- Delete $R0 # delete temp file
- FunctionEnd
- Function parseCommandLineSwitches
- # Load the parameters
- ${GetParameters} $R0
- # Display Help
- ClearErrors
- ${GetOptions} $R0 "/?" $R1
- IfErrors display_help_not_found
- System::Call 'kernel32::GetStdHandle(i -11)i.r0'
- System::Call 'kernel32::AttachConsole(i -1)i.r1'
- ${If} $0 = 0
- ${OrIf} $1 = 0
- System::Call 'kernel32::AllocConsole()'
- System::Call 'kernel32::GetStdHandle(i -11)i.r0'
- ${EndIf}
- FileWrite $0 "$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "Help for Salt Minion installation$\n"
- FileWrite $0 "===============================================================================$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "/minion-name=$\t$\tA string value to set the minion name. Default value is$\n"
- FileWrite $0 "$\t$\t$\t'hostname'. Setting the minion name causes the installer$\n"
- FileWrite $0 "$\t$\t$\tto use the default config or a custom config if defined$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "/master=$\t$\tA string value to set the IP address or hostname of the$\n"
- FileWrite $0 "$\t$\t$\tmaster. Default value is 'salt'. You may pass a single$\n"
- FileWrite $0 "$\t$\t$\tmaster or a comma-separated list of masters. Setting$\n"
- FileWrite $0 "$\t$\t$\tthe master will cause the installer to use the default$\n"
- FileWrite $0 "$\t$\t$\tconfig or a custom config if defined$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "/start-minion=$\t$\t1 will start the minion service, 0 will not.$\n"
- FileWrite $0 "$\t$\t$\tDefault is 1$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "/start-minion-delayed$\tSet the minion start type to 'Automatic (Delayed Start)'$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "/default-config$\t$\tOverwrite the existing config if present with the$\n"
- FileWrite $0 "$\t$\t$\tdefault config for salt. Default is to use the existing$\n"
- FileWrite $0 "$\t$\t$\tconfig if present. If /master and/or /minion-name is$\n"
- FileWrite $0 "$\t$\t$\tpassed, those values will be used to update the new$\n"
- FileWrite $0 "$\t$\t$\tdefault config$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "$\t$\t$\tAny existing config will be backed up by appending$\n"
- FileWrite $0 "$\t$\t$\ta timestamp and a .bak extension. That includes\n"
- FileWrite $0 "$\t$\t$\tthe minion file and the minion.d directory$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "/custom-config=$\t$\tA string value specifying the name of a custom config$\n"
- FileWrite $0 "$\t$\t$\tfile in the same path as the installer or the full path$\n"
- FileWrite $0 "$\t$\t$\tto a custom config file. If /master and/or /minion-name$\n"
- FileWrite $0 "$\t$\t$\tis passed, those values will be used to update the new$\n"
- FileWrite $0 "$\t$\t$\tcustom config$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "$\t$\t$\tAny existing config will be backed up by appending$\n"
- FileWrite $0 "$\t$\t$\ta timestamp and a .bak extension. That includes\n"
- FileWrite $0 "$\t$\t$\tthe minion file and the minion.d directory$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "/S$\t$\t$\tInstall Salt silently$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "/?$\t$\t$\tDisplay this help screen$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "-------------------------------------------------------------------------------$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "Examples:$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "${OutFile} /S$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "${OutFile} /S /minion-name=myminion /master=master.mydomain.com /start-minion-delayed$\n"
- FileWrite $0 "$\n"
- FileWrite $0 "===============================================================================$\n"
- FileWrite $0 "$\n"
- System::Free $0
- System::Free $1
- System::Call 'kernel32::FreeConsole()'
- # Give the user back the prompt
- !define VK_RETURN 0x0D ; Enter Key
- !define KEYEVENTF_EXTENDEDKEY 0x0001
- !define KEYEVENTF_KEYUP 0x0002
- System::Call "user32::keybd_event(i${VK_RETURN}, i0x45, i${KEYEVENTF_EXTENDEDKEY}|0, i0)"
- System::Call "user32::keybd_event(i${VK_RETURN}, i0x45, i${KEYEVENTF_EXTENDEDKEY}|${KEYEVENTF_KEYUP}, i0)"
- Abort
- display_help_not_found:
- # Set default value for Use Existing Config
- StrCpy $ConfigType_State "Existing Config"
- # Check for start-minion switches
- # /start-service is to be deprecated, so we must check for both
- ${GetOptions} $R0 "/start-service=" $R1
- ${GetOptions} $R0 "/start-minion=" $R2
- # Service: Start Salt Minion
- ${IfNot} $R2 == ""
- # If start-minion was passed something, then set it
- StrCpy $StartMinion $R2
- ${ElseIfNot} $R1 == ""
- # If start-service was passed something, then set StartMinion to that
- StrCpy $StartMinion $R1
- ${Else}
- # Otherwise default to 1
- StrCpy $StartMinion 1
- ${EndIf}
- # Service: Minion Startup Type Delayed
- ClearErrors
- ${GetOptions} $R0 "/start-minion-delayed" $R1
- IfErrors start_minion_delayed_not_found
- StrCpy $StartMinionDelayed 1
- start_minion_delayed_not_found:
- # Minion Config: Master IP/Name
- # If setting master, we don't want to use existing config
- ${GetOptions} $R0 "/master=" $R1
- ${IfNot} $R1 == ""
- StrCpy $MasterHost_State $R1
- StrCpy $ConfigType_State "Default Config"
- ${ElseIf} $MasterHost_State == ""
- StrCpy $MasterHost_State "salt"
- ${EndIf}
- # Minion Config: Minion ID
- # If setting minion id, we don't want to use existing config
- ${GetOptions} $R0 "/minion-name=" $R1
- ${IfNot} $R1 == ""
- StrCpy $MinionName_State $R1
- StrCpy $ConfigType_State "Default Config"
- ${ElseIf} $MinionName_State == ""
- StrCpy $MinionName_State "hostname"
- ${EndIf}
- # Use Default Config
- ${GetOptions} $R0 "/default-config" $R1
- IfErrors default_config_not_found
- StrCpy $ConfigType_State "Default Config"
- default_config_not_found:
- # Use Custom Config
- # Set default value for Use Custom Config
- StrCpy $CustomConfig_State ""
- # Existing config will get a `.bak` extension
- ${GetOptions} $R0 "/custom-config=" $R1
- ${IfNot} $R1 == ""
- # Custom Config was passed something, set it
- StrCpy $CustomConfig_State $R1
- StrCpy $ConfigType_State "Custom Config"
- ${EndIf}
- FunctionEnd
|