Packaging dillema

Hi,

I'm in an environment where it's kind of a pain in the ass to install
external software on production machines. So, if I write a Ruby
application that uses Tk + Tk extensions + ActiveRecord + Sqlite +
whatever else, it's quite difficult to install all those pre-requistes
on the machines (now, a combination of Redhat 8, 9, Enterprise Redhat,
and IRIX).

What I'd really like to do is to be able to package up Ruby, Sqlite,
ActiveRecord, Tk extensions, all in one directory and say "there's my
application. Run it."

I'm having some luck with rubyscript2exe, but I'm running into
problems getting the other stuff in the directory. For instance, I'm
trying to bundle sqlite functionality.

joe@ubuntu:~/test $ ls
libsqlite3.so rubyscript2exe.rb test.db test.rb

joe@ubuntu:~/test $ cat test.rb

require 'rubygems'
require_gem 'activerecord'

RUBYSCRIPT2EXE_LIB = ["libsqlite3.so"]

ActiveRecord::Base.establish_connection(
  :adapter => 'sqlite3',
  :dbfile => 'test.db'
)

class Partition < ActiveRecord::Base
end

p = Partition.new
p.user = Time.now
p.save

for partition in Partition.find_all
    puts "partition user is #{partition.user} and partition title is
#{partition.title}"
end

joe@ubuntu:~/test $ ruby rubyscript2exe.rb test.rb
Tracing test ...
Gathering files...
/usr/lib/ruby/1.8/dl/import.rb:33:in `initialize': libsqlite3.so:
cannot open shared object file: No such file or directory
(RuntimeError)
        from /usr/lib/ruby/1.8/dl/import.rb:33:in `dlopen'
        from /usr/lib/ruby/1.8/dl/import.rb:33:in `dlload'
        from /usr/lib/ruby/1.8/dl/import.rb:31:in `each'
        from /usr/lib/ruby/1.8/dl/import.rb:31:in `dlload'
        from /usr/lib/ruby/site_ruby/1.8/sqlite3/driver/dl/api.rb:63
        from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in
`require__'
        from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in
`require'
        from /usr/lib/ruby/gems/1.8/gems/activesupport-1.0.0/lib/active_support/dependencies.rb:190:in
`require'
         ... 16 levels...
        from /usr/lib/ruby/gems/1.8/gems/activerecord-1.7.0/lib/active_record/base.rb:856:in
`initialize_without_callbacks'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-1.7.0/lib/active_record/callbacks.rb:224:in
`initialize'
        from test.rb:15:in `new'
        from test.rb:15
Copying files...
Stripping...
Creating test_linux ...

Why can't it find libsqlite3.so?

Anyways, anyone have any advice on how to properly package
applications so I can avoid having to install anything outside the
application directory?

I just realized that using Rubyscript2exe with sqlite probably isn't a
good idea, since the database disappears once the application gets
shut down, and I need the database to persist between application
launches. Hm.

···

On 6/23/05, Joe Van Dyk <joevandyk@gmail.com> wrote:

Hi,

I'm in an environment where it's kind of a pain in the ass to install
external software on production machines. So, if I write a Ruby
application that uses Tk + Tk extensions + ActiveRecord + Sqlite +
whatever else, it's quite difficult to install all those pre-requistes
on the machines (now, a combination of Redhat 8, 9, Enterprise Redhat,
and IRIX).

What I'd really like to do is to be able to package up Ruby, Sqlite,
ActiveRecord, Tk extensions, all in one directory and say "there's my
application. Run it."

I'm having some luck with rubyscript2exe, but I'm running into
problems getting the other stuff in the directory. For instance, I'm
trying to bundle sqlite functionality.

joe@ubuntu:~/test $ ls
libsqlite3.so rubyscript2exe.rb test.db test.rb

joe@ubuntu:~/test $ cat test.rb

require 'rubygems'
require_gem 'activerecord'

RUBYSCRIPT2EXE_LIB = ["libsqlite3.so"]

ActiveRecord::Base.establish_connection(
  :adapter => 'sqlite3',
  :dbfile => 'test.db'
)

class Partition < ActiveRecord::Base
end

p = Partition.new
p.user = Time.now
p.save

for partition in Partition.find_all
    puts "partition user is #{partition.user} and partition title is
#{partition.title}"
end

joe@ubuntu:~/test $ ruby rubyscript2exe.rb test.rb
Tracing test ...
Gathering files...
/usr/lib/ruby/1.8/dl/import.rb:33:in `initialize': libsqlite3.so:
cannot open shared object file: No such file or directory
(RuntimeError)
        from /usr/lib/ruby/1.8/dl/import.rb:33:in `dlopen'
        from /usr/lib/ruby/1.8/dl/import.rb:33:in `dlload'
        from /usr/lib/ruby/1.8/dl/import.rb:31:in `each'
        from /usr/lib/ruby/1.8/dl/import.rb:31:in `dlload'
        from /usr/lib/ruby/site_ruby/1.8/sqlite3/driver/dl/api.rb:63
        from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in
