Saltstack - installing script with manual interactions - salt-stack

I am creating a state which is running a shell script, but to be installed need manual interactions.
like:
press yes to continue
add home folder for the user x
accept license agreement yes or no
default answer is: n
is the following path correct press yes to continue
etc.
Start_shell_Script:
cmd.run:
- name: script.sh
- stateful: True
- shell: /bin/bash
- runas: user-x
I would like to automate the process and do not cut in half the installation of the application and run some scripts manually.
Thank you in advance.

As of now there is no built-in way to pass interactive inputs to scripts from Saltstack cmd module. However take a look at Linux expect. This is one of the ways you can automate your interactive scripts.
To be specific, autoexpect is a handy tool to quickly automate an interactive script. For your use case, you can run it as:
autoexpect /path/to/script.sh
Provide interactive inputs as required. This will create a script.exp (expect script) with a record of your inputs. This can then be run at any time with expect /path/to/script.exp non-interactively.
You can transfer this file to the minion and use it in a Salt state as well:
Start_shell_Script:
cmd.run:
- name: /usr/bin/expect /path/to/script.exp

Related

R function(s) create file that can't be deleted: "The operation can’t be completed because a required item is in use."

First off, I apologize in advance that I don't know how to provide a reproducible example, because I'm not sure what is even causing this problem. I will provide as much detail as possible. I am on macOS Catalina 10.15.7, using R 4.1.0, and RStudio 1.4.1717.
I'm using a set of custom R functions and scripts, some of which involve creating and writing to logfiles, almost always logfile.txt or something of that sort. The scripts include the following line before any writing to delete any old logfiles:
system("touch logfile.txt; rm logfile.txt")
The outputs are written using commands of the structure:
system(paste0('echo \"Some output ', variable, ' here\" >> logfile.txt'))
Finally, one of the scripts uses the flock package to prevent simultaneous writing in certain parallelized sections:
intro.lock = flock::lock("logfile1.txt")
Which is then unlocked 2 lines later after writing output:
flock::unlock(intro.lock)
My problem is that most of the time, these logfiles created are IMPOSSIBLE to delete, even the ones that don't use flock. Whenever I try deleting them, I get the error: "The operation can’t be completed because a required item is in use." See image here:error message
Steps I have tried:
Quitting RStudio and all other apps that might be using the file
Deleting the file via terminal with [sudo] rm logfile.txt. I get rm: logfile.txt: Resource busy
Running system(paste0("chflags -R nouchg,noschg logfile.txt")) in each script that makes a logfile
Using "Get Info" to see if the file is locked (none of them are)
Checking lsof +D ./ for any processes using these files. None appear to be.
The only solution I know of that makes these files able to be deleted is to restart my entire computer. After a restart, they are deletable using any method, even just dragging to the trash.
Any possible solutions are much appreciated.
Not sure if this will solve your problem, but in one of my scripts I use the following to clean up specific files that are 'left behind' at the end of the run:
rm(list = ls())
gc()
system("rm -R /tmp/Rtmp*")
system("rm -R /tmp/lib*.so")

unix script for initial setup using ssh, newgrp, cleartool setview: how to avoid subshell?

I have following requirements for a project initial setup
need to login to remote server using ssh <servername>
need to change default group using newgrp <grpname>
need to set the clearcase view using cleartool setview <viewname>
change dir to clearcase vobs using cd /vobs/proj/dita
I am trying to write a script which I source when I open a new terminal which does all the above and give me the terminal with required setup.
Now the problem is, 3 out of 4 above commands create a new shell.
Can you help me to achieve this?
Do no use cleartool setview (which does spawn a subshell, as I mentioned before, and as you found out)
Use, as described here, the full path of the view you want to access in your ssh session:
/view/view-tag-name/vobs/some/path
That way, you are sure to remain in the same shell.

what's the differences between functions in state file and functions in command line in saltstack?

When I use saltstack to manage my servers. I found an interesting thing:
When I run salt '*' pkg.installed httpd, I get the following message: pkg.installed is not available. But I can use pkg.installed function in my .sls files and it worked very well. So, I am confused about that. And I think this is happening because of saltstack.
Who can help me?
There are two related but different concepts here.
Salt Execution Modules
Salt State Modules.
Execution modules are where most of the work actually happens and is what you are running on the command line, generally. For example:
salt '*' pkg.install vim
That will call out directly to your OS's package manager, such as yum or apt, and install vim.
State modules are statefull commands that kind of sit "above" the execution modules. A state module will check if the desired result already exists and make any necessary changes to get the desired state. They are conjugated differently than the execution modules. For example in this salt state file (sls file):
cat /srv/salt/vim.sls
install_vim_please:
pkg.installed:
- name: vim
Then you could run the state.sls execution module to apply this sls file with the pkg.installed state.
salt '*' state.sls vim
Because we're using the pkg.installed state Salt will check with your OS's package manager and see if vim is already installed. Salt will only attempt to install vim if the package manager says that vim is not installed already.
Keeping your Salt States in sls files makes it easy to keep them in git or whatever vcs you use to track them.
You could skip the sls file and run the command statefully from the command line like this:
salt '*' state.single pkg.installed name=vim

