Practice 7

This commit is contained in:
Ivan Evtukhovich
2013-09-20 17:29:08 +04:00
parent 53b595c4ac
commit 5fec919ed3
39 changed files with 1305 additions and 3 deletions

View File

@@ -52,3 +52,11 @@ cookbook "redmine",
cookbook "runit",
:git => "git@github.com:express42-cookbooks/runit.git"
cookbook "strano",
:path => "inhouse-cookbooks/strano"
cookbook "chiliproject",
:path => "inhouse-cookbooks/chiliproject"
cookbook "ssh_known_hosts",
:git => "git@github.com:opscode-cookbooks/ssh_known_hosts.git"

View File

@@ -1,3 +1,12 @@
SITE
remote: http://community.opscode.com/api/v1
specs:
build-essential (1.4.2)
partial_search (1.0.2)
rvm (0.0.4)
apt (>= 0)
build-essential (>= 0)
GIT
remote: git@github.com:evilmartians/chef-nginx.git
ref: master
@@ -94,6 +103,14 @@ GIT
specs:
apt (2.1.1)
GIT
remote: git@github.com:opscode-cookbooks/ssh_known_hosts.git
ref: master
sha: c13eed20b074cd377db0daaca76f4c5b58b12830
specs:
ssh_known_hosts (1.0.3)
partial_search (>= 0.0.0)
GIT
remote: https://github.com/fnichol/chef-user.git
ref: master
@@ -120,14 +137,28 @@ PATH
specs:
base (0.1.0)
PATH
remote: inhouse-cookbooks/chiliproject
specs:
chiliproject (0.0.0)
PATH
remote: inhouse-cookbooks/fake
specs:
fake (0.1.0)
PATH
remote: inhouse-cookbooks/strano
specs:
strano (0.0.1)
lvm (>= 0.0.0)
rvm (>= 0.0.0)
sudo (>= 0.0.0)
DEPENDENCIES
apt (>= 0)
base (>= 0)
chiliproject (>= 0)
fake (>= 0)
lvm (>= 0)
nginx (>= 0)
@@ -138,6 +169,8 @@ DEPENDENCIES
redmine (>= 0)
ruby (>= 0)
runit (>= 0)
ssh_known_hosts (>= 0)
strano (>= 0)
sudo (>= 0)
sysctl (>= 0)
timezone (>= 0)

4
Vagrantfile vendored
View File

@@ -3,6 +3,7 @@ Vagrant.configure("2") do |config|
main.vm.box = "ubuntu12.04-chef11-chruby"
main.vm.hostname = "etalon"
config.vm.network :forwarded_port, guest: 8080, host: 7070
config.vm.network :forwarded_port, guest: 80, host: 7071
main.vm.provider :virtualbox do |vb|
vb.customize ["modifyvm", :id, "--memory", "2048"]
end
@@ -14,7 +15,8 @@ Vagrant.configure("2") do |config|
chef.encrypted_data_bag_secret_key_path = "./.chef/encrypted_data_bag_secret"
chef.add_role "base"
chef.add_role "redmine"
chef.add_role "strano"
chef.add_role "chiliproject"
end
end
end

View File

@@ -1,10 +1,20 @@
{
"id": "databases",
"databases": {
"chiliproject": {
"options": {
"owner": "chiliproject"
}
},
"redmine": {
"options": {
"owner": "redmine"
}
},
"strano": {
"options": {
"owner": "strano"
}
}
}
}

View File

@@ -1,6 +1,8 @@
{
"id": "users",
"users": {
"redmine": {}
"redmine": {},
"chiliproject": {},
"strano": {}
}
}

View File

@@ -0,0 +1,15 @@
{
"id": "key",
"public_key": {
"encrypted_data": "G/9a8qKJd8vFp6SPYW6Fm3hLUx1KjbHWsra03bM9sltKTabreznqqYGcLmcr\nRVg4ZZ3OzsOevlClhFPFoLwMguq2QCD5ttdHIoP231MX8AUhm89pPwqt7Wet\narClxd2XB8fNKyaf4xB5Fdh9ZM7H7aXVL+4UW4oxqxrm0bA5B+5UqwYlUF46\nsFmf9dOoJ1XyE2RfISJ5cigPcjqpH8osEY15jPZYZ9PrzzZTke+G32JGKyLp\nqjES0JCx192SBvWpxAIxCEgk3Vvdwz+9Ng3EMSuiIOI6crILSgVoYGysBBBs\nLJ8gv9mpa5YSRCPaGxEC+ssEELym80/dQSYIag7zNqBCDghKfxkTlI19cbkQ\nggMrN62sJ/ly0DwV+Lf4+l2hUOmaRuVlePMpcHp10rgET4wCZouAlL1zzzSq\ncqtUQJDSmFWm1xeq5noEvmGCBqzGIQBRc0J3v4sKSaohJZ3FciMgTys+2gfx\nRZP2Ch2Wb0zkkugzpo1MRYcoLRkAvei9TPysML3FlT2slMBwe3gwdz6DzfYg\nK4tFox4HDCtIxPA3yC4jM+4G4AtmGAImkn6Q\n",
"iv": "DbyIs1H8ClNSrbhCsoDKXg==\n",
"version": 1,
"cipher": "aes-256-cbc"
},
"private_key": {
"encrypted_data": "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\n9UyfSdClvxfXayQEtOWbqACi\n",
"iv": "sjINJ/v1TAAwwsn96TzCNQ==\n",
"version": 1,
"cipher": "aes-256-cbc"
}
}

