How to set conditional variables in capistrano's deploy.rb - capistrano

Snippet from deploy.rb
task :prod1 do
set :deploy_to, "/home/project/src/prod1"
end
task :prod2 do
set :deploy_to, "/home/project/src/prod2"
end
I have 2 tasks like the above. Now instead of manually running either "cap prod1 deploy" or "cap prod2 deploy", I want to create a task "prod" which sets the required "deploy_to" based on the existence of a file on the server.
something like:
task :prod do
if (A_FILE_IN_SERVER_EXISTS)
set :deploy_to, "/home/project/src/prod2"
else
set :deploy_to, "/home/project/src/prod1"
end
How do I do that?

You can do that like this:
task :set_deploy_to_location do
if capture("[ -f /etc/passwd2 ] && echo '1' || echo '0'").strip == '1'
set :deploy_to, "/home/project/src/prod2"
else
set :deploy_to, "/home/project/src/prod1"
end
logger.info "set deploy_to = #{deploy_to}"
end
This will do what you need. You can hook this method using before and after hooks like this:
before :deploy, :set_deploy_to_location

Related

YAML, cmd based shell, if else conditions is not working

I am writing CICD in the YAML file of GitHub, therein one instance I need to compare the branch names where a pull request is being triggered to determine which environment the other underlying process thereafter should use to the do MsBuild and other tasks.
Below is the comparison in YAML:
- name: build
shell: cmd
run: |
if not x%GITHUB_REF_NAME:RSDEV_=%==x%GITHUB_REF_NAME% (
SET PLATFORM=Qa
) else if not x%GITHUB_REF_NAME:Feature_=%==x%GITHUB_REF_NAME% (
SET PLATFORM=Qa
) else if not x%GITHUB_REF_NAME:Release_=%==x%GITHUB_REF_NAME%(
SET PLATFORM=Uat
) else (
echo "Check something went wrong"
exit 1
)
However, when I ran pull-request, it says
The syntax of the command is incorrect
Am I following the correct way for branch comparison like release_** and so on cmd?
Btw, I was able to figure out the reason behind the error: The syntax of the command is incorrect
There was an indentation error in the else block:
- name: build
shell: cmd
run: |
if not x%GITHUB_REF_NAME:RSDEV_=%==x%GITHUB_REF_NAME% (
SET PLATFORM=Qa
) else if not x%GITHUB_REF_NAME:Feature_=%==x%GITHUB_REF_NAME% (
SET PLATFORM=Qa
) else if not x%GITHUB_REF_NAME:Release_=%==x%GITHUB_REF_NAME%(
SET PLATFORM=Uat
) else (
echo "Check something went wrong"
exit 1
)
[Courtesy Edit]
The correct syntax in cmd.exe:
if /i not "%GITHUB_REF_NAME:RSDEV_=%" == "%GITHUB_REF_NAME%" (
SET "PLATFORM=Qa"
) else if /i not "%GITHUB_REF_NAME:Feature_=%" == "%GITHUB_REF_NAME%" (
SET "PLATFORM=Qa"
) else if /i not "%GITHUB_REF_NAME:Release_=%" == "%GITHUB_REF_NAME%" (
SET "PLATFORM=Uat"
) else (
echo Check something went wrong
exit 1
)

Is it possible to get inside-out ordering of provisioners in a Vagrant multi-machine setup?

