Is it possible to force a Ruby program to run as a proc name different than "ruby"?

Hi, I have a Python software called “py_program”. It runs as daemon in
Linux
so doing a “ps” I get:

root 6541 /usr/bin/python /home/ibc/py_program

However in /proc/6541/status I read:

Name: py_program

This is good because this means that in Debian it can be stopped with
the
command:

start-stop-daemon --stop --name py_program

Anyhow the proces name is “python” still rather than “py_program”:

~# netstat -putan | grep 6541
6541/python

and I cannot kill the process with “killall py_program”.

Well, I’m coding a server “rb_program” in Ruby (a HTTP server built with
Rack)
and the behavior is different:

root 5412 ruby1.9 /home/ibc/rb_program

In /proc/5412/status:

Name: ruby1.9

So I cannot use “start-stop-daemon --stop --name rb_program” because it
would
find no process names “rb_program”
(and of course I cannot use “–name ruby1.9” as I would stop any ruby
program
running in the host).

So, is there some way to force the process to appear as “rb_program” in
/proc/PID/status?

Thanks a lot.

El Viernes, 11 de Diciembre de 2009, Iñaki Baz C. escribió:

So, is there some way to force the process to appear as “rb_program” in
/proc/PID/status?

I forgot to say that a dirty workaround is creating a link to ruby
binary
called “rb_program”.

Of course is really dirty :slight_smile:

El Sábado, 12 de Diciembre de 2009, David M. escribió:

start-stop-daemon --start --startas /home/ibc/rb_program --make-pidfile –
pidfile /var/run/rb_program.pid --background

If your program is backgrounding itself already, configure it to create its
own pidfile – shouldn’t be too hard. Then you can do this instead:

start-stop-daemon --stop --pidfile /var/run/rb_program.pid

Yes, in fact I use it now: my Ruby server creates a pidfile.

The good point of using:

start-stop-daemon --stop --pidfile /var/run/rb_program.pid --name
rb_program

is that it would stop the process just if it’s called “rb_program” and
its pid
matches the value of /var/run/rb_program.pid, so you cannot kill any
other
process using that pid by accident (it could occur if your program
didn’t
delete the pidfile and a new process has taken same pid value).

On Friday 11 December 2009 04:34:04 pm Iñaki Baz C. wrote:

This is good because this means that in Debian it can be stopped with the
command:

start-stop-daemon --stop --name py_program
[snip]
So I cannot use “start-stop-daemon --stop --name rb_program” because it
would find no process names “rb_program”

This is probably not a good idea in the first place – it means you
can’t have
separate copies of the program running, and start/stop them
independently, to
say nothing of the possibility that some other program might share the
same
name.

Since you’re using start-stop-daemon anyway, why don’t you make a
pidfile?

start-stop-daemon --start --startas /home/ibc/rb_program --make-pidfile

pidfile /var/run/rb_program.pid --background

If your program is backgrounding itself already, configure it to create
its
own pidfile – shouldn’t be too hard. Then you can do this instead:

start-stop-daemon --stop --pidfile /var/run/rb_program.pid

So, is there some way to force the process to appear as “rb_program” in
/proc/PID/status?

I’d like to know that, too, because it’d be useful for things like
killall
when things get out of hand. But even if there was, this is still the
wrong
approach – your start-stop-daemon command is sort of equivalent to
killall,
which is a really blunt instrument.

On Friday 11 December 2009 05:33:06 pm Iñaki Baz C. wrote:

The good point of using:

start-stop-daemon --stop --pidfile /var/run/rb_program.pid --name
rb_program

is that it would stop the process just if it’s called “rb_program” and its
pid matches the value of /var/run/rb_program.pid, so you cannot kill any
other process using that pid by accident (it could occur if your program
didn’t delete the pidfile and a new process has taken same pid value).

That’s a good point – though I would guess that in theory, it shouldn’t
be
possible for a program to die in such a way that it wouldn’t be able to
delete
that file. The only thing that would make sense is a reboot, and on my
system,
/var/run is a tmpfs (only exists in RAM/swap), so it’s not stored
anywhere
that would survive a reboot.

I can think of a few other possibilities, like checking directly (with
fuser,
for example) which process is controlling the resource your daemon is
associated with, or even talking to the old daemon over a socket, or
some sort
of formal IPC like dbus.

