Vlad the Deployer - Usage Patterns? - ruby-on-rails

I'm starting to use vlad for new deployments and am wondering what's the best way to set it up so I can use the same tasks for my local development and remote production servers?
I thought about defining everything as remote tasks then having dev/prod methods which set the domain variable, then I can just call rake dev/prod vlad:do_something, but this just feels totally wrong.
Many of my tasks are useful to run on my local server and on my production server and I want to avoid repeating myself by having one 'task' for local and one 'remote_task' for remote. e.g.
def do_something
run "echo something"
end
task :do_something_dev
do_something
end
remote_task do_something_prod
do_something
end
Am I missing something or are these really the only options for using the same rake tasks on both the local and remote machine?

How about this:
[:development, :test, :production].each do |environment|
namespace environment do
task :do_something do
echo "do something on #{environment}"
end
end
end
This will give you:
rake vlad:development:do_something
rake vlad:test:do_something
rake vlad:production:do_something
With just one method it is probably less verbose to do it your way. But as soon as you have 2 or three methods, the overhead can be neglected.

Related

NoMethodError: undefined method `within' for main:Object

I'm trying to make Capistrano deploy script.
In my Capfile I make sure all rake tasks are included
# Load tasks
Dir.glob('config/capistrano_tasks/*.rake').each { |r| import r }
Next I have a 'migrations.rake' containing:
namespace :fileservice do
task :migrate do
within release_path do
info 'Doing migrations'
execute :php, fetch(:symfony_console_path), 'doctrine:migrations:migrate', '--no-interaction', fetch(:symfony_console_flags)
end
end
end
In my deploy.rb I call the task at the very end with:
after 'deploy:publishing', 'fileservice:migrate'
For some reason I keep getting an error saying:
NoMethodError: undefined method `within' for main:Object
I have no idea where to look or what might be wrong... When googling I get a lot of "NoMethodError" hits but none about the 'within' method and most are general Ruby errors.
Where should "within" be defined? I dat a ruby on rails thing? Or capistrano?
Hopefully someone knows where to start looking or which library / script to include!
UPDATE: I just discovered that none of the methods work. When removing lines I got the same error for "info" and "execute".... So I guess somewhere, something is missing.....
You need to tell Capistrano where (i.e. on what servers) to run your SSH commands. Do this using an on block, as follows:
namespace :fileservice do
task :migrate do
on roles(:db) do
within release_path do
info 'Doing migrations'
execute :php, fetch(:symfony_console_path), 'doctrine:migrations:migrate', '--no-interaction', fetch(:symfony_console_flags)
end
end
end
end
Replace roles(:db) as appropriate for your task, depending on where you want the commands to be run. The expression on roles(:all) do ... end, for example, will run the commands on all servers.
You can also follow the official documentation at http://capistranorb.com, or the Capistrano README, both of which show examples of the task/on/execute syntax.
As you already got the answer but Let me put the bulb from basic.
SSHKit was actually developed and released with Capistrano 3, and it’s basically a lower-level tool that provides methods for connecting and interacting with remote servers; it does all the heavy lifting for Capistrano, in other words.
There are four main methods you need to know about.
on(): specifies the server to run on
within(): specifies the directory path to run in
as(): specifies the user to run as
with(): specifies the environment variables to run with
Typically, you’ll start a task by using an on() method to specify the server on which you want your commands to run. Then you can use any combination of as(), within(), and with() methods, which are repeatable and stackable in any order.
Hope this help you

Where do I enqueue jobs into ActiveJob in Rails 4.2?

I am a beginner when it comes to Rails. I am trying to follow this example:
http://ryanselk.com/2014/09/25/using-background-jobs-in-rails-42-with-active-job/
It says:
"Jobs can be added to the job queue from anywhere. We can add a job to the queue by: ResizeImage.perform_later 'http://example.com/ex.png' "
[UPDATE] Sorry, I am stupid. I came up with this task:
namespace :simple do
# call from command line:
# rake simple:resize_images
desc "Resize images"
task resize_images: :environment do
Dir.foreach('storage') do |next_image|
puts next_image
next if next_image == '.' or next_image == '..'
ResizeImage.perform_later next_image
end
end
end
but now I do:
rake simple:resize_images
and I get:
zacek2_phpP9JGif.jpg
rake aborted!
NameError: uninitialized constant ResizeImage
I've tried:
require ResizeImage
but that did not fix the problem.
I am afraid I don't understand how loading works in Rails. How do I load ResizeImage?
Do I set it up as a cron job?
No.
From the rails guides:
Active Job is a framework for declaring jobs and making them run on a variety of queueing backends.
Active Job is an interface to queueing backends such as sidekiq, delayed_job or resque. It's simply a way for you to write background jobs where you don't have to care about which of the queueing backends will be used.
How do I start ActiveJob?
So ActiveJob doesn't run background jobs on it's own. You're still missing one of the backends. Say you have decided to use delayed_job: Get it installed and then start it via:
script/delayed_job start
I don't understand where "anywhere" is.
That means anywhere in your code, you could write something like:
user.rb
def send_registration_email
UserRegistraionMailJob.perform_later self
end

