Satellite 6 - Listing of hosts with installed package(s)

Latest response

Hi,

for now i must go to every single contenthost to see what package or version of packages are installed.
How can i get a list of hosts who has installed a specific package.

Responses

What version of Satellite are you running?

In Satellite 6.1, this was particularly difficult to do via the UI, and you had to resort to calling the API to get this data. An example is the sat6ShowHostWithPackage.py script.

In Satellite 6.2, you can leverage the improved search capabilities to search for hosts by package, by going to Hosts -> Content Hosts and inputting installed_package = $NAME_VERSION_OF_PACKAGE -> Example:

Image of hosts page

Note: the search fields supports various operators such as > (greater than), < (less than), as well as boolean operators for AND (& or &&), OR (| , or ||), or NOT ( - or ! )

Hi Rich,

i'm still using Satellite 6.1.9.
Thanks for your great script, this helps me a lot.

Hi Guru, I have facing the below error while executing the script. displayMessage "You have not set a default organization on the user admin." errors
0 "You have not set a default organization on the user admin."

this probably won't help... you asked for contenthost... but if you can use a script,

For a match against a single rpm...

#!/bin/bash
package='PUT_NAME_OF_PACKAGE_HERE'
echo -n `hostname -s` ": " `rpm -qa | grep $package`

Push the above through the satellite server.

for a match against a number of packages...

#!/bin/bash
packages=( apache httpd kernel )
for i in ${packages[@]}
  do echo -n `hostname -s` ": " `rpm -qa | grep $i`
done

The output will show the hostname with a full colon character and the list of package(s) matching following the hostname (the first one is a single rpm query, the bottom one is for multiple packages).

I often push scripts such as the above via spacecmd (I suspect hammer in satellite 6 will do the same in some fashion)

@Rich Jerrido, yes this is helpful. can you tell me how to get report with Machine type like physical or virtual ! Example : installed_package > kernel-2.6.18-416.el5.x86_64 and content_view = cv-rhel5 From above how do choose Virtual or physical? Thanks Ram

Virtual or Physical is a system fact, so adding

facts.is_virtual = true or facts.is_virtual = false

to your searches will allow you to include virtual or physical systems (respectively).

Hi,

Here is an example of Python script that collects info for a specific package and sends an email with CSV attachment. It can me easily modified to do much more:

 #!/usr/bin/python

import json
import sys
import ConfigParser
import urllib2
import urllib
import base64
import warnings
import datetime
import smtplib
import glob, os
import time

try:
  import requests
except ImportError:
  print "Please install the python-requests module."
  sys.exit(-1)

defval1 = "" 
defval2 = "" 

mydate = datetime.date.today().strftime("%d%b%Y")
myresults = 'Sat6-installed-packages-{0}.csv'.format(mydate)

# Save report in CSV file
#
tcfile = open(myresults, "w+")

# URL to Satellite 6 server.
#
URL = "https://sat6srv.domain.dom"

# URL for the API to deployed Satellite 6 server.
#
SAT_API = "%s/api/v2/" % URL
SAT_API2 = "%s/api/hosts/" % URL
SAT_API3 = "%s/api/v2/hosts/" % URL

# Katello-specific API
#
KATELLO_API = "%s/katello/api/" % URL
POST_HEADERS = {'content-type': 'application/json'}

# Default credentials to login to Satellite 6.
# Read Satellite API login and password and do not disclose it in the script itself.
#
mydir = "/home/myuser/.config-sat6"
config = ConfigParser.ConfigParser()
config.read(mydir)
USERNAME = config.get("sat6", "username")
PASSWORD = config.get("sat6", "password")

SSL_VERIFY = True

def isNotEmpty(s):
  return bool(s and s.strip())

def get_json(location):
  """
  Performs a GET using the passed URL location
  """
  r = requests.get(location, auth=(USERNAME, PASSWORD), verify=SSL_VERIFY)

  jsn = r.json()
  hosts = jsn['results']
  for host in hosts:
    base64string = base64.encodestring('%s:%s' % (USERNAME, PASSWORD)).strip()
    request = urllib2.Request(SAT_API3 + str(host['name']))
    request.add_header("Authorization", "Basic %s" % base64string)
    result = urllib2.urlopen(request)
    jsonresult = json.load(result)
    request2 = urllib2.Request(SAT_API2 + str(host['id']) + "/packages?per_page=3000")
    request2.add_header("Authorization", "Basic %s" % base64string)
    result2 = urllib2.urlopen(request2)
    jsonresult2 = json.load(result2)

    myinst = ''
    for dataform in jsonresult2['results']:
      if 'MyPackage' in dataform['nvra']:
        myinst = dataform['nvra']
    if isNotEmpty(jsonresult['subscription_facet_attributes']['registered_at']):
      defval1 = jsonresult['subscription_facet_attributes']['registered_at']

    if isNotEmpty(jsonresult['subscription_facet_attributes']['last_checkin']):
      defval2 = jsonresult['subscription_facet_attributes']['last_checkin']

    if isNotEmpty(myinst):
      print >> tcfile, "%s, %s, %s, %s, %s, %s, %s, %s" % (host['name'], jsonresult['operatingsystem_name'], jsonresult['facts']['kernelrelease'],
          jsonresult['facts']['cpu::cpu(s)'], defval1, jsonresult['facts']['uptime'], defval2, myinst )

print >> tcfile, "System,RHEL Release,Kernel,CPU Count,Registration Date,Uptime,Last Checkin to Satellite,Package Installations"

myhosts = get_json(SAT_API + "hosts/?per_page=3000")

tcfile.close()

# Email package modules we need
#
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
from email.mime.base import MIMEBase
from email import encoders

COMMASPACE = ', '

# Create the container (outer) email message
#
msg = MIMEMultipart()
msg['Subject'] = 'SUMMARY: Package status
me = "root@domain.dom "
family = "myroup@domain.dom"
msg['From'] = "me@domain.dom"
msg['To'] = family
msg.preamble = 'Whatever'

# Open the CSV file in binary mode
#
fp = open(myresults, 'rb')
xls = MIMEBase('application','vnd.ms-excel')
xls.set_payload(fp.read())
fp.close()
encoders.encode_base64(xls)
xls.add_header('Content-Disposition', 'attachment', filename=myresults)
msg.attach(xls)

# Send the email via our own SMTP server
#
s = smtplib.SMTP('smptsrv.domain.dom')
s.sendmail(me, family, msg.as_string())
s.quit()

sys.exit()

Regards,

Dusan Baljevic (amateur radio VK2COT)

What if you want to list content hosts that DON'T have a particular package installed? In Satellite 5, all you had to do was click on the package, then there was a tab that showed the name of the server that didn't have the package installed.

That's a simple search query in the UI. On the hosts page, you generally would use a search query similar to installed_package = $NAME_VERSION_OF_PACKAGE. To perform a negative query (thus show systems without a specific version of a package), use:

NOT installed_package = $NAME_VERSION_OF_PACKAGE

Close

Welcome! Check out the Getting Started with Red Hat page for quick tours and guides for common tasks.