S
Simon Strandgaard
I have some data which I make a backup of on daily basis.
The data has many different owners/groups.
I have writen some Ruby which does the job (when logged in as root).
I don't like running things as root, so I have created a dedicated
account only for backup, under which the backup script is supposed
to be executed.
Unfortunatly I cannot figure out the last part (running the
ruby script with root read-permissions).
Q1: How should I setup the right permissions (setuid, /etc/group), any ideas ?
Q2: How do you execute your backup scripts with the right permissions ?
--
Simon Strandgaard
At that point where my script invokes 'cvslock', then it
fails like this:
cvsbackup@server> ruby backup.rb
NEONEYE'S CVS-BACKUP TOOL
source="/reliable/"
dest="/home/cvsbackup/todays_snapshot_of_cvs/"
stamp="20030911_23"
dropzone="[email protected]:backup/."
COMPRESSING REPOSITORIES
#3 public_documents ... cvslock: Error while locking repository.
backup.rb:39:in `size': No such file or directory - /home/cvsbackup/todays_snapshot_of_cvs/
public_documents/20030911_23.tar.gz (Errno::ENOENT)
from backup.rb:39:in `backup'
from backup.rb:47:in `pretty_backup'
from backup.rb:44:in `each'
from backup.rb:44:in `pretty_backup'
from backup.rb:70:in `execute'
from backup.rb:77
cvsbackup@server>
cvsbackup@server> expand -t2 backup.rb
require 'fileutils'
class Backup
# these constants must be absolute paths,
# Ruby doesn't like "~/stuff" kind of paths!
DIR_SOURCE = "/reliable/"
DIR_DEST = "/home/neoneye/todays_snapshot_of_cvs/"
DROPZONE = "[email protected]:backup/."
def initialize
@stamp = prepare_stamp
prepare_dirs
end
def prepare_stamp
Time.now.strftime("%Y%m%d_%H")
end
def prepare_dirs
if FileTest.exists?(DIR_DEST)
FileUtils.rm_r DIR_DEST, :force => true
end
FileUtils.mkdir_p DIR_DEST, :mode => 0700
end
def names # repository_names
Dir.chdir(DIR_SOURCE)
Dir["*"]
end
def backup(name)
dir_dest = DIR_DEST + name + "/"
dest = dir_dest + @stamp + ".tar.gz"
cmd_nest = "tar cfz #{dest} #{name}"
cmd = "cvslock -q -d #{name} -c \"#{cmd_nest}\" ."
# tar doesn't like leading '/' (slashes)
# thus we must chdir to DIR_SOURCE
Dir.chdir(DIR_SOURCE)
FileUtils.mkdir_p dir_dest, :mode => 0700
system(cmd)
FileTest.size(dest) # return number of bytes
end
def pretty_backup
ary = names
n = ary.size
ary.each do |name|
print "##{n} #{name} ... "
$stdout.flush
bytes = backup(name)
puts "OK (#{bytes} bytes)"
n -= 1
end
end
def transfer
# transfer to remote host
Dir.chdir(DIR_DEST)
system("scp -rBq * #{DROPZONE}")
end
def info
<<MSG
source=#{DIR_SOURCE.inspect}
dest=#{DIR_DEST.inspect}
stamp=#{@stamp.inspect}
dropzone=#{DROPZONE.inspect}
MSG
end
def Backup.execute
i = Backup.new
puts "NEONEYE'S CVS-BACKUP TOOL"
puts i.info
puts "COMPRESSING REPOSITORIES"
i.pretty_backup
puts "TRANSFERING REPOSITORIES"
i.transfer
puts "DONE"
end
end
Backup.execute
cvsbackup@server>
The data has many different owners/groups.
I have writen some Ruby which does the job (when logged in as root).
I don't like running things as root, so I have created a dedicated
account only for backup, under which the backup script is supposed
to be executed.
Unfortunatly I cannot figure out the last part (running the
ruby script with root read-permissions).
Q1: How should I setup the right permissions (setuid, /etc/group), any ideas ?
Q2: How do you execute your backup scripts with the right permissions ?
--
Simon Strandgaard
At that point where my script invokes 'cvslock', then it
fails like this:
cvsbackup@server> ruby backup.rb
NEONEYE'S CVS-BACKUP TOOL
source="/reliable/"
dest="/home/cvsbackup/todays_snapshot_of_cvs/"
stamp="20030911_23"
dropzone="[email protected]:backup/."
COMPRESSING REPOSITORIES
#3 public_documents ... cvslock: Error while locking repository.
backup.rb:39:in `size': No such file or directory - /home/cvsbackup/todays_snapshot_of_cvs/
public_documents/20030911_23.tar.gz (Errno::ENOENT)
from backup.rb:39:in `backup'
from backup.rb:47:in `pretty_backup'
from backup.rb:44:in `each'
from backup.rb:44:in `pretty_backup'
from backup.rb:70:in `execute'
from backup.rb:77
cvsbackup@server>
cvsbackup@server> expand -t2 backup.rb
require 'fileutils'
class Backup
# these constants must be absolute paths,
# Ruby doesn't like "~/stuff" kind of paths!
DIR_SOURCE = "/reliable/"
DIR_DEST = "/home/neoneye/todays_snapshot_of_cvs/"
DROPZONE = "[email protected]:backup/."
def initialize
@stamp = prepare_stamp
prepare_dirs
end
def prepare_stamp
Time.now.strftime("%Y%m%d_%H")
end
def prepare_dirs
if FileTest.exists?(DIR_DEST)
FileUtils.rm_r DIR_DEST, :force => true
end
FileUtils.mkdir_p DIR_DEST, :mode => 0700
end
def names # repository_names
Dir.chdir(DIR_SOURCE)
Dir["*"]
end
def backup(name)
dir_dest = DIR_DEST + name + "/"
dest = dir_dest + @stamp + ".tar.gz"
cmd_nest = "tar cfz #{dest} #{name}"
cmd = "cvslock -q -d #{name} -c \"#{cmd_nest}\" ."
# tar doesn't like leading '/' (slashes)
# thus we must chdir to DIR_SOURCE
Dir.chdir(DIR_SOURCE)
FileUtils.mkdir_p dir_dest, :mode => 0700
system(cmd)
FileTest.size(dest) # return number of bytes
end
def pretty_backup
ary = names
n = ary.size
ary.each do |name|
print "##{n} #{name} ... "
$stdout.flush
bytes = backup(name)
puts "OK (#{bytes} bytes)"
n -= 1
end
end
def transfer
# transfer to remote host
Dir.chdir(DIR_DEST)
system("scp -rBq * #{DROPZONE}")
end
def info
<<MSG
source=#{DIR_SOURCE.inspect}
dest=#{DIR_DEST.inspect}
stamp=#{@stamp.inspect}
dropzone=#{DROPZONE.inspect}
MSG
end
def Backup.execute
i = Backup.new
puts "NEONEYE'S CVS-BACKUP TOOL"
puts i.info
puts "COMPRESSING REPOSITORIES"
i.pretty_backup
puts "TRANSFERING REPOSITORIES"
i.transfer
puts "DONE"
end
end
Backup.execute
cvsbackup@server>