How to install something using saltstack?

Saltstack documentation is very difficult and unclear for beginner. If you could give simple example how to install something on vagrant machine using saltstack I'd be very grateful
I believe some tutorials are out on the web. I could offer some of mine:
Setup Zabbix using Salt in a masterless setup, this installs among others a PHP stack needed for Zabbix.
Setup Consul in the cloud at DigitalOcean, with Saltstack. Includes a full script, but also works with Vagrant (see cheatsheet.adoc)
I think the biggest help for me when starting was the SaltStack tutorials.
https://docs.saltstack.com/en/getstarted/fundamentals/index.html
The states tutorial gives an example of installing rsync, lftp and curl:
https://docs.saltstack.com/en/getstarted/fundamentals/states.html
This tutorial shows how to setup what you need with vagrant with a master and a couple of minions, shows basics of targeting minions and setting up state files (the files that tell Salt what to do on a minion).
There is a lot more to Salt than that, but it is a good start.
In Saltstack there are two types of machines :
Master : As the name suggests this is the controlling. You can use this to run tasks on multiple minions.
Minion : Minions are like slaves. You can run commands on minions, or install any packages, run scripts on minions through master. Basically any command or any task that you can run by logging into a minion machine you should be able to accomplish through the master machine.
You can write all the tasks you want to perform on minion in an sls file and run it.
Saltstack has functions which you should call along with the desired arguments. Every function performs a specific task. Saltstack has Execution modules and States modules
Execution modules:
They are designed to perform tasks on a minion. For example: mysql.query will query a specified database. The execution module does not check if the database needs to be queried or not. It just executes its task.
Have a look at the complete list of modules and you will see that they will just execute a task for you. https://docs.saltstack.com/en/latest/ref/modules/all/index.html
States module:
It's called THE states module.
The states module is a module too. But it's a special one. With the states module you can create states (the sls files under /srv/salt ) for your Minions.
You could for example create a state that ensures the Minion has a web server configured for www.example.com.
After you have created your state you can apply it with the states module: salt state.apply example_webserver
The example_webserver state specifies what the Minion needs to have. If the Minion is already in the correct state, it does nothing. If the Minion is not in the correct state it will try to get there.
The states module can be found here: https://docs.saltstack.com/en/latest/ref/states/all/salt.states.module.html
Sample sls file :
//This state is to make sure git is installed. If yes : no action will be taken if not it will be installed.
git_install:
pkg.installed:
- name: git
//This step makes sure the folder with the specified name is not present. If it is present it will be deleted. Here "delete_appname_old" is the step name and should not be duplicated in the same sls file
delete_appname_old:
file.absent:
- name: /home/user/folder_name
//This step is for cloning a git project
clone_project:
module.run:
- name: git.clone
- url: ssh://gitreposshclonelink
- cwd: /home/user/folder_name
- user: $username
- identity: $pathofsshkey

How to check that package is not present on server in SaltStack state file?

I am trying to automate an Aerospike database installation using saltstack version 2015.5.2 on an Ubuntu machine.
The following is the process of manual installation that I want to automate. (I'll only mention the key steps to keep it simple)
Download Aerospike
wget -O aerospike.tgz
http://aerospike.com/download/server/latest/artifact/ubuntu12
extract the contents of the package
tar -xvf aerospike.tgz
Install Aerospike Server & Tools
cd aerospike-server-community-3.5.15-ubuntu12.04
./asinstall
Start Aerospike
/etc/init.d/aerospike start
Step 3 performs the actual installation which includes installation of 2 packages: aerospike-server-community and aerospike-tools.
Now in the saltstack state file I want to check if both the packages are already present on server, and in that case do not execute the ./asinstall command in step 3.
How can I involve that condition in my automated process?
I recommend you read requisites in salt before going on because you can find many interesting things there.
Furthermore,what you really need, in my opinion is: UNLESS, because if you already have these packages on your system they should not be installed. Unless can be used together with the pkg keyword, but for you the rpm -q package_name might work just as well.
It should look something like this:
start_process:
cmd.run:
- name: 'write here your command'
- unless:
- rpm -q package1,package2
I would like to provide a small comment to the answer, but my reputation does not allow me, so I apologize in advance for this.
This line:
- rpm -q package1,package2
Should actually be:
- rpm -q package1 package2

Resources