`require__'
        from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in
`require'
        from /usr/lib/ruby/gems/1.8/gems/activesupport-1.0.0/lib/active_support/dependencies.rb:190:in
`require'
         ... 16 levels...
        from /usr/lib/ruby/gems/1.8/gems/activerecord-1.7.0/lib/active_record/base.rb:856:in
`initialize_without_callbacks'
        from /usr/lib/ruby/gems/1.8/gems/activerecord-1.7.0/lib/active_record/callbacks.rb:224:in
`initialize'
        from test.rb:15:in `new'
        from test.rb:15
Copying files...
Stripping...
Creating test_linux ...

Why can't it find libsqlite3.so?

Anyways, anyone have any advice on how to properly package
applications so I can avoid having to install anything outside the
application directory?

Hi,

I'm in an environment where it's kind of a pain in the ass to install
external software on production machines. So, if I write a Ruby
application that uses Tk + Tk extensions + ActiveRecord + Sqlite +
whatever else, it's quite difficult to install all those pre-requistes
on the machines (now, a combination of Redhat 8, 9, Enterprise Redhat,
and IRIX).

is there a central nfs server?

What I'd really like to do is to be able to package up Ruby, Sqlite,
ActiveRecord, Tk extensions, all in one directory and say "there's my
application. Run it."

I'm having some luck with rubyscript2exe, but I'm running into
problems getting the other stuff in the directory. For instance, I'm
trying to bundle sqlite functionality.

joe@ubuntu:~/test $ ls
libsqlite3.so rubyscript2exe.rb test.db test.rb

joe@ubuntu:~/test $ cat test.rb

require 'rubygems'
require_gem 'activerecord'

RUBYSCRIPT2EXE_LIB = ["libsqlite3.so"]

ActiveRecord::Base.establish_connection(
:adapter => 'sqlite3',
:dbfile => 'test.db'
)

class Partition < ActiveRecord::Base
end

p = Partition.new
p.user = Time.now
p.save

for partition in Partition.find_all
   puts "partition user is #{partition.user} and partition title is
#{partition.title}"
end

joe@ubuntu:~/test $ ruby rubyscript2exe.rb test.rb
Tracing test ...
Gathering files...
/usr/lib/ruby/1.8/dl/import.rb:33:in `initialize': libsqlite3.so:
cannot open shared object file: No such file or directory
(RuntimeError)
       from /usr/lib/ruby/1.8/dl/import.rb:33:in `dlopen'
       from /usr/lib/ruby/1.8/dl/import.rb:33:in `dlload'
       from /usr/lib/ruby/1.8/dl/import.rb:31:in `each'
       from /usr/lib/ruby/1.8/dl/import.rb:31:in `dlload'
       from /usr/lib/ruby/site_ruby/1.8/sqlite3/driver/dl/api.rb:63
       from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in
`require__'
       from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:18:in
`require'
       from /usr/lib/ruby/gems/1.8/gems/activesupport-1.0.0/lib/active_support/dependencies.rb:190:in
`require'
        ... 16 levels...
       from /usr/lib/ruby/gems/1.8/gems/activerecord-1.7.0/lib/active_record/base.rb:856:in