Rake task failing to load :environment properly

I'm running a custom rake task...
namespace :import do
desc "Import terms of service as HTML from stdin"
task :terms => :environment do
html = STDIN.read
settings = ApplicationWideSetting.first
settings.terms_and_conditions = html
if settings.save
puts "Updated terms of service"
else
puts "There was an error updating terms of service"
end
end
end
The model ApplicationWideSetting is reported as undefined when running the task in the production environment. However, when running the task on other environments (ie. development, staging, test.) the task runs fine.
Running the process in rails console, in all environments, completes ok.
Does anyone know what's going on, things I could check?
note: I ran the task with
puts Rails.env
To check the shell environment var RAILS_ENV was getting set/read correctly. I've also tried both with and without the square brackets around the :environment dependency declaration.
additional info: Rails v3.2.14
further info: I've setup a completely fresh rails app, and the script works fine in any environment. Since the install in question is a real production environment, I'll have to setup another deploy and check it thoroughly. More info as I find it.
In a nutshell, Rails doesn't eager load models (or anything else) when running rake tasks on Production.
The simplest way to work with a model is to require it when you begin the rake task, and it should work as expected, in this case:
# explicitly require model
require 'application_wide_setting'
It's possible to eager load the entire rails app with:
Rails.application.eager_load!
However, you may have issues with some initializers (ie. devise)

How to deploy Rails 3 project using "Rake"?

How to deploy Rails project on live server using Rake task?
For other projects I used Capistrano deployment.But for this project I wish to use rake...if anybody guide me please ... What gem I will need to install or what is the procedure I should follow?
You already answered your question yourself:
Either you use capistrano (the recommended way) - or you write your own custom rake Tasks that do what you want.
Writing Rake tasks is nothing complicated, you simply define tasks that depend on each other for each step of your deployment and then run them.
Remember: Rake tasks are just plain Ruby and you therefore can use any Gem that suits your needs.
Only if you get a bit more detailed on what tasks you want to do during your deployment I can start recommending Gems or what Tasks you may need to write.
Article by Martin Fowler on Rake: http://martinfowler.com/articles/rake.html
Generally a Rake file looks pretty much like this:
task :default => [:test]
task :test do
# You can write regular ruby here and do anything you want
puts "Foo"
end
task :dependant => [:test] do
# This task will automatically make sure task test is run before running.
puts "Hello World"
end
Linux or windows? which is the os you are using?
you can follow this refeerence
http://guides.rubyonrails.org/command_line.html
http://www.tutorialspoint.com/ruby-on-rails/rails-and-rake.htm
Just guessing a bit.
You probably would need:
A command line options parser
A way to interact through ssh
Some linux command execution
Optionally a way to interact with git

Set RAILS_ENV for test rake tasks

I've done this patch to my test_helper.rb
ENV["RAILS_ENV"] = ENV["RAILS_ENV_TEST"] || "test"
This works in that I can run
RAILS_ENV_TEST=test_dan ruby -Itest test/unit/post_test.rb
but I want to be able to run all kinds of test things, including rake db:test:clone but not using the environment test. How can I do this?
Most rake tasks that are namespaced with "test" will only run on your test environment and not in other environments. It's hardcoded into the task as to mitigate potentially devastating affects they might have in an environment such as production.
You can see that these tasks don't take into account the environment in which they are called in the source.
If you want to run these tasks in whatever environment you want, your best bet is to recreate these tasks and pass in the environment.
namespace :any_environment_test do
task :load => :environment do
...
task :clone => :environment do
...
In this specific case, it's a little trickier, as it sounds like you want to clone from any environment to any environment. If this is the case, you should probably have two vars that are passed, such as FROM_ENV= and TO_ENV=.
Long story longer, you're going to write custom tasks, but can inspire yourself from the link I posted above. :)

Resources