Tuesday, October 20, 2009

Weather monitor for Ion3 statusbar

Recently with the effort of this guy i switch my desktop window manager from XFCE to a tiling expirience of ion3. So far so good, however the weather monitor i wanted to add to my status bar was somehow broken. A bit of messing with lua scrips and i managed to get it working:
  1
  2 local weather_timer = statusd.create_timer()
  3
  4 local defaults = {
  5   update_interval = 15 * 60 * 1000,
  6   unit = {
  7     tempC = "°",
  8     tempF = "F",
  9     humidity = "%",
 10     pressure = "hPa",
 11     windspeed = "MPH",
 12   },
 13   important = {
 14     tempC = 10,
 15     tempF = 50,
 16     windspeed = 5,
 17     humidity = 30,
 18   },
 19   critical = {
 20     tempC = 26,
 21     tempF = 78,
 22     windspeed = 20,
 23     humidity = 90,
 24   },
 25 }
 26
 27 local url = "http://weather.noaa.gov/pub/data/observations/metar/decoded/"
 28
 29 local data = {
 30   timezone = tonumber(os.date("%z")),
 31 }
 32
 33 local raw_data
 34
 35 local settings = table.join(statusd.get_config("weather"), defaults)
 36
 37 local function get_weather()
 38   local command = "/usr/bin/curl -s"..url..settings.station..".TXT"
 39   f = io.popen(command)
 40   raw_data = f:read("*all")
 41   f:close()
 42 end
 43
 44 local function process_data()
 45   local s = raw_data
 46   _, _, data.location, data.country = string.find(s, "^(.+)%,%s(.+)%(%u+%)" )
 47   _, _, data.date, data.time = string.find(s, ".+%/%s([%d.]+)%s(%d+)%sUTC" )
 48   _, _, data.wind, data.windspeed =
 49   string.find(s, "Wind%:%s(.+%sat%s(%d+)%sMPH)" )
 50   _, _, data.sky = string.find(s, "Sky%sconditions:%s(.-)%c" )
 51   _, _, data.tempF, data.tempC =
 52   string.find(s, "Temperature:%s([%d%.]+)%sF%s%(([%d%.]+)%sC%)%c" )
 53   _, _, data.dewpointF, data.dewpointC =
 54   string.find(s, "Dew%sPoint:%s([%d%.]+)%sF%s%(([%d%.]+)%sC%)" )
 55   _, _, data.humidity = string.find(s, "Relative%sHumidity:%s(%d+)%%")
 56   _, _, data.pressure = string.find(s, "Pressure%s.+%((.+)%shPa%)" )
 57   _, _, data.weather = string.find(s, "Weather:%s(.-)%c" )
 58   format_time()
 59 end
 60
 61 function format_time()
 62   local time
 63   if data.time then
 64     time = tonumber(data.time) + tonumber(data.timezone)
 65   else return
 66   end
 67   if time > 2400 then
 68     time = tostring(time - 2400)
 69   end
 70   if string.match(time, "^%d%d$") then
 71     time = "00"..time
 72   end
 73   if string.match(time, "^%d%d%d$") then
 74     time = "0"..time
 75   end
 76   data.time = tostring(time):gsub("(%d%d)(%d%d)","%1%:%2")
 77 end
 78
 79 local function get_hint(meter, val)
 80   local hint = "normal"
 81   local crit = settings.critical[meter]
 82   local imp = settings.important[meter]
 83   if crit and tonumber(val) > crit then
 84     hint = "critical"
 85   elseif imp and tonumber(val) > imp then
 86     hint = "important"
 87   end
 88   return hint
 89 end
 90
 91 -- get the unit of each meter
 92 local function get_unit(meter)
 93   local unit = settings.unit[meter]
 94   if unit then return unit end
 95   return ""
 96 end
 97
 98 -- update information for statusd
 99 local function notify()
100   for i,v in pairs(data) do
101     statusd.inform("weather_"..i.."_"..settings.station.."_hint", get_hint(i, v))
102     statusd.inform("weather_"..i.."_hint", get_hint(i, v))
103     if not v then v = "N/A" end
104     statusd.inform("weather_"..i.."_"..settings.station, v..get_unit(i))
105     statusd.inform("weather_"..i, v..get_unit(i))
106   end
107 end
108
109
110 local function run()
111       get_weather()
112       process_data()
113       notify()
114       weather_timer:set(settings.update_interval, run)
115 end
116
117 run()
118
119 -- EOF

