String parsing via ruby (chef) - ruby

Need to do install on centos 6 logrotate 3.8.7 out of sources, via chef.
Using simple execute. But also need to check for existing installation. How can I do that thing, if I can't parse logrotate --version output.
logrotate --version | tr -cd [:digit:]
&
logrotate --version | tr -d "logrotate"
and awk - no use..
Even if I don't parse output, chef can't compare it with my variable..
My recipe is:
ver = `logrotate --version`
if ver.eql? "logrotate 3.8.7"
puts "nothing to do"
else
bash "logrotate-source-install" do
user "root"
group "root"
cwd "/tmp"
code <<-EOH
cd /tmp
yum -y install gettext popt-devel
wget https://fedorahosted.org/releases/l/o/logrotate/logrotate-3.8.7.tar.gz
tar xf logrotate-3.8.7.tar.gz
cd logrotate-3.8.7
gmake
gmake install
EOH
end
end
Thx in advance.
Upd.
actual_ver = `logrotate --version 2>&1 | awk '{print $2}'`
ver = "3.8.7"
if actual_ver == ver
puts "nothing to do"
else
bash "logrotate-source-install" do ...
Parsing done, but chef can't recognize output..

You could use attribute only_if to guard this resource for idempotence.
Also, good idea would be to pull version to node attribute like:
default['logrotate']['version'] = '3.8.7'
and then use it in recepie:
version = default['logrotate']['version']
bash "logrotate-source-install" do
user "root"
group "root"
cwd "/tmp"
code <<-EOH
yum -y install gettext popt-devel
wget https://fedorahosted.org/releases/l/o/logrotate/logrotate-#{version}.tar.gz
tar xf logrotate-#{version}.tar.gz
cd logrotate-#{version}
gmake
gmake install
EOH
not_if "[ ${version} = \"$(logrotate --version 2>&1 | awk '{print $2}')\" ]"
end

Better version of this:
bash "logrotate-source-install" do
user "root"
group "root"
cwd "/tmp"
code <<-EOH
cd /tmp
yum -y install gettext popt-devel
wget https://fedorahosted.org/releases/l/o/logrotate/logrotate-3.8.7.tar.gz
tar xf logrotate-3.8.7.tar.gz
cd logrotate-3.8.7
gmake
gmake install
EOH
only_if do
version = shell_out('logrotate --version')
version.error? || version.stdout.split.last != '3.8.7'
end
end
This uses the only_if guard clause to control if the resource converges or not, and uses the shell_out helper instead of Ruby's shell execute syntax. This will be more widely portable, automatically splits stdout and stderr, and will correctly run the install if the command fails. Also doesn't depend on awk.

String parsing via ruby do the thing:
actual_ver = `logrotate --version 2>&1 | awk '{print $2}'`
ver = "387"
if actual_ver.delete('^0-9') == ver
puts "nothing to do"
else
bash "logrotate-source-install" do
user "root"
group "root"
cwd "/tmp"
code <<-EOH
cd /tmp
yum -y install gettext popt-devel
wget https://fedorahosted.org/releases/l/o/logrotate/logrotate-3.8.7.tar.gz
tar xf logrotate-3.8.7.tar.gz
cd logrotate-3.8.7
gmake
gmake install
EOH
end
end

Related

Unable to install Ruby on Ubuntu

