Using Ansible Facts to get devices information

8,947 views
Skip to first unread message

Kavin

unread,
Dec 28, 2012, 7:28:40 PM12/28/12
to ansible...@googlegroups.com
Ansible facts, i.e. when i run ansible all -m setup I get all the basic information like the interfaces, IP etc, But i am really interested in also getting disk/partition information and devices attached, Like the information with fdisk  and hdparm/smartctl  will give.

Is there a way i can get those from facts ? If not what would be the right vehicle ? Modify setup.py to get the details needed ?

Brian Coca

unread,
Dec 28, 2012, 7:45:22 PM12/28/12
to ansible...@googlegroups.com

Modifying setup will work, but take into account that this is relied on by default for all plays. I had this at one point (for freebsd), but didn't need it any more and setup has changed a lot since then.

You can also create your own module that adds custom facts.

Brian Coca

Brian Coca

unread,
Dec 28, 2012, 8:03:41 PM12/28/12
to ansible...@googlegroups.com

I just remembered, check the setup module docs, it uses a couple of popular system info gathering utilities if they are installed on the target, they might already get the mount info.

Brian Coca

Kavin Kankeshwar

unread,
Dec 29, 2012, 4:40:12 AM12/29/12
to ansible...@googlegroups.com
It looks like facter/ohai needs ruby installed on remote machines, I wanted something pure python and with least dependencies, So  tried to create a module.

newbie alert ! How to get this module (attached) reviewed /get help ?

I tried to port the disk-info python script to a Ansible module (from little i understand- started reading about Ansible yesterday). I have attached the module here. I would appreciate if i can get some comments on how to improve it , so it follows all the ansible conventions.

The output looks like this:

{'Devices': {'sda': {'vendor': 'ATA', 'sectors': '976773168', 'sector size(bytes)': '512', 'disk type': 'Spinning disk', 'host': 'SATA controller: Intel Corporation 6 Series/C200 Series Chipset Family SATA AHCI Controller (rev 05)', 'sda2': {'holders': {0: 'VolGroup00-LogVol01', 1: 'VolGroup00-LogVol00'}, 'sectors': '975747072', 'start sector': '1026048', 'size': '465.27GiB'}, 'removable': 'No', 'sda1': {'sectors': '1024000', 'start sector': '2048', 'size': '500.00MiB'}, 'support discard': 'No', 'model': 'ST500DM002-1BC14', 'size': '465.76GiB'}, 'sdb': {'vendor': 'ATA', 'sectors': '395093371', 'sector size(bytes)': '512', 'disk type': 'SSD', 'host': 'SATA controller: Intel Corporation 6 Series/C200 Series Chipset Family SATA AHCI Controller (rev 05)', 'removable': 'No', 'support discard': 'Yes', 'model': 'SAMSUNG SSD 830', 'size': '188.40GiB'}, 'sdc': {'vendor': 'ATA', 'sectors': '395093371', 'sector size(bytes)': '512', 'disk type': 'SSD', 'host': 'SATA controller: Intel Corporation 6 Series/C200 Series Chipset Family SATA AHCI Controller (rev 05)', 'removable': 'No', 'support discard': 'Yes', 'model': 'SAMSUNG SSD 830', 'size': '188.40GiB'}}}

 (to get the above result in main of get_devices module, i commented out ansible related stuff and ran as a standalone python script which just printed output of get_devices(module))

Regards,
--
Kavin K

On Fri, Dec 28, 2012 at 5:03 PM, Brian Coca <bria...@gmail.com> wrote:

I just remembered, check the setup module docs, it uses a couple of popular system info gathering utilities if they are installed on the target, they might already get the mount info.

Brian Coca

--
 
 

get_devices

Kavin

unread,
Dec 29, 2012, 5:04:08 AM12/29/12
to ansible...@googlegroups.com
I guess cannot attach file: uploaded it here:



On Saturday, December 29, 2012 1:40:12 AM UTC-8, Kavin wrote:
It looks like facter/ohai needs ruby installed on remote machines, I wanted something pure python and with least dependencies, So  tried to create a module.

newbie alert ! How to get this module (attached) reviewed /get help ?

I tried to port the disk-info python script to a Ansible module (from little i understand- started reading about Ansible yesterday). I have attached the module here. I would appreciate if i can get some comments on how to improve it , so it follows all the ansible conventions.

The output looks like this:

{'Devices': {'sda': {'vendor': 'ATA', 'sectors': '976773168', 'sector size(bytes)': '512', 'disk type': 'Spinning disk', 'host': 'SATA controller: Intel Corporation 6 Series/C200 Series Chipset Family SATA AHCI Controller (rev 05)', 'sda2': {'holders': {0: 'VolGroup00-LogVol01', 1: 'VolGroup00-LogVol00'}, 'sectors': '975747072', 'start sector': '1026048', 'size': '465.27GiB'}, 'removable': 'No', 'sda1': {'sectors': '1024000', 'start sector': '2048', 'size': '500.00MiB'}, 'support discard': 'No', 'model': 'ST500DM002-1BC14', 'size': '465.76GiB'}, 'sdb': {'vendor': 'ATA', 'sectors': '395093371', 'sector size(bytes)': '512', 'disk type': 'SSD', 'host': 'SATA controller: Intel Corporation 6 Series/C200 Series Chipset Family SATA AHCI Controller (rev 05)', 'removable': 'No', 'support discard': 'Yes', 'model': 'SAMSUNG SSD 830', 'size': '188.40GiB'}, 'sdc': {'vendor': 'ATA', 'sectors': '395093371', 'sector size(bytes)': '512', 'disk type': 'SSD', 'host': 'SATA controller: Intel Corporation 6 Series/C200 Series Chipset Family SATA AHCI Controller (rev 05)', 'removable': 'No', 'support discard': 'Yes', 'model': 'SAMSUNG SSD 830', 'size': '188.40GiB'}}}

 (to get the above result in main of get_devices module, i commented out ansible related stuff and ran as a standalone python script which just printed output of get_devices(module))

Regards,
--
Kavin K

James Martin

unread,
Dec 29, 2012, 9:13:20 AM12/29/12
to ansible...@googlegroups.com
On Sat, Dec 29, 2012 at 4:40 AM, Kavin Kankeshwar <ka...@aerospike.com> wrote:
It looks like facter/ohai needs ruby installed on remote machines, I wanted something pure python and with least dependencies, So  tried to create a module.

newbie alert ! How to get this module (attached) reviewed /get help ?


The way I understand it is that you put your module data in a dict named ansible_facts and return it , like this:

    ansible_facts['riak_primary_node'] = host_list[0]
    ansible_facts['riak_last_node'] = host_list[-1]
    ansible_facts['riak_node_count'] = len(host_list)
    changed = True

    result = {"changed": changed,
              "ansible_facts": ansible_facts }
    module.exit_json(**result)

Then from your module you can directly access your custom facts like:

$riak_primary_node
$riak_node_count

etc.

This is all documented http://ansible.cc/docs/moduledev.htm under "Module Provided 'Facts'.

- James

 
I tried to port the disk-info python script to a Ansible module (from little i understand- started reading about Ansible yesterday). I have attached the module here. I would appreciate if i can get some comments on how to improve it , so it follows all the ansible conventions.

The output looks like this:

{'Devices': {'sda': {'vendor': 'ATA', 'sectors': '976773168', 'sector size(bytes)': '512', 'disk type': 'Spinning disk', 'host': 'SATA controller: Intel Corporation 6 Series/C200 Series Chipset Family SATA AHCI Controller (rev 05)', 'sda2': {'holders': {0: 'VolGroup00-LogVol01', 1: 'VolGroup00-LogVol00'}, 'sectors': '975747072', 'start sector': '1026048', 'size': '465.27GiB'}, 'removable': 'No', 'sda1': {'sectors': '1024000', 'start sector': '2048', 'size': '500.00MiB'}, 'support discard': 'No', 'model': 'ST500DM002-1BC14', 'size': '465.76GiB'}, 'sdb': {'vendor': 'ATA', 'sectors': '395093371', 'sector size(bytes)': '512', 'disk type': 'SSD', 'host': 'SATA controller: Intel Corporation 6 Series/C200 Series Chipset Family SATA AHCI Controller (rev 05)', 'removable': 'No', 'support discard': 'Yes', 'model': 'SAMSUNG SSD 830', 'size': '188.40GiB'}, 'sdc': {'vendor': 'ATA', 'sectors': '395093371', 'sector size(bytes)': '512', 'disk type': 'SSD', 'host': 'SATA controller: Intel Corporation 6 Series/C200 Series Chipset Family SATA AHCI Controller (rev 05)', 'removable': 'No', 'support discard': 'Yes', 'model': 'SAMSUNG SSD 830', 'size': '188.40GiB'}}}

 (to get the above result in main of get_devices module, i commented out ansible related stuff and ran as a standalone python script which just printed output of get_devices(module))

