Thursday, August 31, 2017

Ruby required for chef



There are three basic constraints:

1)How to apply conditions?
2)How to use loops,for that,what is the syntactical structure we need to follow.
3)And how do you define variables and all other stuff in ruby?

You can take this and directly apply in your recipe.

(ruby has programming language strength directly).


one is chef documentation for ruby.

other one is:

ruby on windows  >>  rubyinstaller for windows. (google)

$ruby –v

and do

irb  (Interactive ruby,you can extract the interactions of the ruby over here).

Why do I need to learn ruby?

Ansible internally uses python   ---. WE WRITE HERE PLAYBOOK (WHICH MAY HAVE THERE,OWN LANGUAGE TO DEFINE THINGS)
Puppet internally uses ruby  à   WE WRITE HERE MANIFESTS (WHICH MAY HAVE THERE,OWN LANGUAGE TO DEFINE THINGS)
Where as in chef,you directly ruby.
It is very easy to write ruby syntaxies.

Yum install httpd
Apt-get install  apache2

Some resource called package.

-à package  ‘httpd:   (centos) when run in redhat,this line should be executed.
à  package   ‘apache2:  (Ubuntu) ) when run in debian,this line should be executed.

For these kind of loop,how do we control in loop.

(Generally,when you come with the programming language,all of the 1o lines will be executed one after the other).

How to start the services?
Service httpd start
Service apache2 start

If you want package for 10 times,you wont write package for 10 times,it’s a bad practice.you iterate the one package.

Where are ruby files used?
Recipes is the place,where we use the ruby.
Attributes,roles,environment we use ruby in all these places.


How to execute all the lines of the code.(write syntaxies,that will execute one-after the other.
How to choose between the lines of the code.
FOR EXAMPLE:
A
B
C
D
If you want to execute all the four.
(but there will situations,where you want to execute A,B  and D,you want to skip C).
because for example it is RedHat.
(but there will situations,where you want to execute A,B  and C,you want to skip C).
because for example it is Debian.

One some cases,you want to execute A and B for 10times and C for 15times.

How do you control these executions?
We need to control the executions.

How do you maintain this?
This is equivalent to the shell scripting.

Ruby is beyond that,there is a rubygem. (not covered)
We are getting  in to key basic constraints of programming.

***** We are just controlling the execution of lines:

whatever the programming,we write,it will use read memory.
(do they use RAM or do they use hard disk??).
RAM
Why do they RAM?
Because,harddisk is not meant for executions.(harddisk is meant for storage).
Whenever your program executes.Memory will be created and whatever values you give will be store in the memory.

Generally,if you know the RAM:
RAM Is nothing but a slot of address spaces.

It will have,many address locations.(in hexadecimal).

For example,

If you want to store the 10,it will look the address,something like this:
Xof334f

This might be the address of your variable,where your storing.address of the data,wherever your storing.

And everytime,this address is changed.
(you cannot get the same addresses on every machine).

Is it possible,to access the memory of the RAM by its address,I don’t think so,we have that option,because it is quite dynamic,In my machine,if I am running the game and launching my application,my execution will be extremely at the end,because most of the RAM was used.lossed on lot of memory.

When you accessed too much of data,the address you get is different.

To  access a storage location in RAM,going by a address is a principle that works only on microprocessors.
(this works here in 8086 and 8051 microprocessor,because you know the addresses).

But here it is dynamic addresses.

What every programming language comes up is,it will define something called as variable.
So the purpose of variable is to give,an alias to your memory location.because for me it is difficult right,

For example on my machine,this is the address  xof334f
On your machine,something it is like 0xfgc …
(this is not same and even if I execute again,I don’t know I get the same addresses).

Every programming language,as a concept of referring to the address in your memory,that is been done with the concept of variable.

For example:

If I write sometime like  a=10;
(your intension,to store the value called 10 in to the RAM).

When you store 10 in to the RAM,you get the address.
And from there,you define the address not from there,but you will give the alias name as ‘a’.

For example
à  a =a+1
(what your saying access a=10  and perform addition on that).
(11,assign this to the address,where it was present).

Basically,we are operating on memory.

Note:
Variable is nothing but a reference to a memory location.
(it looks readable and simple,in everyone’s machine).
(One thing is clear that,we are allocating the memory right and we refer that by variables).

Next question:
how much memory we have to allocate?
We cannot have integers throughout our program.
We use,many kinds of data.
The size of the data,is determined by what your storing.

That is,why programming languages will have  a concept called the datatypes:

The primary reason for datatypes is:
To tell your operating system,how much memory,do you need on RAM.

For example:
Integer is a 32 bit.
Boolean(true/false) -à 1bit
Floating numbers.
Realnumbers.
Decimal points also.
Whenever you write something like int a.
Basically,your demanding 32 bit of space in the RAM.
So,we are having different kinds of data.
Note:
All of these called,fixed lenght of datatypes.

But there are,majority of the data,what we used are not fixed:

Example:

Using ruby,we are all writing library application,will every book will have a name with same characters.every book title will have same length?,similarly every book’s authors name,there are many factors,when you text,you cannot fix.

So that’s way,they defined a variable called the `string`.

Note:
Whenever your referring a string,your referring as,variable length datatype.
You will not be able to determine the size of the string,until you assign a value.

For EXAMPLE:
WORKING NATURE OF STRING:
String a  = “hello”
So it requires the space of 5+1, 6 characters.
For each character,how much space it takes?
These calculations happened dynamically.

In simple,
How many kinds of datatypes?
Fixed-length (integer,Boolean……etc),there will be a number assigned to it and it is easy for the programming language to ask for it).