I’m not sure about Debian, but on Ubuntu, the upstart system might also
be
worth looking into.

I did find a solution, though:

#!/usr/bin/env ruby

doesn’t work. However:

#!/usr/bin/ruby1.9.1

produces a process which responds both to killall and to
‘start-stop-daemon –
stop --name’. But hardcoding the location of the Ruby interpreter is
antisocial, especially when there are so many of them. The whole point
of env
is that I can always override PATH and point to a different Ruby
interpreter,
to easily switch between 1.8, 1.9, JRuby, Rubinius, etc.

I thought I’d found a workaround, and I’ve been getting messy with C
trying to
figure out how to replace env with a more appropriate program, but I’m
not
sure how to change the program name at all. That is, this isn’t a Ruby
issue,
it’s a Linux/Unix issue. The best I could figure out was this:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int main(int argc, char *argv[]) {
if (argc == 1) {
fprintf(stderr, “Usage: %s PROGRAM ARGUMENTS\n”, argv[0]);
return 1;
}

char * filename = argv[1];
argv[1] = “foo”;

execvp(filename, argv+1);

char * outstr = malloc(strlen(argv[0]) + strlen(argv[1]) + 2);
sprintf(outstr, “%s: %s”, argv[0], argv[1]);
perror(outstr);
return errno;
}

Compile that, then change the Ruby script to be:

#!/path/to/that/binary ruby

The same should work for Python.

Except it doesn’t.

It does indeed change the program name in /proc/self/cmdline – it
becomes
‘foo /name/of/my/program.rb’. And killall and start-stop-daemon both
seem to
work, here, but only when I give them “ruby” as the name of the program
to
kill.

Notice, also, I’m explicitly setting ‘foo’ as the program name. If this
worked, I’d detect that dynamically – but it doesn’t.

At this point, I’m about ready to write a script that would copy your
script
(or create a wrapper for your script) and change the shebang to match
which ruby at the point of invocation, but that wouldn’t work either – that
will
fool the program name in /proc, but it won’t fool your program –
there’s $0
and probably a dozen other things I haven’t thought of to tell it that
it’s
being loaded by a separate script.

I don’t really know what else to try. /proc/self/exe is no help; that
points
to the Ruby binary no matter what. You might write your own script that
greps
through /proc/*/cmdline, but I don’t see a way to fool start-stop-daemon
without changing to #!/usr/bin/ruby1.9.1.

Iñaki Baz C. wrote:

So, is there some way to force the process to appear as “rb_program” in
/proc/PID/status?

Have you tried

$0 = ‘rb_program’

?

You may find there’s a problem if your program name is longer than some
hard-coded limit. There is a workaround at
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/336743

At the top of your program put:

$progname = $0
alias $PROGRAM_NAME $0
alias $0 $progname
trace_var(:$0) {|val| $PROGRAM_NAME = val} # update for ps

El Sábado, 12 de Diciembre de 2009, David M. escribió:

value).

That’s a good point – though I would guess that in theory, it shouldn’t be
possible for a program to die in such a way that it wouldn’t be able to
delete that file. The only thing that would make sense is a reboot, and on
my system, /var/run is a tmpfs (only exists in RAM/swap), so it’s not
stored anywhere that would survive a reboot.

Well, usually daemons are coded to deelte the pidfile upon receipt of a
SIGINT
signal (or some others). But if the daemon is killed with “kill -9 PID”
then
it terminates inmediately without deleting the piddile.

In the case of a crash or segmentfault the daemon wouldn’t delete the
pidfile
again.

I’ve coded my Debian init script “start” action so it deletes the
existing
“pidfile” if it exists (it shouldn’t).

I can think of a few other possibilities, like checking directly (with
fuser, for example) which process is controlling the resource your daemon
is associated with, or even talking to the old daemon over a socket, or
some sort of formal IPC like dbus.

Sounds interesting, but perhaps a bit complex. I think I don’t need so
much as
there will be an unique instance of the ruby program running in the
server.

I did find a solution, though:

#!/usr/bin/env ruby

doesn’t work. However:

#!/usr/bin/ruby1.9.1

produces a process which responds both to killall and to ‘start-stop-daemon
– stop --name’.

Great! this is the point. I’ve checked the daemon in python and it uses
“/usr/bin/python” rather than “/usr/bin/env python”.

But hardcoding the location of the Ruby interpreter is
antisocial, especially when there are so many of them. The whole point of
env is that I can always override PATH and point to a different Ruby
interpreter, to easily switch between 1.8, 1.9, JRuby, Rubinius, etc.

Yes, and when dealing with compiled sources rather than linux
distribution
specific packages we could have ruby1.9 binay in /usr/local/bin/,
/opt/bin/…
I agree 100%. I wouldn’t like to hardcode the ruby location.

#include <errno.h>
execvp(filename, argv+1);
#!/path/to/that/binary ruby
Notice, also, I’m explicitly setting ‘foo’ as the program name. If this
points to the Ruby binary no matter what. You might write your own script
that greps through /proc/*/cmdline, but I don’t see a way to fool
start-stop-daemon without changing to #!/usr/bin/ruby1.9.1.

