Question

J'ai un travail cron sur un VPS Ubuntu Hardy qui ne fonctionne qu'à moitié et je n'arrive pas à comprendre pourquoi.Le travail est un script Ruby qui utilise mysqldump pour sauvegarder une base de données MySQL utilisée par une application Rails, qui est ensuite compressée et téléchargée sur un serveur distant à l'aide de SFTP.

Le fichier gzip est créé et copié avec succès mais il contient toujours zéro octet.Pourtant, si j'exécute la commande cron directement depuis la ligne de commande, cela fonctionne parfaitement.

Voici le travail cron :

PATH=/usr/bin
10 3 * * * ruby /home/deploy/bin/datadump.rb

Voici datadump.rb :

#!/usr/bin/ruby
require 'yaml'
require 'logger'
require 'rubygems'
require 'net/ssh'
require 'net/sftp'

APP        = '/home/deploy/apps/myapp/current'
LOGFILE    = '/home/deploy/log/data.log'
TIMESTAMP  = '%Y%m%d-%H%M'
TABLES     = 'table1 table2'

log        = Logger.new(LOGFILE, 5, 10 * 1024)
dump       = "myapp-#{Time.now.strftime(TIMESTAMP)}.sql.gz"
ftpconfig  = YAML::load(open('/home/deploy/apps/myapp/shared/config/sftp.yml'))
config     = YAML::load(open(APP + '/config/database.yml'))['production']
cmd        = "mysqldump -u #{config['username']} -p#{config['password']} -h #{config['host']} --add-drop-table --add-locks --extended-insert --lock-tables #{config['database']} #{TABLES} | gzip -cf9 > #{dump}"

log.info 'Getting ready to create a backup'
`#{cmd}`    

# Strongspace
log.info 'Backup created, starting the transfer to Strongspace'
Net::SSH.start(ftpconfig['strongspace']['host'], ftpconfig['strongspace']['username'], ftpconfig['strongspace']['password']) do |ssh|
  ssh.sftp.connect do |sftp|
    sftp.open_handle("#{ftpconfig['strongspace']['dir']}/#{dump}", 'w') do |handle|
      sftp.write(handle, open("#{dump}").read)
    end
  end
end
log.info 'Finished transferring backup to Strongspace'

log.info 'Removing local file'
cmd       = "rm -f #{dump}" 
log.debug "Executing: #{cmd}"
`#{cmd}`
log.info 'Local file removed'

J'ai vérifié et revérifié tous les chemins et ils sont corrects.Les deux sftp.yml (identifiants SFTP) et base de données.yml (Identifiants MySQL) appartiennent à l'utilisateur exécutant (déploiement) avec des autorisations en lecture seule pour cet utilisateur (chmod 400).J'utilise les versions 1.1.x de net-ssh et net-sftp.Je sais que ce ne sont pas les derniers, mais c'est ce que je connais pour le moment.

Qu'est-ce qui pourrait causer l'échec de la tâche cron ?

Était-ce utile?

La solution

Êtes-vous sûr que le fichier temporaire est créé correctement lors de l'exécution en tant que tâche cron ?Le répertoire de travail de votre script sera spécifié soit dans la variable d'environnement HOME, soit dans l'entrée /etc/passwd de l'utilisateur qui a installé la tâche cron.Si le déploiement ne dispose pas d'autorisations d'écriture pour le répertoire dans lequel il s'exécute, vous pouvez spécifier un chemin absolu pour le fichier de vidage afin de résoudre le problème.

Autres conseils

Lorsque les scripts s'exécutent correctement de manière interactive mais pas lorsqu'ils sont exécutés par cron, le problème est généralement dû aux paramètres d'environnement en place...par exemple le PATH comme déjà mentionné par @Ted Percival, mais peut être d'autres variables d'environnement.

En effet, cron n'invoquera pas .bash_profile, .bashrc ou /etc/profile avant de s'exécuter.

La meilleure façon d'éviter cela est de s'assurer que les scripts invoqués par cron ne font aucune hypothèse sur l'environnement lors de leur exécution.Pour surmonter ce problème, il suffit d'inclure quelques lignes dans votre script pour vous assurer que l'environnement est correctement configuré.Par exemple, dans mon cas, j'ai tous les paramètres importants dans /etc/profile (pour RHEL), j'inclurai donc la ligne suivante dans tous les scripts à exécuter sous cron :

source /etc/profile

On dirait que ton PATH il manque quelques répertoires, le plus important /bin (pour /bin/rm).Voici ce que mon système /etc/crontab les usages:

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

Cron envoie-t-il des e-mails avec des journaux ?

Sinon, dirigez la sortie de cron vers un fichier journal.

Assurez-vous de rediriger STDERR vers le journal.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top