procps-ng 3.3.5

Are you using procps 3.3.4?  My suggestion is you don’t!

An API change slipped through which mean if you tried to run procps 3.3.5 on libproc 3.3.4 it did strange things. One of those strange things is ps ax crashes. Top looked rather interesting as well.  This in turn upsets the boot sequence around mounting drives so you get a horrible mess.  The problem is the testsuite didn’t catch it because we’re not testing the API yet and the binaries use the libtool hack to use the library in the build directory.  Lucky for me I only updated manually the binaries and not the library so I saw it early.

procps 3.3.5 was released tonight and it has the SONAME bump ,so we are not at libprocps1 not libprocps0.

Enhanced by Zemanta

More spam from nobistech.net

I get a lot of spam.  Most of it, thankfully is blocked by dspam but occasionally i get some through the filter.  One that particularly caught my eye was interesting not so much what it was advertising (I don’t read that part of the email) but where it came from and goes to.

Normally there are two service providers involved in spam.  The email comes from (or via) one and then the spamvertised website is another.  The interesting thing is for this spam both of these were the same service provider. The email came from 174.34.168.85 and the spamvertised website was 70.32.40.194. Both of these addresses are owned by nobistech.net.  I punted the email to spamcop and it said that they’re not interested in spam reports.

A few google queries shows that these guys seem quite happy to have spam sources and destinations and have been doing it for years.  They either appear as nobistech.net or unbiquity servers but they are one and the same organisation, or at least related.

I won’t bother to send anything to them, it seems this has been done many many times by others with no results. Instead some CIDR blocks will be put into my blacklist.

Enhanced by Zemanta

jqGridWidget in Turbogears

 

 

Turbogears 2 uses Toscawidgets 2 for a series of very clever widgets and base objects that you can use in your projects.  One I have been playing with is the jqGridWidget which uses jquery to display a grid. The idea with jquery is creating a grid or other object and then using javascript to call back to the webserver to obtain the data which usually comes from a database using the very excellent SQLAlchemy framework.

I found it a bit fiddly to get going and it is unforgiving, you get one thing wrong and you end up with an empty grid but when it works, it works very well.

from tw2.jqplugins.jqgrid import jqGridWidget
from tw2.jqplugins.jqgrid.base import word_wrap_css

class ItemsWidget(jqGridWidget):
    def prepare(self):
        self.resources.append(word_wrap_css)
        super(ItemsWidget, self).prepare()
    options = {
            'pager': 'item-list-pager2',
            'url': '/items/jqgrid',
            'datatype': 'json',
            'colNames': ['Date', 'Type', 'Area', 'Description'],

The code above is a snippet of the widget I use to make the graph. This is the visual side of the graph and shows just the  graph with nothing in it.  You need the datatype and url lines in the options which tell the code the url to get the data.  I have an items controller and within it there is a jqgrid method.  Note the number of columns I have, the data sent by the jqgrid method has to match this.

Deep inside the items controller is a jqgrid method. The idea is to return some rows of data back to the grid in the exact way the grid expects it otherwise you get, yep more empty grids.

   @expose('json')
    def jqgrid(self, page=1, rows=30, sidx=1, soid='asc', _search='false',
            searchOper=u'', searchField=u'', searchString=u'', **kw):

        qry = DBSession.query(Item)
        qry = qry.filter()
        qry = qry.order_by()
        result_count = qry.count()
        rows = int(rows)

        offset = (int(page)-1) * rows
        qry = qry.offset(offset).limit(rows)

        records = [{'id': rw.id,
           'cell': [ rw.created.strftime('%d %b %H:%M:%S'), rw.item_type.display_name), rw.display_name, rw.text()]} for rw in qry]
        total = int(math.ceil(result_count / float(rows)))
        return dict(page=int(page), total=total, records=result_count, rows=records)

The four items in the value for the cell in the dictionary must equal the number defined for the colNames.  I found it was useful to have firebug looking at my gets and another widget based upon SQLAjqGridWidget which is a lot simpler to setup but much less flexible too.

 

Enhanced by Zemanta

NTP control messages

I have had an opportunity to rework some code to query NTP servers directly in python rather than running ntpq -pn and scraping the result.  The over-the-wire protocol format is reasonably straight forward and my little module is now passing all of its nosetests which is wonderful.

While its only a single table, ntpq actually does multiple requests to get its results.  NTP control messages are all mode 6 which tells the client and server its not time sort of things, but more about queries. A control packet has a sequence number which the server responds with so you can line up your requests with responses.  For large responses, the more, offset and count fields work together to knit up a large block of data.  The first packet of the response will have the offset field of 0. The count is the size of the data payload in bytes.  If the response is too big, the more bit will be set to 1 to say there is more coming.  The second packet will have an offset that is the same value as the previous packets count value, so you can stitch them together.

The first query is a READSTAT which uses opcode 1.  This returns a list of 4 byte responses with the association ID taking the first two bytes and the peer status taking the second.  If you look at the output of ntpq you will notice a character in the first column which is the peer selection.  The important one for us is asterix, which equates to 110 in the lower 3 bits of the first status byte.  This is the system peer which is the main one. There may be others, up to 2, (usually symbol +) which are compared to the system peer.  ntpq doesn’t really care about the different peers and just displays the status but I want to know what peer the server is synchronised to.

Next we need more details about the system peer (or all peers in ntpq).  To do this a READVAR or opcode 2 is sent to the server. The association ID is set to the association or peer we are interested in.  The response for my setup is sent over two packets which need to be reassembled and it is all in plain ascii which is a comma-separated list with a key=value pair.  I use the following python line to split it up.

self.assoc_data.update(dict([tuple(ad.strip().split("=")) for ad in data[header_len:].split(",") if ad.find("=") > -1]))

I’m sure people that know python better than I will say I am doing it wrong (it looks a bit klunky to me too) but it does work. From that I can query the various values that are returned by the server about its peers, including the source of its clock.

Enhanced by Zemanta

Anti-Spam Fails

A day or two ago I tried sending an email to a friend who happens to use the Road Runner ISP for his mail service.  Now this ISP doesn’t like dynamic IP addresses (using the increasing inaccurately named Dial Up List) so I have to punt the email through my ISP’s mailserver first.  Now that server is telling me this:

The reason for the problem: 4.3.2 – Not accepting messages at this time 554-‘5.7.1 – ERROR: Mail refused – <150.101.137.131> – See http://sendersupport.senderscore.net’

So their ISP mailserver is refusing connections from my ISP’s mailserver for some reason, probably on some spam list.  There’s a URL to look up the problem, so going there gives you three things:

  1. A redirection to https://sendersupport.senderscore.net/
  2. A badly configured webserver that uses the above URL with a certificate for www.senderscore.net
  3. A page that says “It works”

Either Road Runner or Senderscore, preferably both, need to get a clue. Oh and going to https://www.senderscore.net/ gives connection refused. A bit of digging around shows the correct URL is https://senderscore.org/

Now I just realized that my SSL certificate for https://enc.com.au/ expired on the weekend so I know these things can happen, but I’m one person (who was away for a while), why can’t companies get their act together?

Enhanced by Zemanta