Thanks a lot for all your suggestions, it’s a really interesting
subject.
However I would prefer to keep the code as simple as possible. The only
I
wanted was the possibility of kill my program using “killall
rb_program”.

To summarize this is possible in these cases:

a) Hardcoding the ruby location (avoiding using “env”).
Not user-friendly.

b) Creating a link “rb_program” to ruby interpreter and invoke my
program with
“rb_program /PATH_TO_rb_program.rb”.
Not very beauty :slight_smile:

c) Replacing env with your above suggestion.
It involves compiling a C program, it could break something in a not
pure
Linux environment…

Well, I’ve learnt a lot in this thread but at this point I think is
better
just to leave the code as it is.
Really thanks a lot.

Brian C. wrote:

Iñaki Baz C. wrote:

So, is there some way to force the process to appear as “rb_program” in
/proc/PID/status?

Have you tried

$0 = ‘rb_program’

?

… or I can’t remember the details, but perhaps you needed
$0.replace(‘rb_program’), but that doesn’t work for newer versions of
Ruby where $0 is a frozen string, hence the required special code:

$progname = $0
alias $PROGRAM_NAME $0
alias $0 $progname
trace_var(:$0) {|val| $PROGRAM_NAME = val} # update for ps

El Sábado, 12 de Diciembre de 2009, Brian C. escribió:

… or I can’t remember the details, but perhaps you needed
$0.replace(‘rb_program’), but that doesn’t work for newer versions of

Ruby where $0 is a frozen string, hence the required special code:

$progname = $0
alias $PROGRAM_NAME $0
alias $0 $progname
trace_var(:$0) {|val| $PROGRAM_NAME = val} # update for ps

Thanks a lot, it sounds really interesting.

However all the above works for me just by adding at the top:
$0 = “rb_program”
or:
$PROGRAM_NAME = “rb_program”

With it when I do a “ps” I see “rb_program” which is great.

However in /proc/PID/status I still have the same described issues:
“Name:
ruby1.9”, so I cannot do “killall rb_program”.

This can be solved by using:
#!/usr/local/bin/ruby1.9
rather than:
#!/usr/bin/env ruby1.9

but of course hardcoding the location of ruby is not very good approach
(specially when you want your code to run on any Linux system).

Thanks a lot.

El Sábado, 12 de Diciembre de 2009, Iñaki Baz C. escribió:

However in /proc/PID/status I still have the same described issues: “Name:
ruby1.9”, so I cannot do “killall rb_program”.

It seems to be more a “killall” issue since “pidof rb_program” works
while
“killall rb_program” not.

El Sábado, 12 de Diciembre de 2009, Iñaki Baz C. escribió:

El Sábado, 12 de Diciembre de 2009, Iñaki Baz C. escribió:

However in /proc/PID/status I still have the same described issues:
“Name: ruby1.9”, so I cannot do “killall rb_program”.

It seems to be more a “killall” issue since “pidof rb_program” works while
“killall rb_program” not.

I read in http://psmisc.sourceforge.net/changelog.html:


Changes from version 12 to 13 (16-APR-1997)

killall: now lists PIDs if invoked as “pidof” (proposed by Peter Daum)