Regards,
--
Kavin K

On Fri, Dec 28, 2012 at 5:03 PM, Brian Coca <bria...@gmail.com> wrote:

I just remembered, check the setup module docs, it uses a couple of popular system info gathering utilities if they are installed on the target, they might already get the mount info.

Brian Coca

--
 
 

--
 
 

Michael DeHaan

unread,
Dec 29, 2012, 12:48:31 PM12/29/12
to ansible...@googlegroups.com
On Sat, Dec 29, 2012 at 9:13 AM, James Martin <james.s...@gmail.com> wrote:
> On Sat, Dec 29, 2012 at 4:40 AM, Kavin Kankeshwar <ka...@aerospike.com>
> wrote:
>>
>> It looks like facter/ohai needs ruby installed on remote machines, I
>> wanted something pure python and with least dependencies, So tried to
>> create a module.
>>
>> newbie alert ! How to get this module (attached) reviewed /get help ?
>>
>
> The way I understand it is that you put your module data in a dict named
> ansible_facts and return it , like this:
>
> ansible_facts['riak_primary_node'] = host_list[0]
> ansible_facts['riak_last_node'] = host_list[-1]
> ansible_facts['riak_node_count'] = len(host_list)
> changed = True
>
> result = {"changed": changed,
> "ansible_facts": ansible_facts }
> module.exit_json(**result)

This is super minor, but I figured I'd share... there's no need to
return a 'changed' attribute in a facts module.

A changed = True/False only is really useful if you have a 'notify'
hanging off of the task and the module makes changes to the underlying
system.

It implies that the module has actually /changed/ the underlying
system, so you wouldn't want to return it unless that were actually
the case.

--Michael

Brian Coca

unread,
Dec 29, 2012, 1:52:46 PM12/29/12
to ansible...@googlegroups.com
2 small changes, added a path to lspci and made it non critical if it
isn't isntalled.

pcidata = None
try:
p = Popen(["/usr/sbin/lspci"], stdout=PIPE)
err = p.wait()
if err:
print "Error running lspci"
else:
pcidata = p.stdout.read()
except OSError:
pass # no lspci

works nicely for me now

--
Brian Coca
Stultorum infinitus est numerus
0110000101110010011001010110111000100111011101000010000001111001011011110111010100100000011100110110110101100001011100100111010000100001
Pedo mellon a minno

Kavin Kankeshwar

unread,
Dec 29, 2012, 3:21:12 PM12/29/12
to ansible...@googlegroups.com
Thanks for all the feedback,  On my Centos 6.3 machine lspci is located in /sbin/lspci
So i changed it to:

    pcidata = None
    try:
        try:
            p = Popen(["/sbin/lspci"], stdout=PIPE)
        except:
            try:
                p = Popen(["/usr/sbin/lspci"], stdout=PIPE)
            except:
                p = Popen(["lspci"], stdout=PIPE)
        err = p.wait()
        if err:
            print "Error running lspci"
        else:
            pcidata = p.stdout.read()
    except OSError, e:
        module.fail_json( msg="lspci failed %s" % e) # no lspci


This is the modified code based on the feedback received, Let me know if i can make it better .

Out put:

s2 | success >> {
    "ansible_facts": {
        "device_details": {
            "sda": {
                "disk type": "Spinning disk", 
                "host": "SATA controller: Intel Corporation 6 Series/C200 Series Chipset Family SATA AHCI Controller (rev 05)", 
                "model": "ST500DM002-1BC14", 
                "removable": "No", 
                "sda1": {
                    "sectors": "1024000", 
                    "size": "500.00MiB", 
                    "start sector": "2048"
                }, 
                "sda2": {
                    "holders": [
                        "VolGroup00-LogVol01", 
                        "VolGroup00-LogVol00"
                    ], 
                    "sectors": "975747072", 
                    "size": "465.27GiB", 
                    "start sector": "1026048"
                }, 
                "sector size(bytes)": "512", 
                "sectors": "976773168", 
                "size": "465.76GiB", 
                "support discard": "No", 
                "vendor": "ATA"
            }, 
            "sdb": {
                "disk type": "SSD", 
                "host": "SATA controller: Intel Corporation 6 Series/C200 Series Chipset Family SATA AHCI Controller (rev 05)", 
                "model": "SAMSUNG SSD 830", 
                "removable": "No", 
                "sector size(bytes)": "512", 
                "sectors": "395093371", 
                "size": "188.40GiB", 
                "support discard": "Yes", 
                "vendor": "ATA"
            }, 
            "sdc": {
                "disk type": "SSD", 
                "host": "SATA controller: Intel Corporation 6 Series/C200 Series Chipset Family SATA AHCI Controller (rev 05)", 
                "model": "SAMSUNG SSD 830", 
                "removable": "No", 
                "sector size(bytes)": "512", 
                "sectors": "395093371", 
                "size": "188.40GiB", 
                "support discard": "Yes", 
                "vendor": "ATA"
            }
        }, 
        "devices": [
            "sda", 
            "sdb", 
            "sdc"
        ]
    }, 
    "changed": false
}