27
deploy_rsa Normal file
View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAxmlnI8Q4rahslpfcO7TV1EArvtyPLFUpBhdTgI/10Imj5G9Z
IHWtNhErNRppzkBQ9cwrgc/I4/n6tPtiYg7h/aZYfIFQhMrxFfYggIlrHU8DZDQv
WkNj1K6WzsIiomHw+rHJvHK4lbhDmjk4qmmbosGlpOyHd2IqICXq5PVL1NiMdEy+
WQ0EQNABuGRK8q6Pt7+reirE3vVzsVgGYwLlAIJmzq8FLORG7JAdPh0KRUOU5phJ
DMygm5zTGLgkJ8SnN72NnzNryCkTf1x4uRYiof4chdlFcPo+NjzW5Y1DPi42lmKF
BkDtwQovEvJJ7/hk934rfJV7LzDVvtHl82kgmwIDAQABAoIBAGJOIPsYophwJXUr
wsOWYoeqT8JeF1X4z72j2wyMx1dOivSIstkhVPO/5++Eqb22IibWxQupPritx6ja
ELHS++en/pmZnKJexrqB2zK0Y2z/FAgWzwti7liXNEM27uATtMkRQ4nqMUiFJoGI
LmpIrwMh/QdM5gWhjoulHc/ZNXw7+lo0lLsBa1KwgsZ217fmEQ0s4fgCl5FDiVlG
uEbpR5+1LJyrHFvcwz2fB7L3PJ9g0w5LCQQPiQIwu4wo4U5yD3BUUyNFPcY6+lvQ
rWvbBQaVUIEd7C3Swu7Expv0XON7Ai/BNIXo0MN0vBVzq6GjmWu86ovQsYpfMT19
3ksLQzkCgYEA+KTfmdRjXmb906c6EiW4UzjbWWeI9Nb8oXWuJjCcfWj6g45LJTpt
b36mLTnVfmcsDvdYDKmuWYlJfb+44QzrFjfrWa+UbBdjwV3pXzJel043uzNJPA63
k+pDX+XTw2mrIWc0AJhE/QzLLML8tIFPnGPzFrKWxE9AqzTYmIMg4C0CgYEAzEgX
QVxp9Wo3jlymIfJzp5rvhcbQxdacE9A0ZoLJ0TCTZ1Usp8QpKPpdSQTM4hLjIX/5
3HpjKsc5mCY2koJxMxEWvgjczwTlAnsM7fygP4Kmdxg3zhEijEM5v2ZBdZ0ewxMi
qFsdey8E4l11ZdWZLDwbh2Jt7jg5jZhyq3qpOOcCgYBmNYAlAAWI/NVCd++LHi5T
J4AjlEfcPbPDu1hHIpxxgQHZqliBiS8LMgildqyoNUkLLenn6qhc7e5j3rfk6yaI
D5yTVXWxqTu8dRpFo7L2h5SpQz/LjFEyYI4pkZQnM/zA0meyBuX1D5lFYTH4EV/k
bcGzht4q/FkdB7AxoVWWUQKBgBEn/MwAduWlhgTuwwUW15+742HY0K/M1k7TrZLu
aQSoj7id7qIoV0yZujvnq01RSMIHfXSG0s1E7hFZJDwpuFgRl1deZyz7vD/5FZzn
Go466sAVyJoF1mDxRGhOrjCygWLguIhrHo655C8eqj1jMvoEEkvMeG8JScwagYbl
RlEBAoGBAKzWXsEbsLLjNyj8EmGJF+o74al38YdBY2zlyZ1VYCyTtXn0ZNxVi2iQ
ttwOgpEI+icGzDgU5AFkWlJIAouEGPmT+tAquce41ythm6lbg406/rJGtl01UnlQ
WQ+s0itRYeBnm6n7xqkk0p6f8CECUVthhOa+iZcYSOt5q9Ds5RvV
-----END RSA PRIVATE KEY-----

1
deploy_rsa.pub Normal file
View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGaWcjxDitqGyWl9w7tNXUQCu+3I8sVSkGF1OAj/XQiaPkb1kgda02ESs1GmnOQFD1zCuBz8jj+fq0+2JiDuH9plh8gVCEyvEV9iCAiWsdTwNkNC9aQ2PUrpbOwiKiYfD6scm8criVuEOaOTiqaZuiwaWk7Id3YiogJerk9UvU2Ix0TL5ZDQRA0AG4ZEryro+3v6t6KsTe9XOxWAZjAuUAgmbOrwUs5EbskB0+HQpFQ5TmmEkMzKCbnNMYuCQnxKc3vY2fM2vIKRN/XHi5FiKh/hyF2UVw+j42PNbljUM+LjaWYoUGQO3BCi8S8knv+GT3fit8lXsvMNW+0eXzaSCb brun@Ivans-MacBook-Pro.local

View File

@@ -0,0 +1,13 @@
default["chiliproject"]["application"]["lvm_volume"] = "chiliproject-application"
default["chiliproject"]["application"]["lvm_group"] = "shared"
default["chiliproject"]["application"]["volume_size"] = "2GB"
default["chiliproject"]["application"]["rails_environment"] = "development"
default["chiliproject"]["application"]["application_user"] = "chiliproject"
default["chiliproject"]["application"]["application_directory"] = "/srv/chiliproject-application"
default["chiliproject"]["application"]["database_name"] = "chiliproject"
default["chiliproject"]["application"]["github_key"] = ""
default["chiliproject"]["application"]["github_secret"] = ""
default["chiliproject"]["application"]["create_partitions"] = "yes"
default["chiliproject"]["application"]['secret'] = '63c894873708c4d4a0d4ce7aa86b7b9638355d65082999bf806eae8d42a2c1f81de08df74349ebb1'
default["chiliproject"]["ruby_version"] = "1.9.3-p448"