This, if I do “killall rb_” and pres TAB (I’ve autocompletion) I get
“killall
rb_program” but it doesn’t work, it doesn’t kill the process.
However if I do “pidof rb_program” I get its pid.

Strange… I’ll report a bug in psmisc.

On 12.12.2009 10:53, Iñaki Baz C. wrote:

value).
In the case of a crash or segmentfault the daemon wouldn’t delete the pidfile
again.

I’ve coded my Debian init script “start” action so it deletes the existing
“pidfile” if it exists (it shouldn’t).

You can make deletion conditionally depending on the presence of the
process (kill 0). This is what I would do:

VAR=’/var/run’

pid_file = File.join(VAR, File.basename($0) + ‘.pid’)

begin
old_pid = File.read(pid_file).to_i
Process.kill 0, old_pid
$stderr.puts “ERROR: already running with PID #{old_pid}”
exit 1
rescue Errno::ENOENT

no pid file

rescue Errno::ESRCH

process not running

$stderr.puts ‘WARNING: stale pid file’
end

open file with EXCL in order to catch race conditions where two

processes were started almost at the same time and both thought

they would be a new instance. Uncomment sleep to simulate:

sleep 2

File.open(pid_file, File::EXCL | File::WRONLY | File::CREAT) {|io|
io.write($$)}
trap(0) {File.delete pid_file}

puts “OK, here we go.”

just for testing purposes:

File.read(pid_file).to_i == $$ or raise “What went wrong?”

sleep 10

puts “Finished”

Thanks a lot for all your suggestions, it’s a really interesting subject.
However I would prefer to keep the code as simple as possible. The only I
wanted was the possibility of kill my program using “killall rb_program”.

Why does it have to be “killall”? What about providing a command line
option “-k” or “–kill” for killing (e.g. as ssh-agent does)? You could
integrate that pretty easily with the PID handling code above.

To summarize this is possible in these cases:

a) Hardcoding the ruby location (avoiding using “env”).
Not user-friendly.

I personally do not find it too unfriendly to place the interpreter name
with an absolute path in the script. This has also greater safety and
robustness: the one installing the program and ruby interpreter (some
person with administrative permissions) is likely the same and can
ensure location is set properly. Relying on users’ environments is more
fragile IMHO.

Really thanks a lot.
Well, it’s your choice.

Kind regards

robert

El Sábado, 12 de Diciembre de 2009, Robert K.
escribió:> >>> your program didn’t delete the pidfile and a new process has taken same

PID" then it terminates inmediately without deleting the piddile.
VAR=’/var/run’
rescue Errno::ESRCH
trap(0) {File.delete pid_file}
Thanks a lot for all your suggestions, it’s a really interesting subject.
Not user-friendly.
Not very beauty :slight_smile:

c) Replacing env with your above suggestion.
It involves compiling a C program, it could break something in a not pure
Linux environment…

Well, I’ve learnt a lot in this thread but at this point I think is
better just to leave the code as it is.
Really thanks a lot.

Well, it’s your choice.

Thanks a lot!

On Saturday 12 December 2009 03:53:06 am Iñaki Baz C. wrote:

Well, usually daemons are coded to deelte the pidfile upon receipt of a
SIGINT signal (or some others). But if the daemon is killed with “kill -9
PID” then it terminates inmediately without deleting the piddile.

True. I tried (and failed) to find an example of this working. However,
a
separate process can watch your process and clean up after it however it
dies.
I think this is the principle behind letting init handle it – take
“upstart”.

In the case of a crash or segmentfault the daemon wouldn’t delete the
pidfile again.

If the crash raises an exception, you can catch that. Segmentation
faults
trigger SIGSEGV, which you can trap. I suspect you’d have a chance to at
least
fire that unlink call with any death except a ‘kill -9’.

I can think of a few other possibilities, like checking directly (with
fuser, for example) which process is controlling the resource your
daemon is associated with, or even talking to the old daemon over a
socket, or some sort of formal IPC like dbus.

Sounds interesting, but perhaps a bit complex. I think I don’t need so much
as there will be an unique instance of the ruby program running in the
server.

Yes, probably too complex to do for a specific program. However, it
might be
worth wrapping into a library, if there isn’t already one designed for
this.