Is it possible to reverse the order of provisioners from innermost to outermost when using a multi-machine setup? I want a small shell provisioner to create some facts in /etc/facter/facts.d/ before provisioning with puppet, to mimic our current setup as much as possible. (I have inherited a large puppet repo and am trying to create a Vagrant testbed for it before I start doing changes.)
The puppet settings are the same for every box, but requires the shell provisioner to run first. Here's an example Vagrantfile to show what I want to do (some names changed to protect the innocent):
$facts =<<FACTS
set -x
mkdir -p /etc/facter/facts.d
echo role=$1 > /etc/facter/facts.d/role.txt
echo location=$2 > /etc/facter/facts.d/location.txt
echo environment=$3 > /etc/facter/facts.d/environment.txt
FACTS
Vagrant.configure(2) do |config|
config.vm.box = "centos-6.6"
config.vm.synced_folder "hiera", "/etc/puppet/hiera"
config.vm.provision :puppet do |puppet|
puppet.manifest_file = "site.pp"
puppet.module_path = ["modules", "internal"]
puppet.hiera_config_path = "hiera.yaml"
puppet.options = "--test"
end
config.vm.define :foo1 do |c|
c.vm.hostname = "foo-1.vagrant"
c.vm.provision :shell, inline: $facts, args: "foo testing stage"
end
config.vm.define :bar do |c|
c.vm.hostname = "bar-1.vagrant"
c.vm.provision :shell, inline: $facts, args: "bar testing stage"
end
# ... more machines omitted ...
end
Answering my own question as I found an acceptable workaround: I moved the puppet provisioning into the inner block. Here's what my current code looks like:
$facts =<<SET_FACTS
set -x
mkdir -p /etc/facter/facts.d
echo role=$1 > /etc/facter/facts.d/role.txt
echo location=$2 > /etc/facter/facts.d/location.txt
echo environment=$3 > /etc/facter/facts.d/environment.txt
SET_FACTS
module Vagrant
module Config
module V2
class Root
def provision(role, location, environment)
vm.provision "set-facts",
type: :shell,
inline: $facts,
args: [role, location, environment].map { |x| x.to_s }
vm.provision :puppet do |puppet|
puppet.manifest_file = "site.pp"
puppet.module_path = ["modules", "internal"]
puppet.hiera_config_path = "hiera.yaml"
end
end
end
end
end
end
Vagrant.configure(2) do |config|
config.vm.box = "centos-6.6"
config.vm.synced_folder "hiera", "/etc/puppet/hiera"
config.vm.define :foo1 do |c|
c.vm.hostname = "foo-1.vagrant"
c.provision(:foo, :testing, :stage)
end
config.vm.define :bar1 do |c|
c.vm.hostname = "bar-1.vagrant"
c.provision(:bar, :testing, :stage)
end
end

How do I use the inputbox to add info to a batch file that sends emails and require a password to send?

I've got this code from here and it works great to create and send:
:: email.bat :::::::::::::::::::::::::::::::::::::::::::::::::::::
#echo off
setlocal
:: use these settings to send from a gmail account
:: set port=465 and set SSL=True
:: use these settings for standard email SMTP port and no encryption
:: set port=25 and set SSL=False
:: Change these following items to use the same variables all the time
:: or use the command line to pass all the variables
set Port=25
set SSL=False
set From="myemail#myemailserver.com"
set To="recipient#server.com"
set Subject="Subject line"
set Body="Email Body in one line"
set SMTPServer="mailservername.myemailserver.com"
set User="username"
set Pass="password"
set fileattach="d:\myfolder\file.txt"
:: This section sets the command line arguments
:: use this format: CALL email.bat "myname#gmail.com" "RecipientEmailAddress#server.com" "Subject line" "Email Body in one line" "smtp.gmail.com" "myname#gmail.com" "password" "d:\folder\filename to attach.txt"
if "%~7" NEQ "" (
set From="%~1"
set To="%~2"
set Subject="%~3"
set Body="%~4"
set SMTPServer="%~5"
set User="%~6"
set Pass="%~7"
set fileattach="%~8"
)
set "vbsfile=%temp%\email-bat.vbs"
del "%vbsfile%" 2>nul
set cdoSchema=http://schemas.microsoft.com/cdo/configuration
echo >>"%vbsfile%" Set objArgs = WScript.Arguments
echo >>"%vbsfile%" Set objEmail = CreateObject("CDO.Message")
echo >>"%vbsfile%" objEmail.From = %From%
echo >>"%vbsfile%" objEmail.To = %To%
echo >>"%vbsfile%" objEmail.Subject = %Subject%
echo >>"%vbsfile%" objEmail.Textbody = %body%
if exist %fileattach% echo >>"%vbsfile%" objEmail.AddAttachment %fileattach%
echo >>"%vbsfile%" with objEmail.Configuration.Fields
echo >>"%vbsfile%" .Item ("%cdoSchema%/sendusing") = 2 ' not local, smtp
echo >>"%vbsfile%" .Item ("%cdoSchema%/smtpserver") = %SMTPServer%
echo >>"%vbsfile%" .Item ("%cdoSchema%/smtpserverport") = %port%
echo >>"%vbsfile%" .Item ("%cdoSchema%/smtpauthenticate") = 1 ' cdobasic
echo >>"%vbsfile%" .Item ("%cdoSchema%/sendusername") = %user%
echo >>"%vbsfile%" .Item ("%cdoSchema%/sendpassword") = %pass%
echo >>"%vbsfile%" .Item ("%cdoSchema%/smtpusessl") = %SSL%
echo >>"%vbsfile%" .Item ("%cdoSchema%/smtpconnectiontimeout") = 30
echo >>"%vbsfile%" .Update
echo >>"%vbsfile%" end with
echo >>"%vbsfile%" objEmail.Send
cscript.exe /nologo "%vbsfile%"
echo email sent (if variables were correct)
del "%vbsfile%" 2>nul
goto :EOF
and I found this bit for the input GUI:
#echo off
REM Input routine for batch using VBScript to provide input box
REM Stephen Knight, October 2009, http://www.dragon-it.co.uk/
call :inputbox "Please enter something for me:" "Box Title"
echo You entered %Input%
exit /b
:InputBox
set input=
set heading=%~2
set message=%~1
echo wscript.echo inputbox(WScript.Arguments(0),WScript.Arguments(1)) >"%temp%\input.vbs"
for /f "tokens=* delims=" %%a in ('cscript //nologo "%temp%\input.vbs" "%message%" "%heading%"') do set input=%%a
exit /b
All of the info in the email is static the to, from, subject, username, password and smtp except the body which I need the user input from the input box for. The user response for the body of the email will be exactly 12 characters. I have the input box script modified to display what I want for the input, but I dont know how to put it all into one file and pass the input over to the VBScript file.
To use a batch file input routine, Enter the required details in the lines below (which are already in the script) and add the last two lines shown.
set Port=25
set SSL=False
set From="myemail#myemailserver.com"
set To="recipient#server.com"
set Subject="Subject line"
REM set Body="Email Body in one line"
set SMTPServer="mailservername.myemailserver.com"
set User="username"
set Pass="password"
set fileattach="d:\myfolder\file.txt"
set /p "Body=Enter the 12 characters here: "
set Body="%body%"