View File

@@ -0,0 +1 @@
name "chiliproject"

View File

@@ -0,0 +1,199 @@
#
# Cookbook Name:: chiliproject
# Recipe:: application
#
# Copyright 2012, LLC Express 42
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
class Chef::Recipe
include Express42::Base::Network
end
if Chef::Config[:solo]
Chef::Log.warn("This recipe uses search. Chef Solo does not support search. I will return current node")
application_nodes = [ node ]
else
application_nodes = search(:node, "role:application AND chef_environment:#{node.chef_environment}")
frontend_nodes = search(:node, "role:chiliproject-frontend AND chef_environment:#{node.chef_environment}")
end
application_servers_ip = application_nodes.map{|node| net_get_all_ip(node)}.flatten.uniq
if frontend_nodes
frontend_servers_ip = frontend_nodes.map{|server| net_get_public(server)[0][1] }
frontend_servers_ip.flatten!
else
frontend_servers_ip = []
end
block_device = "/dev/#{node["chiliproject"]["application"]["lvm_group"]}/#{node["chiliproject"]["application"]["lvm_volume"]}"
user = node["chiliproject"]["application"]["application_user"]
application_directory = node["chiliproject"]["application"]["application_directory"]
rails_environment = node["chiliproject"]["application"]["rails_environment"]
lvm_volume = node["chiliproject"]["application"]["lvm_volume"]
lvm_group = node["chiliproject"]["application"]["lvm_group"]
lvm_size = node["chiliproject"]["application"]["volume_size"]
%w(libpq5 libpq-dev imagemagick libmagickwand-dev).each { |p| package p }
partition lvm_volume do
group lvm_group
size lvm_size
filesystem 'ext4'
mount_point application_directory
create_partition node["chiliproject"]["application"]["create_partitions"] == "yes"
end
key = Chef::EncryptedDataBagItem.load('deploy-key', 'key')
user_account user do
ssh_keys key['public_key']
end
directory application_directory do
owner user
group user
end
directory "#{application_directory}/shared" do
owner user
group user
end
directory "#{application_directory}/shared/config" do
owner user
group user
end
link "/home/#{user}/#{lvm_volume}" do
to "#{application_directory}"
end
app_path = "/home/#{user}/#{lvm_volume}/current"
ruby_install node["chiliproject"]["ruby_version"] do
action :install
end
ruby_set node["chiliproject"]["ruby_version"] do
username user
end
template "#{application_directory}/shared/config/database.yml" do
source 'database.yml.erb'
owner user
group user
variables :db_name => node["chiliproject"]["application"]["database_name"]
end
template "#{application_directory}/shared/config/chiliproject.yml" do
source 'settings.yml.erb'
owner user
group user
end
template "#{application_directory}/shared/config/Gemfile" do
owner user
group user
end
template "#{application_directory}/shared/config/session_store.rb" do
owner user
group user
variables :secret => node["chiliproject"]["application"]["secret"]
end
template "#{application_directory}/shared/config/unicorn.rb" do
source 'unicorn.rb.erb'
owner user
group user
variables :app_path => app_path,
:user => user,
:timeout => 30,
:worker_processes => 2,
:listen => "/tmp/chiliproject-rails.sock"
end
sysctl(
"kernel.msgmax" => "65536",
"kernel.shmall" => "4294967296",
"kernel.shmmax" => "68719476736",
"kernel.msgmnb" => "65536",
"vm.swappiness" => "0",
"vm.overcommit_memory" => "0",
"fs.file-max" => "1048576"
)
postgresql "main" do
databag "db"
configuration(
:version => "9.1",
:resources => {
:shared_buffers => "32MB",
:max_connections => 10
}
)
hba_configuration(
[
{ :type => "host", :database => "all", :user => "all", :address => "127.0.0.1/32", :method => "trust" },
]
)
end
runit_service "chiliproject_rails" do
template_name "chiliproject"
run_restart false
options :home_path => "/home/#{user}",
:app_path => app_path,
:target_user => user,
:target_ruby => "default",
:target_env => "production"
end
sudo "chiliproject" do
user user
commands ["/usr/bin/sv * chiliproject_*"]
host "ALL"
nopasswd true
end
nginx_site "chiliproject" do
variables :app_path => application_directory,
:application_servers_ip => application_servers_ip,
:frontend_servers_ip => frontend_servers_ip,
:backend => "unix:/tmp/chiliproject-rails.sock",
:vagrant_port => node["chiliproject"]["application"]["vagrant_port"]
end
ssh_known_hosts_entry 'github.com'
# key = Chef::EncryptedDataBagItem.load('deploy-key', 'key')
#
# file "/home/#{user}/.ssh/id_rsa" do
# content key['private_key']
# owner user
# group user
# mode '0600'
# end

View File