Thanks a lot for all your suggestions, it’s a really interesting subject.
However I would prefer to keep the code as simple as possible. The only I
wanted was the possibility of kill my program using “killall rb_program”.

To summarize this is possible in these cases:

a) Hardcoding the ruby location (avoiding using “env”).
Not user-friendly.

However, if you distribute your app as a gem, this problem actually goes
away.
Here’s the top of gems/rake-0.8.7/bin/rake:

#!/usr/bin/env ruby

#–

Copyright © 2003, 2004, 2005, 2006, 2007 Jim W.

Here’s what it actually installs into your PATH:

#!/usr/bin/ruby1.9.1

This file was generated by RubyGems.

The application ‘rake’ is installed as part of a gem, and

this file is here to facilitate running it.

require ‘rubygems’

version = “>= 0”

if ARGV.first =~ /^(.*)$/ and Gem::Version.correct? $1 then
version = $1
ARGV.shift
end

gem ‘rake’, version
load Gem.bin_path(‘rake’, ‘rake’, version)

So, that gives you the best of both worlds – it’s actually somewhat
like one
of the crazier solutions I suggested.

b) Creating a link “rb_program” to ruby interpreter and invoke my program
with “rb_program /PATH_TO_rb_program.rb”.
Not very beauty :slight_smile:

c) Replacing env with your above suggestion.

Except © doesn’t work. I thought it would work, and I posted it to the
list
in case I was close enough for someone to pick up where I left off.

It involves compiling a C program, it could break something in a not pure
Linux environment…

Well, the idea was that if this worked, it’d be generally useful. After
all,
env is on every system, and many Ruby scripts rely on that. So again,
not
something specific to your program.

El Sábado, 12 de Diciembre de 2009, David M. escribió:

On Saturday 12 December 2009 03:53:06 am Iñaki Baz C. wrote:

Well, usually daemons are coded to deelte the pidfile upon receipt of a
SIGINT signal (or some others). But if the daemon is killed with “kill
-9 PID” then it terminates inmediately without deleting the piddile.

True. I tried (and failed) to find an example of this working. However, a
separate process can watch your process and clean up after it however it
dies. I think this is the principle behind letting init handle it – take
“upstart”.

I should take a deep look to “upstart”. Until now I’m just used to usual
Linux
init scripts. But since Debian will adopt upstart it’s good time to
learn it
:slight_smile:

In the case of a crash or segmentfault the daemon wouldn’t delete the
pidfile again.

If the crash raises an exception, you can catch that.

Yes, I catch all the exceptions, I meant segfaults that can occur when
using
Ruby C extensions (or when a Ruby bug occurs).

Segmentation faults
trigger SIGSEGV, which you can trap.

Ops, I didn’t know it at all. Really interesting.

I suspect you’d have a chance to at
least fire that unlink call with any death except a ‘kill -9’.

Ok, so do you say that using “upstart” this problem could be solved as
upstart
itself could manage it when detects a service crash?

#–

Copyright © 2003, 2004, 2005, 2006, 2007 Jim W.

Here’s what it actually installs into your PATH:

#!/usr/bin/ruby1.9.1

This file was generated by RubyGems.

So, that gives you the best of both worlds – it’s actually somewhat like
one of the crazier solutions I suggested.

Great. However I’m not sure if my program would fit well as a gem. It’s
not a
library or utility but a whole http server (for XCAP protocol). This is,
it
will have conf files into /etc directory and so. I’ve never seen a gem
that
installs a server by itself and contains files in /etc.

Also, I need a Debian init/upstart script so a gem is not fully valid
for me.

Thanks a lot for your help.

Iñaki Baz C.:

However in /proc/PID/status I still have the same described
issues: “Name: ruby1.9”, so I cannot do “killall rb_program”.

This can be solved by using:
#!/usr/local/bin/ruby1.9
rather than:
#!/usr/bin/env ruby1.9

but of course hardcoding the location of ruby is not very good
approach (specially when you want your code to run on any Linux
system).

I was wondering about exactly this problem recently. I’m using
hand-rolled Ruby 1.9.1 and 1.8.7 versions in ~/opt – and once I finally
got to rolling my own gem I found out that when RubyGems install an
executable, they put a wrapper script in the given Ruby installation
path, with the hashbang hardcoded to that interpreter’s binary.