`initialize_without_callbacks'
       from /usr/lib/ruby/gems/1.8/gems/activerecord-1.7.0/lib/active_record/callbacks.rb:224:in
`initialize'
       from test.rb:15:in `new'
       from test.rb:15
Copying files...
Stripping...
Creating test_linux ...

Why can't it find libsqlite3.so?

Anyways, anyone have any advice on how to properly package
applications so I can avoid having to install anything outside the
application directory?

-a

···

On Thu, 23 Jun 2005, Joe Van Dyk wrote:
--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
My religion is very simple. My religion is kindness.
--Tenzin Gyatso

===============================================================================

I'm having some luck with rubyscript2exe, but I'm running
into problems getting the other stuff in the directory. For
instance, I'm trying to bundle sqlite functionality.

joe@ubuntu:~/test $ ls

libsqlite3.so rubyscript2exe.rb test.db test.rb

joe@ubuntu:~/test $ ruby rubyscript2exe.rb test.rb

A couple if issues:

* Have you tried to run the application directly? I mean,
  without being wrapped by RubyScript2Exe? It won't work if you
  rely on the local libsqlite3.so. It will work if
  libsqlite3.so is located on the library search path as well.
  That's a Linux issue: Linux doesn't append the local
  directory, nor the directory in which the application is
  located, to $LD_LIBRARY_PATH. Windows does something like
  that, Linux doesn't.

* If libsqlite3.so is located on the library search path, it
  will be embedded by RubyScript2Exe automaticly, without
  specifying it in one of the RUBYSCRIPT2EXE_* pragmas.

* You are listing libsqlite3.so in RUBYSCRIPT2EXE_LIB. Why? It
  isn't a Ruby library, but a shared object. Shared objects
  have to be specified in RUBYSCRIPT2EXE_DLLS or
  RUBYSCRIPT2EXE_BIN, unless the share object is detected and
  embedded automaticly.

* The pragmas are used to specify not-detected files that have
  to be embedded in the generated executable. These pragmas
  don't affect the scanning phase of RubyScript2Exe.

Why can't it find libsqlite3.so?

It's not on the library search path.

Anyways, anyone have any advice on how to properly package
applications so I can avoid having to install anything
outside the application directory?

$ export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${pwd}"
$ ruby rubyscript2exe.rb test.rb

Or install SQLite properly...

gegroet,
Erik V. - http://www.erikveen.dds.nl/

Joe Van Dyk wrote:

I just realized that using Rubyscript2exe with sqlite probably isn't a
good idea, since the database disappears once the application gets
shut down, and I need the database to persist between application
launches. Hm.

I had a similar problem early this year. Working a contract job, I wanted to get co-workers to test a Web app using WATIR (the very cool IE-based Web testing framework) without them having to install Ruby. I used Rubyscript2exe to bundle up the application. The main app would start an instance of WEBrick, pause a bit, then launch a browser to point to the WEBrick instance. The default page would prompt the use for a base test site URL, and list the names of test scripts that were stored in a subdirectory. Once could then click on a link for test script, which would then drive WATIR.

The tricky part was that I wanted people to be able to create their own test scripts, and not lose them when the main app was closed.

(The test scripts were Ruby code, but I created a DSL so that writing one's own examples did not require knowing any real Ruby, though it was always an option for those with more ambition.)

My solution was to create the exe, and bundle it in a zip file with sample scripts and a default config file. The installation was basically to unzip the bundle to create the application directory structure and default files, then just run the main app exe.

I believe that the executable created by Rubyscript2exe knows from what directory it is launched, so the code kicked off it could figure out where to look for script files relative to its execution point, and where to write out any logs.

(I cannot find any actual code right now or I would show an example, or at least confirm my recollection of why this worked.)

But if you can have your installation create a permanent subdirectory then you can get your code to read and write to safe location.

James Britt

···

--

http://www.ruby-doc.org - The Ruby Documentation Site
http://www.rubyxml.com - News, Articles, and Listings for Ruby & XML
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys

Joe Van Dyk wrote:

I just realized that using Rubyscript2exe with sqlite probably isn't a
good idea, since the database disappears once the application gets
shut down, and I need the database to persist between application
launches. Hm.

I'm confused, Doesn't sqlite store its data in a database file?

- alan

-a

···

On Fri, 24 Jun 2005, Erik Veenstra wrote:

I'm having some luck with rubyscript2exe, but I'm running
into problems getting the other stuff in the directory. For
instance, I'm trying to bundle sqlite functionality.

joe@ubuntu:~/test $ ls

libsqlite3.so rubyscript2exe.rb test.db test.rb

joe@ubuntu:~/test $ ruby rubyscript2exe.rb test.rb

A couple if issues:

* Have you tried to run the application directly? I mean,
without being wrapped by RubyScript2Exe? It won't work if you
rely on the local libsqlite3.so. It will work if
libsqlite3.so is located on the library search path as well.
That's a Linux issue: Linux doesn't append the local
directory, nor the directory in which the application is
located, to $LD_LIBRARY_PATH. Windows does something like
that, Linux doesn't.

* If libsqlite3.so is located on the library search path, it
will be embedded by RubyScript2Exe automaticly, without
specifying it in one of the RUBYSCRIPT2EXE_* pragmas.

* You are listing libsqlite3.so in RUBYSCRIPT2EXE_LIB. Why? It
isn't a Ruby library, but a shared object. Shared objects
have to be specified in RUBYSCRIPT2EXE_DLLS or
RUBYSCRIPT2EXE_BIN, unless the share object is detected and
embedded automaticly.

* The pragmas are used to specify not-detected files that have
to be embedded in the generated executable. These pragmas
don't affect the scanning phase of RubyScript2Exe.

Why can't it find libsqlite3.so?

It's not on the library search path.

Anyways, anyone have any advice on how to properly package
applications so I can avoid having to install anything
outside the application directory?

$ export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${pwd}"
$ ruby rubyscript2exe.rb test.rb

Or install SQLite properly...

gegroet,
Erik V. - http://www.erikveen.dds.nl/

--

email :: ara [dot] t [dot] howard [at] noaa [dot] gov
phone :: 303.497.6469
My religion is very simple. My religion is kindness.
--Tenzin Gyatso

===============================================================================

> I just realized that using Rubyscript2exe with sqlite
> probably isn't a good idea, since the database disappears
> once the application gets shut down, and I need the
> database to persist between application launches. Hm.

Don't mix user files with application files. A lot of Windows
application do this, but it is imply bad behaviour. Both worlds
(user space and application space) have to be seperated.

My solution was to create the exe, and bundle it in a zip
file with sample scripts and a default config file. The
installation was basically to unzip the bundle to create the
application directory structure and default files, then just
run the main app exe.

Or create a user directory full of templates, simply by
unzipping an embbeded ZIP file. Or use Tar2RubyScript to create
an RBA which includes the application and the templates
directory (but not the shared objects!...) and copy this
template directory to user space the first the application is
started.

I believe that the executable created by Rubyscript2exe knows
from what directory it is launched, so the code kicked off it
could figure out where to look for script files relative to
its execution point, and where to write out any logs.

This is correct. The internal command "ruby app.rb" is started
in the same directory as the user started "app.exe".

gegroet,
Erik V. - http://www.erikveen.dds.nl/

Erik Veenstra wrote:

James wrote:

My solution was to create the exe, and bundle it in a zip
file with sample scripts and a default config file. The
installation was basically to unzip the bundle to create the
application directory structure and default files, then just
run the main app exe.

Or create a user directory full of templates, simply by
unzipping an embbeded ZIP file. Or use Tar2RubyScript to create
an RBA which includes the application and the templates
directory (but not the shared objects!...) and copy this
template directory to user space the first the application is
started.

Ah, quite good. This would alleviate a problem I had when I first handed the zipped ile/exe set over to someone for a test drive. The app ran but could not find the bundled test scripts. I then realized that the code was running on WinXP, which offers the dubious feature of treating zip files as actual folders. My test user just ran the exe straight from the zip; the program could not find the needed files because they were never correctly extracted. Having the exe progam do the extraction would prevent this sort of thing.

James

···

--

http://www.ruby-doc.org - The Ruby Documentation Site
http://www.rubyxml.com - News, Articles, and Listings for Ruby & XML
http://www.rubystuff.com - The Ruby Store for Ruby Stuff
http://www.jamesbritt.com - Playing with Better Toys