Capistrano 3: Relative symlink instead of absolute for current, linked_dirs and linked_files

I need to have relative symlink​ instead of absolute symlink​ when deploying.
I think the tree tasks than need to be overwritten are.
Rake::Task["deploy:symlink:linked_dirs"]
Rake::Task["deploy:symlink:linked_files"]
Rake::Task["deploy:symlink:release"] ​ ​
What I would like is some DSL I can drop in my deploy.rb so when I'm deploying created links are all relative.
You can juste use this in your deploy.rb to overwrite the default behaviour
## Use relative path instead of absolute
Rake::Task["deploy:symlink:linked_dirs"].clear
Rake::Task["deploy:symlink:linked_files"].clear
Rake::Task["deploy:symlink:release"].clear
namespace :deploy do
namespace :symlink do
desc 'Symlink release to current'
task :release do
on release_roles :all do
tmp_current_path = release_path.parent.join(current_path.basename)
execute :ln, '-s', release_path.relative_path_from(current_path.dirname), tmp_current_path
execute :mv, tmp_current_path, current_path.parent
end
end
desc 'Symlink files and directories from shared to release'
task :shared do
invoke 'deploy:symlink:linked_files'
invoke 'deploy:symlink:linked_dirs'
end
desc 'Symlink linked directories'
task :linked_dirs do
next unless any? :linked_dirs
on release_roles :all do
execute :mkdir, '-p', linked_dir_parents(release_path)
fetch(:linked_dirs).each do |dir|
target = release_path.join(dir)
source = shared_path.join(dir)
unless test "[ -L #{target} ]"
if test "[ -d #{target} ]"
execute :rm, '-rf', target
end
execute :ln, '-s', source.relative_path_from(target.dirname), target
end
end
end
end
desc 'Symlink linked files'
task :linked_files do
next unless any? :linked_files
on release_roles :all do
execute :mkdir, '-p', linked_file_dirs(release_path)
fetch(:linked_files).each do |file|
target = release_path.join(file)
source = shared_path.join(file)
unless test "[ -L #{target} ]"
if test "[ -f #{target} ]"
execute :rm, target
end
execute :ln, '-s', source.relative_path_from(target.dirname), target
end
end
end
end
end
end

Checksum of file in vbscript

I have the following command
"C:\Program Files\File Checksum Integrity Verifier\fciv.exe" -sha1 "D:\new.txt"
How to run this command from vbscript? Can anybody help me?
VBScript comes with a couple of different ways to execute command lines, both of which are on the WshShell object (WScript.Shell)
Using WshShell.Exec
Dim WshShell, oExec
Set WshShell = CreateObject("WScript.Shell")
Set oExec = WshShell.Exec("""C:\Program Files\File Checksum Integrity Verifier\fciv.exe"" -sha1 ""D:\new.txt""")
Do While oExec.Status = 0
WScript.Sleep 100
Loop
WScript.Echo oExec.Status
Using WshShell.Run
Dim WshShell
Set WshShell = CreateObject("WScript.Shell")
WshShell.Run """C:\Program Files\File Checksum Integrity Verifier\fciv.exe"" -sha1 ""D:\new.txt""", 1, true