In other words – while the executables in my repo start with
‘#!/usr/bin/env ruby’ (and so pick up the ‘current’ Ruby interpreter),
once I roll and install a gem RubyGems create a custom executable
wrappers for them, and the ones installed with Ruby 1.9.1 start with
‘#!/home/shot/opt/ruby-1.9.1-p376/bin/ruby’ (and if I link them from
my ~/bin I don’t even need to do any $PATH munging to get them running
through a given Ruby binary).

Hence, my conclusion is that if you turned your code into a gem prior
to installing it, you could still keep the ‘#!/usr/bin/env ruby1.9’
hashbang in your repo (and for testing), but once you want to get
a given version into ‘production’, RubyGems will turn that into
‘#!/usr/local/bin/ruby1.9’ upon the gem’s installation.

— Shot

On Saturday 12 December 2009 03:54:00 pm Iñaki Baz C. wrote:

El Sábado, 12 de Diciembre de 2009, David M. escribió:

I suspect you’d have a chance to at
least fire that unlink call with any death except a ‘kill -9’.

Ok, so do you say that using “upstart” this problem could be solved as
upstart itself could manage it when detects a service crash?

I’m saying most aspects of it can be solved within the program –
anything
except ‘kill -9’. With something like upstart, even that should be
solvable.
On OS X, I think launchd is similar. Basically, you have one (or more)
central
process(es) which manage the launching and killing of daemons.

At this point, you don’t even have to use pidfiles, you can just use
variables. In pseudocode:

class Process
def start
unless running?
if @pid = fork
waitpid(@pid) do
@pid = nil
end
else
exec @cmdline
end
end
end
def stop
kill @pid
end
end

The main reason that’s pseudocode is that upstart very likely already
does
this for you (so why reinvent the wheel in Ruby?), and because waitpid
doesn’t
actually work that way.

But basically, the only problem with this model is that if the process
responsible for watching your process dies abnormally, either the
pidfile
won’t be cleaned up (if there is one), or you’ll now have an unmonitored
copy
of your process running (so you’ll need something like killall again).
If
you’re using something like upstart, that’s not really a problem –
remember,
upstart is init, which means the second it dies, the kernel panics. In
other
words, it doesn’t die.

So, that gives you the best of both worlds – it’s actually somewhat like
one of the crazier solutions I suggested.

Great. However I’m not sure if my program would fit well as a gem. It’s not
a library or utility but a whole http server (for XCAP protocol). This is,
it will have conf files into /etc directory and so. I’ve never seen a gem
that installs a server by itself and contains files in /etc.

The usual approach I’d suggest here is, store a configfile path,
something
like the PATH variable, in which later configfiles override values set
by
earlier ones. Then, set all the default values in a sample config file
inside
your gem, and let the admin put a conf file in /etc/rb_app (or in
~/.rb_app,
or in a place specified by the environment variable RB_APP_CONFIG, or in
a
place specified by --config on the commandline) if they want to override
something.

That just leaves this part:

Also, I need a Debian init/upstart script so a gem is not fully valid for
me.

That much is possibly true – you’d need a script that installs/updates
that
script.

If you’re worried about people going so far as to have separate Ruby
interpreters, I’d suggest letting them write their own script, and
simply
provide documentation, and maybe a command to install some default
samples.
Those scripts would likely be very simple anyway.

On the other hand, you might consider just building a Debian package,
depending on the interpreter you want, and hardcoding it into the
shebang and
the upstart scripts. Let people download the source if they want to
tweak it
further. But I’d only go this route if you’re content to depend on the
Ruby
libraries that are already packaged in Debian – unlike some other
package
managers, apt lacks a way to depend directly on truly alien packages.
(Contrast to Gobo, in which system packages can depend directly on gems,
CPAN
modules, etc – I know Gentoo could depend on CPAN modules, too.)

El Sábado, 12 de Diciembre de 2009, David M. escribió:

solvable. On OS X, I think launchd is similar. Basically, you have one (or
waitpid(@pid) do
end
problem – remember, upstart is init, which means the second it dies, the
kernel panics. In other words, it doesn’t die.

It’s really great and makes lots of sense. The classic usage of pidfiles
and
so seems ugly and “deprecated” stuff.

earlier ones. Then, set all the default values in a sample config file
inside your gem, and let the admin put a conf file in /etc/rb_app (or in
~/.rb_app,

But can a gem installation generate a default conf file/directory in
/etc?
I know gem installations can generate runnable files into /usr/bin (or
/usr/local/bin). This is, I wouldn’t like that the user has to create by
himself the config fiel/directory in /etc :frowning:

or in a place specified by the environment variable
RB_APP_CONFIG, or in a place specified by --config on the commandline) if
they want to override something.

I like --config option as I already have command line options for
chossing
logging directory, process uid/gid, listening port and so. Command line
options override values in the configuration file.

On the other hand, you might consider just building a Debian package,
depending on the interpreter you want, and hardcoding it into the shebang
and the upstart scripts.

The problem is that my server requires 6-7 gems and modern version of
them
(for example Debian Lenny just includes Rack version 0.3 !! while
current gem
version is 1.0.1 !!).

Let people download the source if they want to
tweak it further. But I’d only go this route if you’re content to depend
on the Ruby libraries that are already packaged in Debian – unlike some
other package managers, apt lacks a way to depend directly on truly alien
packages. (Contrast to Gobo, in which system packages can depend directly
on gems, CPAN modules, etc – I know Gentoo could depend on CPAN modules,
too.)

This is the reason why I prefer to build a Gem rather than a deb
package.
Creating the former would require package all the gems withing the deb
package
which would make difficult to upgrade gems and so.

Well, after this good thread (thanks a lot) I think I’ll do the
following:

  • A gem package depending on others gems (as usual).
  • Some runnable Ruby scripts (built into the gem) like:
    • myprogram_create_conf.rb: Creates conf files under /etc.
    • myprogram_create_init.rb: Creates the init script.
    • myprogram_create_database.rb: Creates database for the server.

These scripts could have different behaviour depending on the detected
Linux
distribution, this is, when running “myprogram_create_init.rb” would
detect
the Linux distribution and offer different kinds of init scripts (and
why not:
a upstart script for Ubuntu/Debian !).

Thanks a lot!

El Sábado, 12 de Diciembre de 2009, Robert K.
escribió:> exit 1

sleep 2

File.open(pid_file, File::EXCL | File::WRONLY | File::CREAT) {|io|
io.write($$)}
trap(0) {File.delete pid_file}

puts “OK, here we go.”

Let me a question: is the above a fragment of a Linux init script
written in
Ruby (rather than bash/sh as usual)?

If so, according to LSB specifications it should return 0 (success) in
case of
“start” action when the daemon is already running.

Thanks a lot.

El Sábado, 12 de Diciembre de 2009, Shot (Piotr S.) escribió:

approach (specially when you want your code to run on any Linux
system).

I was wondering about exactly this problem recently. I’m using
hand-rolled Ruby 1.9.1 and 1.8.7 versions in ~/opt – and once I finally
got to rolling my own gem I found out that when RubyGems install an
executable, they put a wrapper script in the given Ruby installation
path, with the hashbang hardcoded to that interpreter’s binary.

I suffer same issues. I’ve installed ruby 1.9.1 (installed from sources)
under
/usr/local. and ruby 1.8.7 (Debian package) under /usr.

I compile ruby1.9 with these options:
/configure --prefix=/usr/local/ --program-suffix=1.9 ; make ; make
install
so all its runnable files are sufixed by 1.9 (ruby1.9, gem1.9,
irb1.9…).

Unfortunatelly executables installed by gems are not sufixed so there is
conflict between ruby1.8 gems and ruby1.9 gems.

By default /usr/local/bin/ appears before than /usr/bin/ in usual PATH
environment variable, so executables belonging to ruby1.9 gems take
preference. This is ugly when you install a ruby1.8 gem which requires
some
ruby executtable (as racc, rake and so).

So finally my “solution/workaround” is a script that rewrites the PATH
variable and sets /usr/bin/ before /usr/local/bin/. And I must run it
before
installing a gem for ruby1.8. Ugly but works :slight_smile:

hashbang in your repo (and for testing), but once you want to get
a given version into ‘production’, RubyGems will turn that into
‘#!/usr/local/bin/ruby1.9’ upon the gem’s installation.

Ok, I’ll do it.
Thanks a lot.