Wednesday, August 19, 2009

Express HOWTO: Ubuntu + Software RAID5 network install from BootP/TFTP

Given:
A server with 3 SATA HDD to setup a RAID5 storage.


Setup TFTP server.

sudo apt-get install bootp tftpd-hpa

sudo vim /etc/xinet.d/bootp

service bootps
{
disable = no
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/bootpd
server_args = -i /etc/bootptab
}

sudo vim /etc/xinet.d/tftpd

oleksiy@odin:/etc/xinetd.d$ cat tftp
service tftp
{
protocol = udp
port = 69
socket_type = dgram
wait = yes
user = nobody
server = /usr/sbin/in.tftpd
server_args = /tftpboot
disable = no
}

sudo vim /etc/bootptab

client:\
hd=/tftpboot:\
bf=pxelinux.0:\
ip=host_ip_addr:\
sm=255.255.255.0:\
sa=tftpsrv_ip_addr:\
ha=host_hw_addr:

sudo /etc/init.d/xinetd restart

sudo mkdir /tftproot

sudo chmod +rx /tftproot

cd /tftproot

wget http://archive.ubuntu.com/ubuntu/dists/karmic/main/installer-i386/current/images/netboot/netboot.tar.gz

tar xfz netboot.tar.gz


boot up the server:

check what PXE boot is enables
the server suppose to start booting.
go through configuration process
when comes partitioning do it manually:
for each drive create 2 partitions: i.e. 100Mb for /boot and the rest. Mark a /dev/sda1 as /root and the rest as 'do not use', go on. Hit Alt+F2, run:

mdadm --create --verbose /dev/md0 --level=1 --raid-devices=3 /dev/sda1 /dev/sdb1 /dev/sdc1
mdadm --create --verbose /dev/md0 --level=5 --raid-devices=3 /dev/sda5 /dev/sdb5 /dev/sdc5


back to the installation process Alt+F1, go couple of steps back to Drive Detection. remove /root mounting point form /dev/sda1. Set the mounting point of /dev/md0 as /boot (at least /boot should be there). Create LVM from /dev/md1 and partition it as you want (at least root, /home, swap).

Proceed with installation.

Friday, April 11, 2008

Go public!

The Sweet Child of Mine:
Ganeti Remote API (first public leak)

Thursday, April 10, 2008

Python stack inspection

Sometimes function curious to know who is made the call.

1 #!/usr/bin/python
2
3 import inspect
4
5 def f1():
6 stack = inspect.stack()
7 for level in stack:
8 print level[0].f_code.co_name
9
10 def f2():
11 f1()
12
13 def f3():
14 f2()
15
16 def f4():
17 f3()
18
19 def f5():
20 f4()
21
22 f5()


The output would be something like this:

f1
f2
f3
f4
f5
...

Tuesday, April 8, 2008

Map networt port to PID in Python for Linux.

Cheap and dirty. It's not suppose to be perfect, just an idea. I hate to run external programs (i.e. netstat -lpn) from Python. The batteries included!!! The root privileges and procfs is necessary to run, sorry there is no miracles in this world.


1 #!/usr/bin/python2.4
2 #
3 """Map port to PID.
4
5 """
6
7 __author__ = 'amishchenko(at)gmail.com'
8
9 import glob
10 import os
11
12 _NET_STAT = ['/proc/net/tcp','/proc/net/udp']
13
14 inode2port = {}
15 port2pid = {}
16
17 for file in _NET_STAT:
18 try:
19 for line in open(file).readlines()[1:]:
20 d = line.split()
21 inode2port[long(d[9])] = int(d[1].split(':')[1], 16)
22 except:
23 pass
24
25 fdlist = glob.glob('/proc/*/fd/*')
26 for fd in fdlist:
27 try:
28 pid = int(fd.split('/')[2])
29 inode = long(os.stat(fd)[1])
30 if inode in inode2port:
31 port2pid[inode2port[inode]] = pid
32 except:
33 pass
34
35 print port2pid