Variable-length.

-à   a = a.append(“hai”)
basically,I want to write hello   hai
(initially,it requires 6 spaces and suddenly your asking same variable,where it size was gone from    to appx 8 characters.

For example,each character is a byte,that means 6 now demands 9 to 10 spaces.


Whenever you do operations on memory,you do that.

For example,

The above box is system allocation.
The first statement,you executed is a. it is 6 characters.
That is hello,   --à   you the space as  `OUR`  in figure

After that someone has space à it is `Some`.


Now,your requirement was changed from 6 characters  to  9
(can you allocate over there,I mean can you allocate sequentially,because your characters have to be sequential,whenever you execute).

Now,what is the problem,with that?
Whnever you use a string everytime,what happens generally is,everytime a new memory will be allocated.
Whenever you change any change anything on the string.

Let it be increasing or let be decreasing.
That’s why strings are called as immutable datatypes.

Note:
Whatever,you operate,everytime a new memory will be allocated.
(you have to be careful with the string,with this understanding).

There will be multiple applications,who are requesting for the RAM,the chrome browser which requires some memory,you launched word application,you launched excel application they will also require some memory right.

For example:
After your programming task is finished,somebody might be asking for the memory.
(and you cannot guarantee,always the sequential amount of characters).

Working with the variable datatypes:
Generally,there are immutable because,especially when there are growing or decreasing.loss on certain spaces.

Note:
We cannot have fixed spaces in any programming languages.

Note:
Strings are called as immutable datatypes,
example:
whatever operation you do on the string.
à  a = a.append
à a  = a.remove (if you done,something,to remove one character).
(these kind of operations ,your allocating a new memory everytime).

Note:
So,whenever your working on string,be careful.

Note:
So,we have to write,these kind of operations in the  `FOR loop`.

Note:
For example:
You cannot  write  `while (true)`
         a= a+1
where a is string,your application(programming) will be crashing.
(because,your application is continuously increasing the memory).
Then after the sometime,you get an error,how is your machine is and a prompt running out of memory.

(Strings are always,variable-length).

Note:

While learning any programming language,the first thing,we have to focus on what datatypes are available and how to apply.
And once you,know that,its just applying the syntaxies.

What are the variableS that are supported in Ruby?
Fortunately,you noneed to be explicit about  your datatypes in the ruby language.

For example: if write the code,

a =10 (there is no need tell that is an integer,ruby will understand automatically).
a = 10.3  (in this case,it will identify,being  a float).
a = “hello”
(a can be only one datatype,)
I want to store one package name,if you have a variable,I can store the package name.

Rather than,having “a” I will be writing:

Package_name=”httpd”
(this is what,we have to prefer).
Version_number=7.9
Or
We can give “7.9”
Version_number=”7.9”
(if you give 7.9 in quotes,is it a string or a number,it is a string).
If it either  ‘ ‘ or “ “ it is a string,with out quotes (Double/single) then it is a number.

Ruby datatypes
1)Strings
2)Numbers
3)Arrays
4)Hashes
5)Symbols.

We will be using symbols a lot.

 à  action  :install    (: the semicolon is called the symbol here).

what is a ruby symbol ?
whenever you see the string,starting with the  symbol that is called the ruby symbol.

(they have effective way of managing strings and symbols).

We can write in two ways,it gives the same result.

àaction :install
àaction “install”

(symbol is a better way of handling,that’s what ruby believe).

The example are from irb (interactive ruby).

Irb<main>:008:0= :

Trying variables in powershell

