Conditions and iterations:
Whenever you write :install (it is something termed as
symbol with Ruby).
(only Ruby has the concept of symbol).
With strings,what is the problem, the memory management is
the complicated one.
(with ruby,we can reduce that issue).
Note:
Ruby maintain,there own cache.
Ruby do the management of dynamic memory allocation.
When we use this :install
instead of this “install”
Value wise,there is
no difference,wherever it is suggested,but the storage wise and alogarithm
wise,symbol is better
Note:
Problem with the symbol is,symbol once assigned to a
variable cannot be changed.
(memory allocation,whatever you give,it will try to reuse
it),which does not happened.
Example:
I have created a
symbol called the :install (representation of symbol in ruby),now we have used
the variable and now we want to change its value.still no problem we can change
it,but the install memory allocation/location,which has been created,it will
try to see the,if any other ruby program asking for it.(it will try to give
from cache,rather than creating).
In most of the
cases,we will be writing:
Action :install
Action :start
(these everything,made as a symbol and these are reused).
(There wil not be a
new memory always).
Note:
If your looking for
values,that is the rubies way of doing it.
(ruby has a efficient
way of looking at things).
But,from the development perspective of the chef,it is no
different than string,creating that in the double quotes or the single quotes.
Value wise,there is no difference.
Symbol is nothing but a string.
Whenever you write
programming,you write steps of instructions:
(it will execute in the order you have written it).
There are situations,you want to execute,some in one case
and some in other case.
For example,
In case of banking withdrawal.
Depositing the amount from one account to another account.
While writing configuration management,there will be many
scenarios.
We should have a sequential flow and at the same time,it
should know what to execute and what to skip.
Ruby scenario:
Goal : apache webserver:
Package
‘apache2’ do
Action :install
End
Package ‘httpd’ do
Action :install
End
(is there ,any case,where we need to execute both the
statements).
You will execute either one of them,how to control it?
For example:
If you take the facter command (the complete information is
assigned to a variable) = facts.
And from there we will access the data through array
representation.
To make,this kind of
decisions,we would be using the conditions:
There are two kinds of conditions broadly:
That is if and other
one Is unless.
The basic syntax of if is :
In if you write some ruby expression,if return true or
false.
If <ruby
expression>
End
You written,in this one code.
If <ruby
expression>
<code>
End
Whatever written will
be executed,if your expression returns true.
Unless <ruby expression>
<code>
End
Whatever written will
be executed,if your expression returns false.
Unless = notif or ifnot
If node = Ubuntu
Then execute this.
If node is not equal to Ubuntu (unless)
Then execute this
Basically,when we use if or unless,where we have the
scenario always only one condition right.
Let us example,that I have to do the separate installation
for Ubuntu 14.04,Ubuntu 16 and Ubuntu 12.
I have three conditions.
I have to make decision,out of three.
And that may come,another operating system,either of this
three.
There are four
conditions,which I need to write:
One is for Ubuntu 12
Another one is Ubuntu 14,16 and any other thing,we are not
going to execute this.
In this case,your building something called ladders.
Lets us
assume,operating system in a variable
called as OS.
If osname==
“ubuntu12”
<code1>
elsif osname ==
“ubuntu14” (whenever you writing elseif in ruby,you wont see ‘e’ in ruby).
(incase of python,it is elif).
<code2>
elsif osname == “ubuntu16”
<code3>
(Purpose:if you have
more than two conditions,we have to go for elsif).
(if you have only two
conditions If and unless).
end
Better ways of doing
this,write a case statements: (very rarely we use this).
Case statement is a switch statement in `C`.
In `c` it is switch and variable.
Array and hashs:
What is an Array?
Array is datatype,which is capable of holding multiple data.
(In other languages:multiple homogeneous data,belonging to
the same datatype).
In the case of
ruby,that is not the case:
It Is multiple objects (that may be numbers,strings and
whatever may be).
Whenever you look at the data in an array,
Like if we have four
positions in an array:
Myarray (0) gives the first position.
(if I want a specify item,we will be using that).
What if ,if I want to
do for every package,I want to install?
Package_name =
[“apache”,”tomcat”,”tree”]
I have been asked to install these three packages.
Today,the value of this is 3 and tomorrow may be 4,size may
increase.
So,I cannot write multiple package statements.
Basically,we will use
the ruby block of statements.
Package_names.each do
|here we will define the variable name|
In the first
iteration,the value will be `apache`
(mypackname during the first iteration will be apache).
During the second iterations,the value will be tomcat.
During the third iteration,the value will be tree.
(we will use this syntax,to write the code block).
(it will iterate and in every iterate,it will give you the
value).
(it will start from 0th position).
Package_names.each do |my
packname|
Action
:install
End
End
(I have written,which
executes mypackname thrice).
(nothing but a
simple `For loop`).
You also have a `For loop` in ruby
For example,if it is an Array wonderful.
Package_details=
{
name => “apache2”,
version =>
“14”
}
if you want to iterate,through a hash.
Package_details.each do |
k,v |
Echo
k,v
End
(Actually,we can
iterate through hashes also).
(it is just indexing
by a position).
Note:
(here,we are getting
two variable,incase of array,we have one).
Name will be part of
key
Value will be part of
v.
(what are the possible values,you get in every iteration,you
get a key and value).
Chef generate cookbook
< name of the cookbook>
Chef generate cookbook
variables_demo
(it will create the cookbook,with basic boilerplate).
Metadata.rb
(this is the place where,you write the details about the
cookbook).
(We know that,if you use the resource package,we can install
the packages depending upon the system).
(what will be installed,in that we will give as an
variable).
Basically,the variable name initially is:
Package_to_be_installed = “tomcat”
Package ‘Package_to_be_installed do
Action :install
End
Problem:I have to change this code,everytime,to change the
variable value.
(I want variable value to be changing,depending upon the
flavor of the operating system)
(for example,the value for the ubutnu to be tomcat7 and for
the centos it will be tomcat,depending upon the os the variable has to be
changing,what is the solution for that?)
Incase of redhat
machines
(I want to basically
installed httpd).
To get that,if we use
the:
Node [‘os’] --à this will give us the
hash.what the `facter os` does.
Let us execute the same command in the linux machine and see
what happens:
(let us find out,what is the node statement,we have to
write,to find out,whether it is the Ubuntu/centos or any other kind of
operating system).
Whatever the command ‘facter’ we are using in the windows
and it is different in the linux virtual machines.
Don’t assign the structure,what is written in the
windows,always it is suggested to
execute facter,atleast the os where you want to execute.
Example,if I want to
execute on the redhat.
(from redhat and Ubuntu,you don’t see any structural
changes).
(but from windows to linux,you see the structural changes
and next to mac,there will be some changes).
Example:when you type
facter in the linux machines,what happends?
Ubuntu@ip :-$ sudo –i
root@ip :-$ facter
The program ‘facter’ is currently not installed.you can
install it by
Apt-get install facter
(this is the
problem,because,we did not installed chefdk).
Example:
Node [kernel] [name]
Chef server > goto specific node >
attributes > kernel > name:linux
(this is the multi structured).
(if one to access,other things ,I need to use the
node [structure]
(node [structure] is technically called is node[object]).
Which is every important,during the chef.
Incase,even in the
ansible.
We have a section called the gatherfacts.
In every,configuration management tool,server will try to
maintain.details about your node.
(every tool,will have its own way of looking at it).
Incase of chef,we
called it as Node object
Note:
Node object contains details of,all of the possible.details
about the system.
It will also,tells about the network,what are the network
interfaces we have:
Eth0 basically and what is io?
And what different values,which you have and possible address which you have.
Note:
Everything,it will try to maintain:
(this details,will be given by your server,by a command line
utility called the facter).
When you install chefdk,facter will be in working,but that
is not the,when you use the knife).
We have to write
something,which I have to be worked,based out of family:
(That is the debian
family or redhat family).
So,you will be using the
platform_family
In my code,I will be
writing/adding:
Previous code:
Node [`os`]
Package_to_be_installed = “tomcat”
Package ‘Package_to_be_installed do
Action :install
End
Modified code(according to the family,it has to install the
packages):
Node [`os`]
If node[‘platform’] =
= “Ubuntu”
Package_to_be_installed = “apache2”
Elsif
node[‘platform’] = = “redhat”
Package_to_be_installed = “httpd”
End
Note:
(the problem which I
said,still exists,because,this is a variable and the value of it,your writing
it,very much near to the code and to read this value,what has to be the
decision.decision is taken where you have the code,straightly and it is
dependent where your code is).
(Anytime,your
changing here,is as good as code).
For example:
I tried to install
the tomcat,changing apache to tomcat.everytime,what I am trying,I am trying to
change the file,where the code is present.
(so,it Is as good as
code change right).
Note:
We should,look at the options,where this kind,variable
assignment where this kind of variable assignment,should not present in the
recipes,there should be present somewhere.
And our recipes,should try to use that,rather than,basically,defining
the values over there.
Steps,how we have
written the packages,using the variables in different styles:
First trial:
First thing,what we have written,we have written a logic for
installation.we used package.
Second trial:
After that,what is my responsilibilty to make it,good,what I
did is,I made in to a variable.
Variables has two ways of possibilities,I have written
the `if`
statement.
The problem,with the
above two approaches:
We have data and the code at the same place.
Which is always,does not seems to be good.
Our code,should access the data,always from the same place.
So,basically,whenever I changed the data and execute the code
again and again.
It requires execution and no compilation required.
So,it will work,even
with different values.
(this is different kind
of variable value assignments).
Don’t keep code and
data in same place.(whenever your coding,there should be independent of
eachother).
Thereshould be a
places,where we should write,for code and data separately.
This thought in chef,gave a new concept called attribute.
Attribute exactly
solves this problem.
What is an attribute?
The place,where you define your variables.
Rather than,using and writing like this,you would write this
parts,where you have the variable and defintions in other folder/in some other
file.
For generating the
attributes:
>>>>>>>>>>>>>>>>>>>>>>>
chef generate attribute . default
(what happens,there is a new folder,which is called
attributes and a new file is generated is called the default file).
Any variables,will be
moving to this.
(this attributes,we can set it,independent of the code). >>>>> this is the first step.
First thing is,write a variable in your code itself and
second try it,whether you can access this from the external file or not.
You might not able to,some times it is a intermediate
variable/sometimes we can set this value from the external world.
For example:
The return part,which comes out of the first part,if you
want to use that as a attribute,you cannot able to do that.
But the value,which you set to the package,you can able to
do that.
For writing values to
that attribute:
There is an
syntax,which we need to follow:
Attribute is a place
where,where we can set all our variable,which is related to the cookbook.
Attribute is a place
where,where we define the variables,which acts as a variables in the cookbook.
-------------------------------------------------------------------------------------------------------------
Default.rb (attributes)
Generally the first
thing,you write in most of the cases is
the cookbookname.
Description:
[ Default [‘cookbookname’] [‘name of the variable’].value
(packagename:why do we want to write a variable
name,because,which can hold the packages name)
[(packagename à this is going to be our variable,to this,we will set our
value).]
Default [‘variables_demo’] [‘packagename’] =”apache2”
Default [‘variables_demo’] [‘servicename’] =”apache2”
Note:
Generally,we wont define two variables.
#Cookbookname:: variables_demo
#recipe ::Default.
***Whenever you want
to access any attribute,we have to write
node []
Package node [‘variables_demo’]
[‘packagename’] do
Action :install
End
Service node [‘variables_demo’] [‘servicename’] do
Action :start
End
[**I want to start the service
generally the service name and package
name will be equal in 99% of cases.]
Node > attributes
>> consists of two things,one the attributes define by you and second is
the attributes fetched by the facter.
Basically,you can
try to define attributes also. (Edit node attributes) and wait for the next
convergence.
Attributes
contain,what we write in the default.rb and it also contain the,whatever the
facter writtens,
[facter variables + whatever we written in the attribute files]
>>> (combined) >> sent back to the chef server.
Whenever we speak of attributes,there
are two things:
1)fetched from the facter.
2)the attributes,defined in cookbooks.
(we can see these all the details in
the node > attributes).
One layer deeper and see what happens:
****Chef is a push model
During converegence time:
chef
server <<<< ======== chef node
(chef
node,will basically question(communicate) with the chef-server,is there
anything new to do?)
Description:
For
example,this is the cookbook,we have changed and we have uploaded to the
server,the server,yes there is a new cookbook called XXX and we have to apply
that and that also will be added to the run_list.basically as a result of
that,that cookbook,it will be executed over there.
And that
contains our attributes and the chef node have a facter,so the facter will be
executed,and attributes are read and those two things are combined and there is
some alogarithm that executes and chef server returns back,something called as node objects,exactly that node objects,we
are trying to access is called node[].
Node [platform] right,that means your
trying to access the node object.
(that is nothing but the,variables
defined you + variables/facts of our node/operating system/wherever your
running your stuff).
For example:
If you want
to execute the script,that is free memory above 1GB.
(you have the
info from the facts/node object which contains all these information).
There are 16 precendence levels,that
we need to understand.
Because the
variables,whatever we defined in the attributes section,with the same I can define in different places,
Note:
While defining,you will define as
default[] (that is in the attributes
folder and in the default file).
While your using that,you defined as
node[] (that is in the recipes foler and for the default.rb file).
Note:
Default [‘variables_demo’] [‘packagename’] =”apache2”
If you want to install tomcat
instead of apache2,just change the value from apache2 to tomcat,here your not
touching anything of the code.
I can override,these values from
multiple places.
This makes it simple,my code is
not effected,with the variable changes.
If you understand the attributes and
attributes precendences,we can easily understand the roles and environments and
we have the section called as databags.
writing recipes (for this you require
resources).
No comments:
Post a Comment