Posted by Dan Sosedoff
on January 30, 2009
Since i completely switched to ubuntu 8.04 on my laptop i got very weird “click” sounds from hard drive. I thought it was just a simple “sleep” mode, parking heads or something pretty simple. But that sound began to appear so often (sometimes 2 clicks in 1 secons) that i cant even get sleep with that disturbing sound.. But that sound appeared only in ubuntu and never heard it in other os. Wtf is going on? After googling for a short time i figured out what was the problem – Advanced Power Management in Ubuntu.
Solution was very simple. Just turn off this power management:
sudo hdparm -B255 /dev/sda
If you have more than one drive – the same operation but with different device. That`s it.
Posted by Dan Sosedoff
on January 24, 2009
Ruby is very powerful language, not only for web development as many can think for the first time. It is also providing all necessary resources to build system utilities and daemons. So, this post exactly about it.
Long time ago i was looking for some tool to write simple daemon in a short term. I didn`t choose C just because i was able to develop program only on special computer (i mean “production-like” environment) and the problem wasnt critical to resources. In other words – this daemon was working only few days to complete the task. Ok, lets see what we`ve got:
#!/usr/bin/ruby
# ---------------------------------------------------------------------
# MODULES
# ---------------------------------------------------------------------
require 'daemonize'
include Daemonize
include Process
# ---------------------------------------------------------------------
# CONFIGURATION
# ---------------------------------------------------------------------
$daemon = {
:name => "Test Daemon", # daemon name
:abbr => "testd", # daemon abbreviation
:author => "(c) 2008 author", # daemon author
:version => "0.1", # actual version
:file_log => "/var/log/testdaemon.log", # log path
:file_pid => "/var/run/testdaemon.pid", # process id path
:delay_sleep => 1, # seconds
:user => 'tux', # working data user
:grp => 'tux', # working data group
:background => false, # background mode
:work => true # daemon work flag
}
$daemon_log = nil
$daemon_pid = nil
# ---------------------------------------------------------------------
def daemon_log(str)
puts "[#{Time.now.strftime("%m/%d/%Y-%H:%M:%S")}] #{str}"
end
def daemon_terminate
$daemon[:work] = false
end
def daemon_stop
daemon_log("Stopping working process...")
$daemon_pid.close
File.delete($daemon[:file_pid])
end
def daemon_start
if File.exist?($daemon[:file_pid]) then
daemon_log("Process already running. If it`s not - remove the pid file")
exit
end
daemon_log("Starting process...")
daemonize if $daemon[:background]
begin
$daemon_pid = File.new($daemon[:file_pid],"w")
rescue Errno::EACCES
daemon_log("Cannot create PID file. Check the permissions and try again!")
$daemon_pid = nil
exit
end
daemon_work
end
def daemon_work
if ($daemon_pid) then
$daemon_pid.sync = true
$daemon_pid.puts(Process.pid.to_s)
begin
while $daemon[:work] do
daemon_log("Daemon working")
daemon_handle_signals
sleep($daemon[:delay_sleep])
end
rescue Exception => e
daemon_log("Error: #{e.message}")
end
daemon_stop
end
end
def daemon_handle_signals
# termination signal
Signal.trap("TERM") do
daemon_log("TERM signal received.")
daemon_terminate
end
# kill signal
Signal.trap("KILL") do
daemon_log("KILL signal received.")
daemon_terminate
end
# keyboard interruption
Signal.trap("INT") do
daemon_log("SIGINT signal received.")
daemon_terminate
end
Signal.trap("TSTP") do
daemon_log("SIGTSTP signal received.")
end
end
def daemon_show_version
puts "#{$daemon[:name]} v#{$daemon[:version]} #{$daemon[:author]}"
end
def daemon_show_usage
daemon_show_version
puts "Usage:"
puts " -b, --background work in background mode"
puts " -v, --version view version of daemon"
puts " -h, --help view this help"
end
def daemon_parse_opts
return true if ARGV.length == 0
case ARGV[0]
when '-b', '--background'
$daemon[:background] = true;
return true
when '-v', '--version'
daemon_show_version
when '-h', '--help'
daemon_show_usage
else
puts "Invalid argument: #{ARGV[0]}" if !ARGV[0].nil?
daemon_show_usage
end
return false
end
def daemon_main
daemon_start if daemon_parse_opts
end
daemon_main
This is just a basic structure of daemon, it supports background mode. I removed all unimportant information and left only main program cycles. As you can see, the entry point of whole program – daemon_main procedure. It parsing the command line parameters. In this example there is no required parameters, so daemon will run in basic mode (not background). To enable background you should specify the -d (or –background) option. Also, very important – this example needs to be executed under root or other user that have access to /var/run. Other way, PID file path can be changed to whatever you want (file_pid key). All daemon configuration variables stored in array $daemon. Also, it supports system signals handling, like SIGTERM or SIGKILL (all ruby signal constants u can explore here).
I think that`s it. Not a lot, but very simple. Download script: http://files.sosedoff.com/b57415aa/
Posted by Dan Sosedoff
on January 16, 2009
Bored of manually delete and add files to project? Ok, me too
So, i decided to make a simple command to work with command “svn commit”. All-in-one solution is:
#!/bin/bash
echo "processing files to add..."
svn status | grep “^?” | sed -r ’s/^\?[ ]+//’ | xargs -r svn add
echo "processing files to delete..."
svn status | grep “^!” | sed -r ’s/^\![ ]+//’ | xargs -r svn delete
echo "processing commit..."
svn commit
Download bash script – http://files.sosedoff.com/62c99246/
Posted by Dan Sosedoff
on January 15, 2009
There is a small useful ruby script to backup your MySQL databases in small projects, where speed of backup not so important.
Source:
#!/usr/bin/ruby
# MySQL Backup Utility
# Usage: ./mysql_backup.rb or ruby mysql_backup.rb
$backup_archive = true # gzip files after processing
$backup_dir = "/home/storage/backup/" # output directory
$backup_template = "project-%s-%s.sql" # text-%dbname-%timestamp.sql
$backup_cmd = "mysqldump -u local_backup --add-drop-table --databases %s > %s"
$backup_dblist = [ # list of databases to backup
'main',
'users',
'admin',
'cards'
]
def backup_database(database)
time = Time.now()
time_str = sprintf("%02i-%02i-%04i-%02i%02i%02i",time.day, time.month, time.year, time.hour, time.min, time.sec)
filename = sprintf($backup_template,database,time_str)
filename = "#{$backup_dir}#{filename}"
cmd = sprintf($backup_cmd,database,filename)
if system(cmd) then
system("gzip --best #{filename}") if $backup_archive
end
end
$backup_dblist.each do |db|
puts "Processing database... #{db}"
backup_database(db)
end
Paste: http://pastie.org/341839
Posted by Dan Sosedoff
on January 15, 2009
For example, instead of using “dirty” url`s in your web application (like test.php?param=1&val=342&fuck=bla) you can use very nice links (/this/is/nice/link/). And also, redirect all the requests to single file.
nginx configuration:
location / {
root /var/site/public_html;
index index.php index.html index.htm;
if (!-e $request_filename) {
rewrite ^/(.*)/$ /index.php?path=$request_uri last;
}
}
The same for Apache 2:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ index.php?path=%{REQUEST_URI} [NCL]
Posted by Dan Sosedoff
on January 15, 2009
Problem: You have a domain name ‘www.domain.com’ that needs to be redirected to ‘domain.com’.
Solution:
In your nginx config file (i`m keeping all configs for all sites separate in different files), befor ’server’ block configuration you should put this piese of code:
server {
server_name www.domain.com;
rewrite ^(.*) http://domain.com$1 permanent;
}
server {
... actual server configuration ...
}
Posted by Dan Sosedoff
on January 15, 2009
Some time ago i had reason to make couple servers being accessible by WebDAV protocol.
But all our special storage servers were running nginx 0.6.x, that also supports this protocol.
By the way, it doesn`t support meta commands such as PROPFIND, OPTIONS, so if you try to connect to server with some command-line or GUI client it will close connection due to accepting “unknown” commands, but will work only with PUT, DELETE, COPY, MOVE, MKCOL requests.
It was a huge problem, because for a long time i couldn`t figure out what the reason of reject. Server allways respond with ‘405 Not allowed’. But when i tried put file – it worked.
Also, alternate fast server Lighttpd supports all meta commands.
Simple nginx configuration:
server {
listen 80;
server_name localhost;
access_log log/access.log;
error_log log/error.log;
charset utf-8;
client_body_temp_path client_body_temp;
autoindex on;
location / {
root /home/dav/public;
dav_methods PUT DELETE MKCOL COPY MOVE;
dav_access user:rw group:rw all:r;
create_full_put_path on;
# auth access
auth_basic "Restricted";
auth_basic_user_file ;
}
}
After configuring server, you`ll need to create htpassword file, that will keep user credentials.
Simple example:
htpasswd -c /where/to/save/the/file username
More information about how to configure nginx can be found at http://wiki.codemongers.com/NginxModules
Posted by Dan Sosedoff
on January 15, 2009
nginx, fast small webserver, supports flash flv files streaming.
I am currently using JW Player 4.0 on projects, its free, lightweight and have a lot useful features.
But, i got some problems with its latest versions. It always adding some special information, like player container resolution like this:
myvideo.flv?start=2659763&width=280&version=4.0&...
Result: cannot seek on the video.
Found a solution on ruby forum. http://www.ruby-forum.com/attachment/2307/patch.flv
You need only apply this patch to sources and rebuild nginx. That`s it.
P.S. Don`t know about older versions of nginx, but 0.6.32 from sources doesnt work with JW Player 4.0.
Posted by Dan Sosedoff
on January 15, 2009
Ufo`s servers crashed during the flight and their craft landed here.. Ok, let`s find something to eat on this small planet