Irb<main>:008:0> no_of_installation=10
= > 10
Irb<main>:008:0> no_of_installation
= > 10
Irb<main>:008:0> no_of_installation=100
= > 100
(it gave me 100).
Irb<main>:008:0> package_name= “apache2”
= > “apache2”
Irb<main>:008:0> package_name= “httpd”
= > “httpd”
Irb<main>:008:0> package_name
= > “httpd”
(because that was the last executed state).

Lets us assume that,I have variable name as package_name right.

I want to print which looks something like this:

I am going to install,(whatever name is there in the package file) -à apache2.

Note:
With in a string,you want to use a string,but that string should not be hardcoded,you want to use it dynamically.

“I am going to install apache2 and count  = your number of installations”.

Actually,you want to write a string which is dynamically now.

I am not to install,whatever the variable name and count =10.
(you have two variables and we are trying to create a string,try to accomidate values of two variables).

This kind of things are called as formatting/code substitutions.

Techincal term for this process =  interpolation.


How to do this in ruby?
There is a standard syntax,which you need to follow:
(whenever your do this code substitution/interpolation your strings cannot be in single quotes).

Note
Your string has to be in double quotes.

Difference between single quote strings and double quote strings  in ruby
single quote strings  -à  if your string is single quote,you cannot interpole it.
(or you cannot substitute the values of other variables in to this).

So for any kind of substitution,we will use the double quotes.


Irb<main>:008:0> message = “I am going to install  #{package_name}”

(In most of our configuration files right,we have to change certain values).

This is something,we will be using a lot.


Irb<main>:008:0> message = “I am going to install  #{package_name}  and count =  (no_of_installations) [(another variable) that is interpolation/substitution].
“I am going to install  httpd and count =100”

Note:
The syntax for the code substitution is :
#{<variable_name>}

we need to use this,in our strings,so that value of that string substituted.

One more explanation on that:

Sometimes,the data which you want to access,might not be singular.

For example,you want to install three installations.


You need to give the data,multiple in nature.

In this situation,we will be using the Array.

Basically,Array multiple data that has been present.

(I want to have multiple values in a variable)
because I want to install,multiple installations.

We would like to create a variable called package_name

Irb<main>:008:0> package_name = [“apache2”,”wget”,”tree”]
(these are the sofwares to be installed).
= > [“apache2”,”wget”,”tree”]  (this is the output).
The first item we are giving is apache2 and the next item,we want to give is the indexing.

[index is the postion of item in the string].

Whenever the position,the array index,starts at zero.

We have to always reduce the [postion-1].

First position  is apache.
Second position is wget.
Third position is tree.

“arrays index starts from zero”


Irb<main>:008:0> package_names[0]
= = > “apache2”

Irb<main>:008:0> package_names[2]
= = >  “tree”

Irb<main>:008:0> package_names[4]
= = > nil

(In array,we will have,all the things with the datatype).


This is my arrays variable name  packages_and_versions = [“apache2”,”1.7”,”tomcat”,9].

We have a combination of string and other datatypes.

Irb<main>:008:0> [“apache2”,”1.7”,”tomcat”,9].
=  > [“apache2”,”1.7”,”tomcat”,9].

(this is allowed).


Note: An array in ruby,need not to be same datatype.can be of multiple datatypes.


In ‘C’  language  it is homogenous kind of datatype.(that means same datatype in an array).
But that is not the case in ruby.
That is not the case,even in python.

In ruby,
It is just collection of data.(it Is irrespective of datatype).

How to implement all the above things in to the recipe?

For example the below one is the recipe:

#cookbook
#Recipe:: tomcat_install


apt_update   ‘update  ubuntu’ do
    action   :update
end

package  ‘tomcat7’  do
    action  :install
end

service ‘tomcat7’ do
   action  :start
end


Note:

We are using the ‘tomcat7’ for several times,this creates memory allocations in many places.
(even the value is same,we are creating two memory locations).

Rather than,using this,create a variable.

Tomcat_pack_name = tomcat7

apt_update   ‘update  ubuntu’ do
    action   :update
end

package  Tomcat_pack_name  do
    action  :install
end

service ‘Tomcat_pack_name
do
   action  :start
end

now,we are having tomcat7 at one memory allocation,we are saving some memory in the programming.

Whenever your seeing repetition of values,rather than hardcoding them,putting them in the variable makes more sense.

(it just reads the variable value).

(These are dynamic languages,assign the value).
(it will indentify the value,which it wants to).


Arrays:

If you don’t want to write in the square bracket syntax,you can also write:

%w (we can write it by using the %w).
and write three of the variables with spaces.

Note:
Whenever your seeing %w that means,he is giving,array representation of w.
I want to define,details about this package:


Note:
Everytime,you do the irb,your past variables,will not exist anymore.

Irb<main>:008:0>  package_ports  = [“apache2”,8080, “tomcat”,8081, “tree”, “wget”]
(for simplicity of that,we are writing two entries).