Regards,
--
Kavin Kankeshwar



--



Michael DeHaan

unread,
Dec 29, 2012, 4:19:21 PM12/29/12
to ansible...@googlegroups.com
Small request.

For those sharing larger pieces of files on this mailing list, I'd
recommend using something like github's gist versus a file download
site like filepicker.

It's much easier to tell what you are looking at before you download
something potentially unsafe.

Pastebin is somewhat less tolerable as content tends to expire.
> --
>
>

Brian Coca

unread,
Dec 29, 2012, 5:38:10 PM12/29/12
to ansible...@googlegroups.com
A small patch that puts partitions in their own key and also adds
mount information

--- Downloads/get_devices 2012-12-29 17:36:50.162819361 -0500
+++ get_devices 2012-12-29 17:37:07.014825267 -0500
@@ -278,6 +278,18 @@
a_devices= {}
device_names=[]
dd={}
+
+ mounts = {}
+
+ try:
+ mtab = open('/etc/mtab')
+ for line in mtab.readlines():
+ if line.startswith('/'):
+ fields = line.rstrip('\n').split(' ')
+ mounts[os.path.basename(fields[0])] = { 'mount':
fields[1], 'fstype' : fields[2], 'mount_opts': fields[3] }
+ except IOError, e:
+ module.fail_json( msg="failed to open mtab: %s" % e)
+
for d in devices:
k={}
k['host']= d.host
@@ -298,8 +310,11 @@
kk.append(h)
k['holders']=kk
if len(d.partitions) > 0:
+ k['partitions'] = {}
for p in d.partitions:
kk1={}
+ if p.diskname in mounts:
+ kk1 = mounts[p.diskname]
kk1['start sector']=p.start
kk1['sectors']=p.sectors
size = float(p.sectors) * float(d.sectorsize)
@@ -311,9 +326,8 @@
for h in p.holders:
kk2.append(h)
kk1['holders']=kk2
-
- k[p.diskname]=kk1
- dd[d.diskname]=k
+ k['partitions'][p.diskname]=kk1
+ dd[d.diskname] = k
device_names.append(d.diskname)
a_devices['devices']=device_names
a_devices['device_details']=dd

On Sat, Dec 29, 2012 at 3:21 PM, Kavin Kankeshwar <ka...@aerospike.com> wrote:
> --

Kavin Kankeshwar

unread,
Dec 30, 2012, 4:00:49 AM12/30/12
to ansible...@googlegroups.com
Thanks for all the help, Sorry about sending files to the group...


Now I also get the scheduler-mode for the devices.

Regards,
--
Kavin Kankeshwar


--



Stephen Fromm

unread,
Dec 31, 2012, 11:57:17 AM12/31/12
to ansible...@googlegroups.com
You may find get_bin_path() in module_common.py useful when searching for the full path to lcpsi:



sf

Brian Coca

unread,
Dec 31, 2012, 12:06:06 PM12/31/12
to ansible...@googlegroups.com
i had a minor version of this hacked into setup, should I attempt to
put this version in (under linux facts)? I would also add a freeBSD
version

Michael DeHaan

unread,
Dec 31, 2012, 12:24:40 PM12/31/12
to ansible...@googlegroups.com
On Mon, Dec 31, 2012 at 12:06 PM, Brian Coca <bria...@gmail.com> wrote:
> i had a minor version of this hacked into setup, should I attempt to
> put this version in (under linux facts)? I would also add a freeBSD
> version

Sounds good!

--Michael

>
>
> --
> Brian Coca
> Stultorum infinitus est numerus
> 0110000101110010011001010110111000100111011101000010000001111001011011110111010100100000011100110110110101100001011100100111010000100001
> Pedo mellon a minno
>
> --
>
>
Reply all
Reply to author
Forward
0 new messages