I'm trying to install Ruby 2.6.1 on Ubuntu but keep coming across this error.
Have tried uninstalling Ubuntu, googling the problem, running in administrator mode, downloading a different version.
This is the error:
:~$ rvm install 2.6.1
Searching for binary rubies, this might take some time.
Found remote file https://rvm_io.global.ssl.fastly.net/binaries/ubuntu/20.04/x86_64/ruby-2.6.1.tar.bz2
Checking requirements for ubuntu.
Installing requirements for ubuntu.
mkdir: cannot create directory ‘/usr/share/rvm/log/1625135668_ruby-2.6.1’: Permission denied
tee: /usr/share/rvm/log/1625135668_ruby-2.6.1/update_system.log: No such file or directory
Updating system..jaydene password required for 'apt-get --quiet --yes update':
Sorry, try again.
jaydene password required for 'apt-get --quiet --yes update':
..
Error running 'requirements_debian_update_system ruby-2.6.1',
please read /usr/share/rvm/log/1625135668_ruby-2.6.1/update_system.log
Requirements installation failed with status: 1.
:~$
you can use a gorails website to checkout ruby on rails installation. And ruby installs version as per dependencies on your system. If it's not founding 2.6.1 it will install next supported version for ex. 2.6.7.
check this website: https://gorails.com/setup/ubuntu/21.04
Check this: How do I install Ruby 1.9.3 on Ubuntu without RVM? but SO says to avoid link answers so here is the script:
#!/usr/bin/env bash
# -- this really is the only solution that worked for me on snap :/
ruby -v
if ! command -v ruby &> /dev/null
then
echo "Going to try to install ruby (ideally 3.1.2)"
# - install rebenv (following ruby-build really is needed eventhough it doesn't look like it)
mkdir -p ~/.rbenv
cd ~/.rbenv
git clone https://github.com/rbenv/rbenv.git .
# if $HOME/.rbenv/bin not in path append it, otherwise don't change it
echo $PATH | tr ':' '\n' | awk '{print " " $0}';
if [[ ":$PATH:" != *":$HOME/.rbenv/bin:"* ]]; then
echo "might want to put $HOME/.rbenv/bin in your path"
export PATH="$HOME/.rbenv/bin:$PATH"
# echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc.lfs
fi
eval "$(rbenv init -)"
rbenv -v
# - install ruby-build, odd, this really is needed for ruby to install despite it not looking like ruby build is need at the bottom
mkdir -p ~/.ruby-build
cd ~/.ruby-build
git clone https://github.com/rbenv/ruby-build.git .
# if $HOME/.ruby-build/bin not in path append it, otherwise don't change it
echo $PATH | tr ':' '\n' | awk '{print " " $0}';
if [[ $PATH != *"$HOME/.ruby-build/bin"* ]]; then
echo "might want to put $HOME/.ruby-build/bin in your path"
export PATH="$HOME/.ruby-build/bin:$PATH"
# echo 'export PATH="$HOME/.ruby-build/bin:$PATH"' >> ~/.bashrc.lfs
fi
ruby-build --version
# - install ruby without sudo -- using rbenv
mkdir -p ~/.local
# ruby-build 3.1.2 ~/.local/
rbenv install 3.1.2
rbenv global 3.1.2
fi
ruby -v
# - Original Prover doesn't work on SNAP
# Proverbot's way to install ruby
# # First, install Ruby, as that is for some reason required to build the "system" project
# git clone https://github.com/rbenv/ruby-build.git ~/ruby-build
# mkdir -p ~/.local
# PREFIX=~/.local ./ruby-build/install.sh
# ~/.local/ruby-build 3.1.2 ~/.local/
# ref: https://superuser.com/questions/340490/how-to-install-and-use-different-versions-of-ruby/1756372#1756372

In clause in if statement in Linux Shell

I'm trying to check if python is installed on the system. if not then install it and run a given code on the machine. We have Linux servers and all servers need this script to be executed.
I'm facing a problem here, my if statement is not working. I don't know why. I'm trying to see if the echo for python --version returns "not found" but the string will be quite big, so I'm checking for a substring. Is there any "IN" statement?
Following is my Code.
#!/bin/sh
# Author : Sushrut Guruji
# Copyright (c) sushrut_guruji
# Script follows here:
INSTALL=$(python3 --version)
PyScriptPath="/PyScripts"
echo $INSTALL
if [[$INSTALL=~*not*found]]
then
echo 'in if'
sudo apt-get install python3.9
sudo ln -s /usr/bin/python3 /usr/bin/python
sudo apt install -y python3-pip
sudo ln -s /usr/bin/pip3 /usr/bin/pi
else
echo "in else"
fi
cd $PyScriptPath
sudo pip install -r requriements.txt
P.S. I'm a novice. Please don't laugh.

`command -v` seems to only search in /usr/bin

