Capistrano 3: How to store git revision into a file? - capistrano

Is there a way how to fetch a git revision variable from Capistrano 3?
I can't figure out how to access capistrano variables:
namespace :deploy do
after :finished, :set_current_version do
on roles(:app) do
# dump current git version
within release_path do
execute :echo, "#{fetch(:revision_log_message)} >> public/version"
end
end
end
end

This one works
after :finished, :set_current_version do
on roles(:app) do
# dump current git version
within release_path do
execute :echo, "#{capture("cd #{repo_path} && git rev-parse --short HEAD")} >> public/version"
end
end
end

This feature is added in 3.0.1, see their changelog!

Related

How to patch remote source code locally in yocto project?

Sometimes, We meet a situation that remote source code fetched by a recipe need to be modified so that suit a specific machine.
How do we create a patch for remote source code locally? After that everytime we build the recipe (even clean it all) we can patch the remote source code automatically.
For example, I have a special machine with architecture A which is not common, so the remote source code need to be modified so that support architecture A.
Suppose there was a file called utils.h (which is code that we fetched by example.bb from remote git repository)
#if defined(__x86_64__) || \
defined(__mips__) || \
defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) \
#define SOME_FUNCTIONALITY 1
Apparently I need to add archtecture A support in the file.
#if defined(__x86_64__) || \
defined(__mips__) || \
defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) || \
defined(__A__) \
#define SOME_FUNCTIONALITY 1
But if we just modified like that, next time we execute
bitbake -c cleanall example
bitbake example
then we get a unchanged copies again(which means we have to modify it again).
How do we create a Add-architecture-A-support.patch locally so that we can patch the remote source code automatically?
This is a simple one from answers.
(Note: If there was no git in the source code directory, before modifying the source code, you need to create a git repository and commit all in the top directory of the source code.)
git init # create a git repository
git add .
git commit -m "First commit" # first commit
After change the utils.h as above, we can check the git status. It usually looks like that.
$ git status
HEAD detached from 87b933c420
Changes not staged for commit:
(use "git add <file>..." to update what will be comitted)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: ../../utils.h
...
no changes added to commit (use "git add" and/or "git commit -a")
Then we add and commit the change locally (usually we don't have the permission to push to upper stream).
$ git add utils.h
$ git commit -m "Patch test"
After that we can use git to create a patch for the recent commit.
$ git show >Add-architecture-A-support.patch
It will creat a patch in the current directory with contents looks like that
commit a79e523...
Author: 杨...
Date: ...
Patch test
diff --git a/somedir/utils.h b/somedir/utils.h
index 20bfd36c84..
--- a/somedir/utils.h
+++ b/somedir/utils.h
...
+ defined(__A__) \
...
Then we can move the patch to the local layer where the recipe stayed.
recipe-example
|-- example
| |-- Add-architecture-A-support.patch
|-- example.bb
And add the patch in example.bb with this.
SRC_URI += "\
file://Add-architecture-A-support.patch \
"
Work finished. (Also, if want to undo the local commit after creating the patch, you can use git reset HEAD^ utils.h. emmm, I think so, maybe there are some faults, just google it)

Buildbot 'try' command starts a build but does not actually apply patch

When I attempt a buildbot try command, the patch is sent and the build starts, but the patch is never actually applied.
My setup uses SVN, with 2 source control steps:
c['change_source'].append(SVNPoller("%s/trunk/a" % base_url , pollinterval=10))
c['change_source'].append(SVNPoller("%s/trunk/b" % base_url , pollinterval=10))
and...
self.addStep(SVN(repourl="%s/trunk/a" % base_url, workdir="build/a"))
self.addStep(SVN(repourl="%s/trunk/b" % base_url, workdir="build/b"))
These get put into the build directory on the slave like:
build/a/...
build/b/...
Then I attempt to run the 'try' command from my local computer:
svn co '.../trunk/a'
cd a
update some files
buildbot try --vc svn --connect pb -m192.168.0.100:5555 \
-uuser --passwd=pass -w user -C "comment" --topdir="a"
I can see on the server that the patch is generated:
svn update ( 11 secs )
patch
stdio
svn_1 update ( 3 secs )
patch
stdio
and the patch looks correct-ish
Index: mmfx/project/se_lib_tests/mmif_unit_tests.c
===================================================================
--- mmfx/project/se_lib_tests/mmif_unit_tests.c (revision 5952)
+++ mmfx/project/se_lib_tests/mmif_unit_tests.c (working copy)
...
However, the patch is never actually applied to the source files. My suspicion is that buildbot doesn't know how to apply the patch to just the 'build/a' tree -- it attempts to do it to the 'build' tree, and silently fails.
Any ideas how to make this work right?
Thanks,
- Caleb

Echo in capistrano task make empty file

I try to create REVISION file with full commit hash on deploy.
#early..
revision = %x[git rev-parse HEAD]
set :revision, revision
namespace :assets do
task :install do
on roles :all do
puts fetch(:revision, "") #it's good, print ee51dc1308a07cb0dfadd60b2a9d1b3485614034
execute :sh, "-c 'echo #{fetch(:revision, "")} > #{release_path}/REVISION2'"
execute :sh, "-c 'cat #{release_path}/REVISION2'" #empty output
execute :php, "#{release_path}/public/index.php assetic build"
end
end
end
As a result I have file REVISION2 with no content.
Capistrano Version: 3.4.0 (Rake Version: 10.1.0)
Dev machine: Ubuntu 14.04.2 LTS
Deploy to CentOS release 6.4 (Final)
I solve this problem by writing REVISION file on the local and then upload it with the following task
task :save_revision do
revision = %x[git rev-parse HEAD]
File.open("REVISION", 'w') { |file| file.write(revision) }
set :revision, revision #save for future
puts revision #print
on roles :all do
upload! "REVISION", "#{release_path}"
end
end

Capistrano 3: how to get release_name

In Capistrano 2.x the DSL used to provide a variable/method release_name that would return the name of the directory into which the app was just deployed, e.g. 20140225134251, corresponding to .../releases/20140225134251.
I can't seem to find an equivalent for this in cap 3.
Also missing is current_revision, although I've replicated that with
`git rev-parse HEAD`.chomp
Did you try release_path and release_timestamp?

Chef running git clone results in host key verification error

I am using Chef, invoked by Capistrano.
There is a directive to clone a repository using git.
git node['rails']['rails_root'] do
repository "git#myrepo.com:/myproj.git"
reference "master"
action :sync
user node['rails']['rails_user']
group node['rails']['rails_group']
end
When it gets to this point, I get:
** [out :: 10.1.1.1] STDERR: Host key verification failed.
So, I need to add a "known_hosts" entry. No problem. But to which user? The core of my problem is that I have no idea which user is executing what commands, and if they are invoking sudo, etc.
I've run keyscan to populate the known_hosts of root, and the user I ssh in as, to no avail.
Note, this git repo is read-protected, and requires ssh key access.
Another way to solve https://github.com/opscode-cookbooks/ssh_known_hosts
this worked for me
You can use an ssh wrapper approach. Look here for details.
Briefly do the following steps
First, create a file in the cookbooks/COOKBOOK_NAME/files/default directory that is named wrap-ssh4git.sh and which contains the following:
#!/usr/bin/env bash
/usr/bin/env ssh -o "StrictHostKeyChecking=no" $1 $2
Then, use the following block for your deployment:
directory "/tmp/private_code/.ssh" do
owner "ubuntu"
recursive true
end
cookbook_file "/tmp/private_code/wrap-ssh4git.sh" do
source "wrap-ssh4git.sh"
owner "ubuntu"
mode 00700
end
deploy "private_repo" do
repo "git#github.com:acctname/private-repo.git"
user "ubuntu"
deploy_to "/tmp/private_code"
action :deploy
ssh_wrapper "/tmp/private_code/wrap-ssh4git.sh"
end
The git repository will be cloned as user node['rails']['rails_user'] (via https://docs.chef.io/resource_git.html) - I assume that users known_hosts file is the one you have to modify.
I have resolved this issue as below
_home_dir = nil
node['etc']['passwd'].each do |user, data|
if user.eql? node['jenkins']['username']
_home_dir = data['dir']
end
end
key_config ="Host *\n\tStrictHostKeyChecking no\n"
file "#{_home_dir}/.ssh/config" do
owner node['jenkins']['username']
group node['jenkins']['username']
mode "0600"
content key_config
end