@@ -0,0 +1,106 @@
# -*- coding: utf-8 -*-
source "https://rubygems.org"
gem "rails", "2.3.18"
gem "unicorn"
gem "rake"
gem "json", "~> 1.7.7"
gem "coderay", "~> 1.0.0"
gem "i18n", "~> 0.4.2"
gem "rubytree", "~> 0.5.2", :require => 'tree'
gem "rdoc", ">= 2.4.2"
gem "liquid", "~> 2.3.0"
gem "acts-as-taggable-on", "= 2.1.0"
gem 'gravatarify', '~> 3.0.0'
gem "tzinfo", "~> 0.3.31" # Fixes #903. Not required for Rails >= 3.2
group :test do
gem 'shoulda', '~> 2.10.3'
# Shoulda doesn't work nice on 1.9.3 and seems to need test-unit explicitely…
gem 'test-unit', :platforms => [:mri_19]
gem 'edavis10-object_daddy', :require => 'object_daddy'
gem 'mocha', '0.12.1'
gem 'capybara'
gem 'nokogiri'
gem 'coveralls', :require => false
end
group :ldap do
gem "net-ldap", '~> 0.3.1'
end
group :openid do
gem "ruby-openid", '~> 2.1.4', :require => 'openid'
end
group :rmagick do
gem "rmagick", ">= 1.15.17"
# Older distributions might not have a sufficiently new ImageMagick version
# for the current rmagick release (current rmagick is rmagick 2, which
# requires ImageMagick 6.4.9 or later). If this is the case for you, comment
# the line above this comment block and uncomment the one underneath it to
# get an rmagick version known to work on older distributions.
#
# The following distributions are known to *not* ship with a usable
# ImageMagick version. There might be additional ones.
# * Ubuntu 9.10 and older
# * Debian Lenny 5.0 and older
# * CentOS 5 and older
# * RedHat 5 and older
#
#gem "rmagick", "< 2.0.0"
end
# Use the commented pure ruby gems, if you have not the needed prerequisites on
# board to compile the native ones. Note, that their use is discouraged, since
# their integration is propbably not that well tested and their are slower in
# orders of magnitude compared to their native counterparts. You have been
# warned.
platforms :mri, :mingw, :rbx do
# keep mysql group as backwards compat
group :mysql2, :mysql do
gem "mysql2", "~> 0.2.7"
end
group :postgres do
gem "pg"
# gem "postgres-pr"
end
group :sqlite do
gem "sqlite3"
end
end
platforms :jruby do
gem "jruby-openssl"
group :mysql do
gem "activerecord-jdbcmysql-adapter"
end
group :postgres do
gem "activerecord-jdbcpostgresql-adapter"
end
group :sqlite do
gem "activerecord-jdbcsqlite3-adapter"
end
end
# Load a "local" Gemfile
gemfile_local = File.join(File.dirname(__FILE__), "Gemfile.local")
if File.readable?(gemfile_local)
puts "Loading #{gemfile_local} ..." if $DEBUG
instance_eval(File.read(gemfile_local))
end
# Load plugins' Gemfiles
["plugins", "chiliproject_plugins"].each do |plugin_path|
Dir.glob File.expand_path("../vendor/#{plugin_path}/*/Gemfile", __FILE__) do |file|
puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v`
instance_eval File.read(file)
end
end

View File

@@ -0,0 +1,49 @@
upstream chiliproject-unicorn-app {
server <%= @backend %>;
}
server {
listen 8080;
# server_name deploy.fake.ru;
resolver_timeout 2s;
charset utf-8;
root <%= @app_path %>/current/public/;
<% @frontend_servers_ip.each do |ip| -%>
set_real_ip_from <%= ip %>;
<% end -%>
access_log /var/log/nginx/strano-access.log;
error_log /var/log/nginx/strano-error.log;
client_max_body_size 256m;
gzip_static on;
location / {
try_files $uri /system/maintenance.html @unicorn;
}
location ^~ /system/ {
root <%= @app_path %>/current/public/;
}
location @unicorn {
satisfy any;
<% @application_servers_ip.each do |ip| -%>
allow <%= ip %>;
<% end -%>
proxy_pass http://chiliproject-unicorn-app;
proxy_redirect off;
proxy_set_header Host $host<%= ":#{@vagrant_port}" if @vagrant_port -%>;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 300;
proxy_buffer_size 16k;
proxy_buffers 32 16k;
}
}

View File

@@ -0,0 +1,12 @@
# MySQL (default setup). Versions 4.1 and 5.0 are recommended.
#
# Get the fast C bindings:
# gem install mysql
# (on OS X: gem install mysql -- --include=/usr/local/lib)
# And be sure to use new-style password hashing:
# http://dev.mysql.com/doc/refman/5.0/en/old-client.html
production:
adapter: postgresql
database: redmine
encoding: utf8

View File

@@ -0,0 +1,2 @@
# Redmine
-A FWR -p tcp -m tcp --dport 3000 -j ACCEPT

View File

@@ -0,0 +1,21 @@
# This file was generated by 'rake config/initializers/session_store.rb',
# and should not be made visible to public.
# If you have a load-balancing Redmine cluster, you will need to use the
# same version of this file on each machine. And be sure to restart your
# server when you modify this file.
# Your secret key for verifying cookie session data integrity. If you
# change this key, all old sessions will become invalid! Make sure the
# secret is at least 30 characters and all random, no regular words or
# you'll be exposed to dictionary attacks.
ActionController::Base.session = {
:key => '_chiliproject_session',
#
# Uncomment and edit the :session_path below if are hosting your Redmine
# at a suburi and don't want the top level path to access the cookies
#
# See: http://www.redmine.org/issues/3968
#
# :session_path => '/url_path_to/your/redmine/',
:secret => '<%= @secret %>'
}

View File

@@ -0,0 +1,142 @@
# redMine - project management software
# Copyright (C) 2006-2007 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# DO NOT MODIFY THIS FILE !!!
# Settings can be defined through the application in Admin -> Settings
app_title:
default: Redmine
app_subtitle:
default: Project management
welcome_text:
default:
login_required:
default: 0
self_registration:
default: '2'
lost_password:
default: 1
attachment_max_size:
format: int
default: 5120
issues_export_limit:
format: int
default: 500
activity_days_default:
format: int
default: 30
per_page_options:
default: '25,50,100'
mail_from:
default: redmine@example.net
bcc_recipients:
default: 1
plain_text_mail:
default: 0
text_formatting:
default: textile
wiki_compression:
default: ""
default_language:
default: en
host_name:
default: localhost:3000
protocol:
default: http
feeds_limit:
format: int
default: 15
diff_max_lines_displayed:
format: int
default: 1500
enabled_scm:
serialized: true
default:
- Subversion
- Darcs
- Mercurial
- Cvs
- Bazaar
- Git
autofetch_changesets:
default: 1
sys_api_enabled:
default: 0
commit_ref_keywords:
default: 'refs,references,IssueID'
commit_fix_keywords:
default: 'fixes,closes'
commit_fix_status_id:
format: int
default: 0
commit_fix_done_ratio:
default: 100
# autologin duration in days
# 0 means autologin is disabled
autologin:
format: int
default: 0
# date format
date_format:
default: ''
time_format:
default: ''
user_format:
default: :firstname_lastname
format: symbol
cross_project_issue_relations:
default: 0
notified_events:
serialized: true
default:
- issue_added
- issue_updated
mail_handler_api_enabled:
default: 0
mail_handler_api_key:
default:
issue_list_default_columns:
serialized: true
default:
- tracker
- status
- priority
- subject
- assigned_to
- updated_on
display_subprojects_issues:
default: 1
default_projects_public:
default: 1
sequential_project_identifiers:
default: 0
# encodings used to convert repository files content to UTF-8
# multiple values accepted, comma separated
repositories_encodings:
default: ''
# encoding used to convert commit logs to UTF-8
commit_logs_encoding:
default: 'UTF-8'
ui_theme:
default: ''
emails_footer:
default: |-
You have received this notification because you have either subscribed to it, or are involved in it.
To change your notification preferences, please click here: http://hostname/my/account
gravatar_enabled:
default: 0

View File

@@ -0,0 +1,4 @@
#!/bin/sh
LOG_FOLDER=/var/log/runit/<%= @service_name %>/
mkdir -p $LOG_FOLDER
exec svlogd -tt $LOG_FOLDER

View File

@@ -0,0 +1,31 @@
#!/bin/sh
set -e
ulimit -n 8192
HOME_PATH=<%= @options[:home_path] %>
APP_PATH=<%= @options[:app_path] %>
TARGET_USER=<%= @options[:target_user] %>
TARGET_RUBY=<%= @options[:target_ruby] == "default" ? "`cat /home/$TARGET_USER/.ruby-version`" : @options[:target_ruby] %>
RAILS_ENV=<%= @options[:target_env] %>
UNICORN_NAME=<%= @options[:unicorn_name] ? @options[:unicorn_name] : "unicorn" %>
UNICORN_PID_FILE=$APP_PATH/tmp/pids/$UNICORN_NAME.pid
CHRUBY_BIN=/opt/chruby/bin/chruby-exec
test -f $UNICORN_PID_FILE && UNICORN_PID=`cat $UNICORN_PID_FILE` || UNICORN_PID=-1
cd $APP_PATH
EXISTING_PID=`pgrep -f 'unicorn_rails master'` && test "$EXISTING_PID" = "$UNICORN_PID" || HOME=$HOME_PATH chpst -u $TARGET_USER $CHRUBY_BIN $TARGET_RUBY -- bundle exec unicorn_rails -c config/$UNICORN_NAME.rb -E $RAILS_ENV
# forward signals received in this wrapper to the Unicorn process:
for sig in HUP USR1 USR2 QUIT TERM QUIT
do
trap 'kill -'$sig' $(cat $UNICORN_PID_FILE)' $sig
done
# loop forever while Unicorn has its pid file
while ( test -e $UNICORN_PID_FILE && ps -p `cat $UNICORN_PID_FILE` > /dev/null ) || ( test -e $UNICORN_PID_FILE.oldbin && ps -p `cat $UNICORN_PID_FILE.oldbin` > /dev/null )
do
sleep 1
done

View File

@@ -0,0 +1,42 @@
WORK_DIR = "<%= @app_path %>"
<% if @prefix -%>
PREFIX = "<%= @prefix -%>-"
<% else -%>
PREFIX = ""
<% end -%>
worker_processes <%= @worker_processes %>
working_directory WORK_DIR
user "<%= @user %>"
preload_app true
timeout <%= @timeout %>
listen "<%= @listen %>", :backlog => 4096
pid "#{WORK_DIR}/tmp/pids/#{PREFIX}unicorn.pid"
stderr_path "#{WORK_DIR}/log/#{PREFIX}unicorn.stderr.log"
stdout_path "#{WORK_DIR}/log/#{PREFIX}unicorn.stdout.log"
before_exec do |_|
ENV["BUNDLE_GEMFILE"] = "#{WORK_DIR}/Gemfile"
end
before_fork do |server, worker|
old_pid = "#{WORK_DIR}/tmp/pids/#{PREFIX}unicorn.pid.oldbin"
if File.exists?(old_pid) && server.pid != old_pid
begin
#Process.kill("QUIT", File.read(old_pid).to_i)
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
end
after_fork do |server, worker|
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end

View File

@@ -1,4 +1,4 @@
zabbix_connect "connect to kupikupon zabbix" do
zabbix_connect "connect to zabbix" do
apiurl "http://127.0.0.1/api_jsonrpc.php"
user "Admin"
password "zabbix"

View File

@@ -0,0 +1,11 @@
default["strano"]["application"]["lvm_volume"] = "strano-application"
default["strano"]["application"]["lvm_group"] = "shared"
default["strano"]["application"]["volume_size"] = "2GB"
default["strano"]["application"]["rails_environment"] = "production"
default["strano"]["application"]["application_user"] = "strano"
default["strano"]["application"]["application_directory"] = "/srv/strano-application"
default["strano"]["application"]["database_name"] = "strano"
default["strano"]["application"]["github_key"] = ""
default["strano"]["application"]["github_secret"] = ""
default["strano"]["application"]["create_partitions"] = "yes"
default["strano"]["ruby_version"] = "1.9.3-p448"

View File

@@ -0,0 +1,8 @@
maintainer "LLC Express 42"
maintainer_email "info@express42.com"
license "Copyright"
description "Deploy Strano Application"
version "0.0.1"
depends "sudo"
depends "rvm"
depends "lvm"

View File

@@ -0,0 +1,225 @@
#
# Cookbook Name:: strano
# Recipe:: application
#
# Copyright 2012, LLC Express 42
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
class Chef::Recipe
include Express42::Base::Network
end
if Chef::Config[:solo]
Chef::Log.warn("This recipe uses search. Chef Solo does not support search. I will return current node")
postgresql_master_node = node
application_nodes = [ node ]
else
postgresql_master_node = search(:node, "role:postgresql-master AND chef_environment:#{node.chef_environment}").first
application_nodes = search(:node, "role:application AND chef_environment:#{node.chef_environment}")
frontend_nodes = search(:node, "role:strano-frontend AND chef_environment:#{node.chef_environment}")
end
postgresql_master_server = net_get_private(postgresql_master_node)[0][1]
application_servers_ip = application_nodes.map{|node| net_get_all_ip(node)}.flatten.uniq
if frontend_nodes
frontend_servers_ip = frontend_nodes.map{|server| net_get_public(server)[0][1] }
frontend_servers_ip.flatten!
else
frontend_servers_ip = []
end
block_device = "/dev/#{node["strano"]["application"]["lvm_group"]}/#{node["strano"]["application"]["lvm_volume"]}"
user = node["strano"]["application"]["application_user"]
application_directory = node["strano"]["application"]["application_directory"]
rails_environment = node["strano"]["application"]["rails_environment"]
lvm_volume = node["strano"]["application"]["lvm_volume"]
lvm_group = node["strano"]["application"]["lvm_group"]
lvm_size = node["strano"]["application"]["volume_size"]
partition lvm_volume do
group lvm_group
size lvm_size
filesystem 'ext4'
mount_point application_directory
create_partition node["strano"]["application"]["create_partitions"] == "yes"
end
user_account user
directory "#{application_directory}/" do
owner user
group user
end
link "/home/#{user}/#{lvm_volume}" do
to "#{application_directory}"
end
ruby_install node["strano"]["ruby_version"] do
action :install
end
ruby_set node["strano"]["ruby_version"] do
username user
end
git "#{application_directory}/current" do
user user
group user
repository "git://github.com/express42/strano.git"
reference "v_0_1"
action :sync
end
template "#{application_directory}/current/config/database.yml" do
source 'database.yml.erb'
owner user
group user
variables :db_name => node["strano"]["application"]["database_name"],
:password => "dbpassword",
:username => "dbuser",
:host => postgresql_master_server
end
template "#{application_directory}/current/config/strano.yml" do
source 'strano.yml.erb'
owner user
group user
end
template "#{application_directory}/current/config/unicorn.rb" do
source 'unicorn.rb.erb'
owner user
group user
variables :app_path => application_directory,
:worker_processes => 2,
:listen => "/tmp/strano-rails.sock"
end
template "/home/#{user}/.ssh/config" do
source 'ssh_config'
owner user
group user
end
execute "bundle install" do
cwd "#{application_directory}/current"
command "/opt/chruby/bin/chruby-exec #{node["strano"]["ruby_version"]} -- bundle install --deployment"
creates "#{application_directory}/current/deploy.lock"
user user
group user
environment 'HOME' => "/home/#{user}"
end
sysctl(
"kernel.msgmax" => "65536",
"kernel.shmall" => "4294967296",
"kernel.shmmax" => "68719476736",
"kernel.msgmnb" => "65536",
"vm.swappiness" => "0",
"vm.overcommit_memory" => "0",
"fs.file-max" => "1048576"
)
postgresql "main" do
databag "db"
end
execute "db migrations" do
cwd "#{application_directory}/current"
command "/opt/chruby/bin/chruby-exec #{node["strano"]["ruby_version"]} -- bundle exec rake db:migrate"
creates "#{application_directory}/current/deploy.lock"
user user
group user
environment 'HOME' => "/home/#{user}", 'RAILS_ENV' => rails_environment
end
execute "assets precompile" do
cwd "#{application_directory}/current"
command "/opt/chruby/bin/chruby-exec #{node["strano"]["ruby_version"]} -- bundle exec rake assets:precompile"
creates "#{application_directory}/current/deploy.lock"
user user
group user
environment 'HOME' => "/home/#{user}", 'RAILS_ENV' => rails_environment
end
execute "create deploy lock" do
cwd "#{application_directory}/current"
command "touch #{application_directory}/current/deploy.lock"
user user
group user
end
runit_service "strano_rails" do
template_name "rails_app"
run_restart false
options :home_path => "/home/#{user}",
:app_path => "#{application_directory}",
:target_user => user,
:target_ruby => "default",
:target_env => rails_environment
end
template "#{node[:nginx][:directories][:conf_dir]}/strano-site-htpasswd" do
source "strano-site-htpasswd.erb"
owner "www-data"
group "www-data"
mode 0640
end
runit_service "strano-worker-1" do
run_restart false
template_name "strano-worker"
options "home_path" => "/home/#{user}",
"app_path" => application_directory,
"target_user" => user,
"target_ruby" => "default",
"target_env" => rails_environment
end
sudo "strano" do
user user
commands ["/usr/bin/sv * strano_*"]
host "ALL"
nopasswd true
end
nginx_site "nginx-strano-application" do
variables :app_path => application_directory,
:application_servers_ip => application_servers_ip,
:frontend_servers_ip => frontend_servers_ip,
:backend => "unix:/tmp/strano-rails.sock",
:vagrant_port => node["strano"]["application"]["vagrant_port"]
end
ssh_known_hosts_entry 'github.com'
key = Chef::EncryptedDataBagItem.load('deploy-key', 'key')
file "/home/#{user}/.ssh/id_rsa" do
content key['private_key']
owner user
group user
mode '0600'
end

View File

@@ -0,0 +1,25 @@
#
# Cookbook Name:: strano
# Recipe:: default
#
# Copyright 2012, LLC Express 42
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#

View File

@@ -0,0 +1,54 @@
#
# Cookbook Name:: strano
# Recipe:: frontend
#
# Author:: LLC Express 42 (info@express42.com)
#
# Copyright (C) LLC 2012 Express 42
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
backend_servers = []
backend_nodes = []
if Chef::Config[:solo]
Chef::Log.warn("This recipe uses search. Chef Solo does not support search. I will return current node")
backend_nodes = [ node ]
else
backend_nodes = search(:node, "role:strano-backend AND chef_environment:#{node.chef_environment}")
end
backend_nodes.each do |item|
if net_get_public(item).empty?
backend_servers << [ net_get_private(item)[0][1], item[:fqdn] ]
else
backend_servers << [ net_get_public(item)[0][1], item[:fqdn] ]
end
end
template "#{node[:nginx][:directories][:conf_dir]}/sites-available/nginx-frontend-strano.conf" do
source "nginx-frontend-strano.erb"
mode "0644"
variables :app_path => node["strano"]["application"]["application_directory"],
:backend_servers => backend_servers
notifies :reload, resources(:service => "nginx")
end
nginx_site "nginx-frontend-strano"

View File

@@ -0,0 +1,4 @@
production:
adapter: postgresql
database: <%= @db_name %>

View File

@@ -0,0 +1,43 @@
upstream strano_backend {
<% @backend_servers.each do |server| %>
server <%= server[0] %> fail_timeout=60s; # Host: <%= server[1] %>
<% end %>
}
server {
listen 80;
server_name _ "";
return 301 $scheme://fake.ru$request_uri;
}
server {
listen 80;
server_name ~^deploy\..+;
resolver_timeout 3s;
charset utf-8;
root <%= @app_path %>/current/public/;
access_log /var/log/nginx/strano-access.log;
error_log /var/log/nginx/strano-error.log;
client_max_body_size 256m;
gzip_static on;
location / {
try_files $uri /system/maintenance.html @upstream;
}
location @upstream {
proxy_pass http://strano_backend;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 300;
proxy_buffer_size 16k;
proxy_buffers 32 16k;
}
}

View File

@@ -0,0 +1,48 @@
upstream unicorn-app {
server <%= @backend %>;
}
server {
listen 80;
# server_name deploy.fake.ru;
resolver_timeout 2s;
charset utf-8;
root <%= @app_path %>/current/public/;
<% @frontend_servers_ip.each do |ip| -%>
set_real_ip_from <%= ip %>;
<% end -%>
access_log /var/log/nginx/strano-access.log;
error_log /var/log/nginx/strano-error.log;
client_max_body_size 256m;
gzip_static on;
location / {
try_files $uri /system/maintenance.html @unicorn;
}
location ^~ /system/ {
root <%= @app_path %>/current/public/;
}
location @unicorn {
satisfy any;
<% @application_servers_ip.each do |ip| -%>
allow <%= ip %>;
<% end -%>
proxy_pass http://unicorn-app;
proxy_redirect off;
proxy_set_header Host $host<%= ":#{@vagrant_port}" if @vagrant_port -%>;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 300;
proxy_buffer_size 16k;
proxy_buffers 32 16k;
}
}

View File

@@ -0,0 +1,3 @@
Host github.com
User git
StrictHostKeyChecking false

View File

@@ -0,0 +1 @@
express42:$apr1$oc5y1WUf$9Rdm4v.itxrAX8DHVhCYm/

View File

@@ -0,0 +1,6 @@
production:
public_ssh_key: MYPUBLICKEY
github_key: <%= node["strano"]["application"]["github_key"] %>
github_secret: <%= node["strano"]["application"]["github_secret"] %>
allow_organizations:
allow_users: true

View File

@@ -0,0 +1,4 @@
#!/bin/sh
LOG_FOLDER=/var/log/runit/<%= @service_name %>/
mkdir -p $LOG_FOLDER
exec svlogd -tt $LOG_FOLDER

View File

@@ -0,0 +1,30 @@
#!/bin/sh
set -e
HOME_PATH=<%= @options[:home_path] %>
APP_PATH=<%= @options[:app_path] %>
TARGET_USER=<%= @options[:target_user] %>
TARGET_RUBY=<%= @options[:target_ruby] == "default" ? "`cat /home/$TARGET_USER/.ruby-version`" : @options[:target_ruby] %>
RAILS_ENV=<%= @options[:target_env] %>
UNICORN_NAME=<%= @options[:unicorn_name] ? @options[:unicorn_name] : "unicorn" %>
UNICORN_PID_FILE=$APP_PATH/current/tmp/pids/unicorn.pid
CHRUBY_BIN=/opt/chruby/bin/chruby-exec
test -f $UNICORN_PID_FILE && UNICORN_PID=`cat $UNICORN_PID_FILE` || UNICORN_PID=-1
export rvm_ignore_rvmrc=1
cd $APP_PATH/current
EXISTING_PID=`pgrep -f 'unicorn_rails master'` && test "$EXISTING_PID" = "$UNICORN_PID" || HOME=$HOME_PATH chpst -u $TARGET_USER $CHRUBY_BIN $TARGET_RUBY -- bundle exec unicorn_rails -c config/$UNICORN_NAME.rb -E $RAILS_ENV
# forward signals received in this wrapper to the Unicorn process:
for sig in HUP USR1 USR2 QUIT TERM QUIT
do
trap 'kill -'$sig' $(cat $UNICORN_PID_FILE)' $sig
done
# loop forever while Unicorn has its pid file
while ( test -e $UNICORN_PID_FILE && ps -p `cat $UNICORN_PID_FILE` > /dev/null ) || ( test -e $UNICORN_PID_FILE.oldbin && ps -p `cat $UNICORN_PID_FILE.oldbin` > /dev/null )
do
sleep 1
done

View File

@@ -0,0 +1,4 @@
#!/bin/sh
LOG_FOLDER=/var/log/runit/<%= @service_name %>/
mkdir -p $LOG_FOLDER
exec svlogd -tt $LOG_FOLDER

View File

@@ -0,0 +1,17 @@
#!/bin/bash
set -e
HOME_PATH=<%= @options['home_path'] %>
APP_PATH=<%= @options['app_path'] %>
TARGET_USER=<%= @options['target_user'] %>
TARGET_RUBY=<%= @options['target_ruby'] == "default" ? "`cat /home/$TARGET_USER/.ruby-version`" : @options['target_ruby'] %>
<% if @options.has_key? 'memlimit' -%>
ulimit -v <%= @options['memlimit'] -%>
<% end -%>
CHRUBY_BIN=/opt/chruby/bin/chruby-exec
export rvm_ignore_rvmrc=1
cd $APP_PATH/current
HOME=$HOME_PATH RAILS_ENV="<%= @options['target_env'] %>" STDOUT=1 chpst -u $TARGET_USER $CHRUBY_BIN $TARGET_RUBY -- bundle exec rake bg:worker --trace

View File

@@ -0,0 +1,74 @@
# unicorn_rails -c <path_to>/current/config/unicorn.rb -E production -D
rails_env = ENV['RAILS_ENV'] || 'production'
worker_processes <%= @worker_processes %>
# Load rails+github.git into the master before forking workers
# for super-fast worker spawn times
preload_app true
# Restart any workers that haven't responded in 120 seconds
timeout 120
# Listen on a Unix data socket
listen '<%= @listen %>', :backlog => 2048
stderr_path "<%= @app_path %>/current/log/unicorn.stderr.log"
stdout_path "<%= @app_path %>/current/log/unicorn.stdout.log"
##
# REE
# http://www.rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
#if GC.respond_to?(:copy_on_write_friendly=)
# GC.copy_on_write_friendly = true
#end
before_fork do |server, worker|
##
# When sent a USR2, Unicorn will suffix its pidfile with .oldbin and
# immediately start loading up a new version of itself (loaded with a new
# version of our app). When this new Unicorn is completely loaded
# it will begin spawning workers. The first worker spawned will check to
# see if an .oldbin pidfile exists. If so, this means we've just booted up
# a new Unicorn and need to tell the old one that it can now die. To do so
# we send it a QUIT.
#
# Using this method we get 0 downtime deploys.
old_pid = File.join(Rails.root, '/tmp/pids/unicorn.pid.oldbin')
if File.exists?(old_pid) && server.pid != old_pid
begin
Process.kill("QUIT", File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
end
after_fork do |server, worker|
##
# Unicorn master loads the app then forks off workers - because of the way
# Unix forking works, we need to make sure we aren't using any of the parent's
# sockets, e.g. db connection
ActiveRecord::Base.establish_connection
# CHIMNEY.client.connect_to_server
# Redis and Memcached would go here but their connections are established
# on demand, so the master never opens a socket
# http://vccv.posterous.com/forking-processes-in-ruby-and-randomness - we've hit this issue with coupon generation
srand
##
# Unicorn master is started as root, which is fine, but let's
# drop the workers to git:git
end
before_exec do |server|
ENV['BUNDLE_GEMFILE'] = "<%= @app_path %>/current/Gemfile"
end

12
roles/chiliproject.rb Normal file
View File

@@ -0,0 +1,12 @@
name "chiliproject"
description "Install and configure chiliproject"
run_list "recipe[runit]", "recipe[postgresql]", "recipe[ruby]", "recipe[ssh_known_hosts]", "recipe[chiliproject]"
default_attributes(
chiliproject: {
application: {
vagrant_port: 7070
}
}
)

13
roles/strano.rb Normal file
View File

@@ -0,0 +1,13 @@
name "strano"
description "Install and configure redmine"
run_list "recipe[user]", "recipe[postgresql]", "recipe[partition]", "recipe[ruby]", "recipe[runit]", "recipe[nginx]", "recipe[ssh_known_hosts]", "recipe[strano::application]"
default_attributes(
strano: {
application: {
github_key: "305bd9ae51bcd0190d9a",
github_secret: "ccc096152a559e27c9304bb9ae4f896b81a3832c",
vagrant_port: 7071
}
}
)