For some shell script I need to store output of command -v foo in variables. I am checking if some binaries exist on the system. When I execute command -v foo in terminal, I get an output but when I execute command -v foo inside a shell script I don't get any output.
➜ tools git:(install-script) ✗ command -v node
/usr/local/bin/node
check_deps() {
declare -A deps
deps=( ['git']=`command -v git`
['gem']=`command -v gem`
['node']=$(command -v node))
# ['redis-server']=command -v redis-server
# ['postgres']=command -v psql
# ['sass']=command -v sass
# ['gulp']=command -v gulp
# ['bower']=command -v bower )
for each in ${!deps[#]};
do
echo $each ${deps[$each]}
done
}
check_deps
Output is:
node
git /usr/bin/git
gem /usr/bin/gem
[Finished in 0.0s]
What's happening? How do I fix this?
I was using Sublime Text which had a plugin called Bash Build system. Basically it got me a file which didn't have /usr/local/bin, this build syntax now returns proper command -v output:
{
"cmd" : ["bash", "$file"],
"selector" : "source.shell",
"osx": {
"path" : "$PATH:/usr/local/bin"
}
}

Cannot install gem with Chef for an RVM gemset

I am simply trying to install passenger for nginx but installing the passenger gem fails. Here's what I have in my recipe:
rvm_gem "passenger" do
ruby_string "ruby-1.9.3-p194#env"
action :install
end
# install nginx for rails
execute "passenger_module1" do
user "#{node[:user][:name]}"
environment ({'HOME' => "/home/#{node[:user][:name]}"})
command "rvmsudo passenger-install-nginx-module --auto | bash"
action :run
end
Here's the Error message:
[2012-12-10T01:05:52+00:00] FATAL: Mixlib::ShellOut::ShellCommandFailed: rvm_gem[passenger] (main::default line 127) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit with [0], but received '1'
---- Begin output of bash -c "source /etc/profile.d/rvm.sh && rvm version | cut -d ' ' -f 2" ----
STDOUT:
STDERR: bash: /etc/profile.d/rvm.sh: No such file or directory
---- End output of bash -c "source /etc/profile.d/rvm.sh && rvm version | cut -d ' ' -f 2" ----
Ran bash -c "source /etc/profile.d/rvm.sh && rvm version | cut -d ' ' -f 2" returned 1
I don't see any issues with your Chef recipe fragment. The error message indicates that the execution of rvm in the shell is failing, because /etc/profile.d/rvm.sh does not exist.
This makes me think that you may not have rvm installed on this node. Did you install rvm on the node?
If you did, did you do it in a way that made it immediately available for use in your Chef run?

Auto-install packages from inside makefile

Goal: when the user types 'make packages', automatically search for the package libx11-dev (required for my program to compile) and, if not found, install it. Here's a stripped-down version of my makefile:
PACKAGES = $(shell if [ -z $(dpkg -l | grep libx11-dev) ]; then sudo apt-get install libx11-dev; fi)
[other definitions and targets]
packages: $(PACKAGES)
When I type 'make packages', I'm prompted for the super-user password. If entered correctly, it then hangs indefinitely.
Is what I'm trying to do even possible from within the makefile? If so, how?
Thanks so much.
The problem is that the shell function acts like backticks in the shell: it takes the output to stdout and returns it as the value of the function. So, apt-get is not hanging, it's waiting for you to enter a response to some question. But you cannot see the question because make has taken the output.
The way you're doing this is not going to work. Why are you using shell instead of just writing it as a rule?
packages:
[ -z `dpkg -l | grep libx11-dev` ] && sudo apt-get install libx11-dev
.PHONY: packages
I figured out a better way, which avoids the problem of having unexpected arguments to the if statement:
if ! dpkg -l | grep libx11-dev -c >>/dev/null; then sudo apt-get install libx11-dev; fi
The -c flag on grep makes it return the number of lines in dpkg -l which contain the string libx11-dev, which will either be 0 (if uninstalled) or 1 (if installed), allowing
dpkg -l | grep libx11-dev -c
to be treated like an ordinary boolean variable.

Resources