“” means those are the strings.

You have to write the program,which will identify the port number of the apache2.

The logic is the:
The postion of our packages name +1.

The problem with this,kind of approach is your assuming conditions.
When you write only the package names in the Array structure,that is the perfect approach.

When you try to mix and match the structure,Array is not meant for  that:
Irb<main>:008:0>  package_ports  = [“apache2”,8080, “tomcat”,8081, “tree”, “wget”]
(for simplicity of that,we are writing two entries).

Array is not mean for the above staructure.
Array means collection of same to you.

It may not be same datatype.

Probably you want to write student names.

If you want to tell more than one thing in the structure:

(hash(= >)  --à is the key value pair.

(hash(= >)  -à  start with the { (curl braces) and ends with the } (curl  braces).

And then you would have a,

{
key = > [(this is the ruby hash) then we have the] value
key1  = >  value1
key2 =  >  value2
key3 =  >  value3
.
.
}

This is the syntax.


If you want to say about the employee

{
  emp.id => 1234
  name => Kaushik
  postion => [“DevOps” , “AWS”, “Bamboo”,”Docker”]
}

I want to write the details of multiple employees.
(whenever I say it is multiple,it is an array).

[{
  emp.id => 1234
  name => Kaushik
  postion => [“DevOps” , “AWS”, “Bamboo”,”Docker”]
}
{
  emp.id => 1235
  name => John
  postion => [“DevOps” , “AWS”, “Bamboo”,”Docker”]
}
{
  emp.id => 1235
  name =>  ricky
}

(now ricky,does not have a postion,then ricky will get a nil/null position).

Example for the employee,using the variable and the key,value structure:


Irb<main>:008:0>   employee =  [ “emp.id” => 1234, “name” => Kaushik , “postion” => [“DevOps” , “AWS”, “Bamboo”,”Docker”]


Irb<main>:008:0>  employee [emp.id]
1234

Irb<main>:008:0>  employee [name]
Kaushik

Whenever,you want to describe about the item,if your trying to describe more than one item,then we will go for the hashes.


We uses the (hashes) in our programming language.

Note:
An hash can contain an array and also array can contain a hash.

We use ruby hashes  ( = > )a lot.

Especially,when we discuss the attributes.

Once,we know,how to write conditions,we discuss about the attributes.

Describe,about some package,when we need to include multiple things.

Array can be multiple items
(An item can be string,Boolean,…).

In hash,

We have a key and value.

Note:

The value of the hash,can be another hash also.
(this is also possible,if your describing about,more complicated).


Example:
If you want to include the address of the employee.

{
  emp.id => 1235
  name => John
  postion => [“DevOps” , “AWS”, “Bamboo”,”Docker”]
  Address = >  {
          “Firstlane” =>  “”,
          “city”     => “”, 
          “state”  => “”,
       }
(the address can be hash also,it can be any datatype.(integer is one way of representing data,array is one way of representing the data)).
what is the property of any hash? => it should have a key and value.
Note:
A value  of a hash can be other hash also.

How to test the hash?
Go to your powershell and
Ø    Facter
Then you will get all the details of the system in the values of the hash (that is the key and value pair).

For example:

I want the system_uptime  (this is the key of the hash).
>>>>>>   facter  system_uptime
              {
                days  => 0,
                 hours  => 1,
                 seconds  => 6291,
                 uptime => “1.44 hours”

whenever you want to use this syntax in the programming language,you have to use this syntax:

>>>>>>   facter[“system_uptime”]
              {
                days  => 0,
                 hours  => 1,
                 seconds  => 6291,
                 uptime => “1.44 hours”
}


if you want to this,in your recipe for some reason.(the above syntax,should be followed).

>>>>>>   facts[“system_uptime”][“days”]
that is stored in to a variable called facts.

Note:

When we type the facter  we get all the information related to the system and that is stored in a variable called the “facts”.
 And after that we are using the hashes syntax to find anything.

Note:
When we type the facter in the linux machine,we get the complete information,related to the machines and this information,we use in our recipes,to add more dynamic nature to the code,this is the use of the hashes.


Example of ,how to use the hash and facts in the chef-recipe:

#cookbook
#Recipe:: tomcat_install

facts[“os”][“name”]


apt_update   ‘update  ubuntu’ do
    action   :update
end

package  ‘tomcat7’  do
    action  :install
end

service ‘tomcat7’ do
   action  :start
end


Note:
We have two recipes and it has same variables,inside the recipes?
In this specific scenario,two recipes will be executing two different memory spaces,so there is no need to worry about this.

Example:
It is like,two programs  having same variables.