capistrano-choique 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZWNmMjllZTVmZTFhM2EwMjc3Y2UwNzM5YWMzMThmODQ0MjMwMmYzYQ==
5
+ data.tar.gz: !binary |-
6
+ NDNiZGZiOWU4ZDVjNWRhNjk4ODA5NDIxN2I1ZmYyNTYyZDMyYjlmNQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ ZTg4NTIwYmMwYzgxOWVkN2ExMzZhZWE5NmYwNGMyZDM0MjI0MmExOTg2YWI1
10
+ NWEyOWM3NTVkMTE0ZDhmYmY3ZTcyMmEyMjg5ZDA0MzIxNDFjZmJjYWVmMDJj
11
+ NzIzMmNjZjA5NjRmOWIwOGQ4MjJiYjg0MjQwMTdiYjY5YTg2ZDc=
12
+ data.tar.gz: !binary |-
13
+ YWZiODZhYzMxMTRkMmMxZmYzMWU2ZWUxMTJhYTY2NjdjMTliNzcwNjhlZTY0
14
+ NWI2MDI2NGIzNGE2YjZkMDlhODFhMGYxZTljNTA0ZWFjZWFkZGZlZjA5NTI0
15
+ M2VkNTFhZjMzNjdmODUxNzkwMmQ3YzY4YzFkNTI1ZDI4ZDIxN2U=
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in capistrano-choique.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Christian Rodriguez
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # Capistrano::Choique
2
+
3
+ Tareas para simplificar el deploy de un choique con capistrano
4
+
5
+ ## Instalacion
6
+
7
+ Agergar la gema a tu Gemfile:
8
+
9
+ gem 'capistrano-choique'
10
+
11
+ y ejecutar:
12
+
13
+ $ bundle
14
+
15
+ O instalarla directamente con:
16
+
17
+ $ gem install capistrano-choique
18
+
19
+ ## Uso
20
+
21
+ Una vez instalada la gema, en el directorio local de trabajo, correr:
22
+
23
+ $ capify-choique .
24
+
25
+
26
+ ## Configurar
27
+
28
+ Analizar la configuracion config/deploy.rb
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'capistrano'
4
+ require 'capistrano-choique'
5
+ require 'optparse'
6
+ require 'fileutils'
7
+
8
+ capistrano_choique_version = Capistrano::Choique::VERSION
9
+
10
+ OptionParser.new do |opts|
11
+ opts.banner = "Usage: #{File.basename($0)} [path]"
12
+
13
+ opts.on("-h", "--help", "Displays this help info") do
14
+ puts opts
15
+ exit 0
16
+ end
17
+
18
+ opts.on("-v", "--version", "") do
19
+ puts "capistrano-choique v#{Capistrano::Choique::VERSION}"
20
+ exit 0
21
+ end
22
+
23
+ begin
24
+ opts.parse!(ARGV)
25
+ rescue OptionParser::ParseError => e
26
+ warn e.message
27
+ puts opts
28
+ exit 1
29
+ end
30
+ end
31
+
32
+ if ARGV.empty?
33
+ abort "Please specify the directory to capify, e.g. `#{File.basename($0)} .'"
34
+ elsif !File.exists?(ARGV.first)
35
+ abort "`#{ARGV.first}' does not exist."
36
+ elsif !File.directory?(ARGV.first)
37
+ abort "`#{ARGV.first}' is not a directory."
38
+ elsif ARGV.length > 1
39
+ abort "Too many arguments; please specify only the directory to capify."
40
+ end
41
+
42
+ def unindent(string)
43
+ indentation = string[/\A\s*/]
44
+ string.strip.gsub(/^#{indentation}/, "")
45
+ end
46
+
47
+ base = ARGV.shift
48
+
49
+ files = {
50
+ "Capfile" => unindent(<<-FILE),
51
+ load 'deploy'
52
+
53
+ require 'capistrano-choique'
54
+ load 'config/deploy'
55
+ FILE
56
+
57
+ "config/deploy.rb" => unindent(<<-FILE)
58
+ set :application, "set your application name here"
59
+
60
+ # Database settings
61
+ #set :user, "ssh user used for deployment"
62
+ #set :db_type, "mysql"
63
+ #set :db_host, "localhost"
64
+ #set :db_port, "3306"
65
+ #set :db_name, "Set database name. Defaults to \#{application}"
66
+ #set :db_user, "Set database user to connect. Defaults to \#{application}"
67
+ set :db_password, "Change database password"
68
+
69
+ # Deploy settings
70
+ set :domain, "\#{application}.unlp.edu.ar"
71
+ set :deploy_to, "/opt/applications/\#{application}"
72
+
73
+ role :web, domain # Your HTTP server, Apache/etc
74
+ role :app, domain # This may be the same as your `Web` server
75
+ role :db, domain, :primary => true # This is where Symfony2 migrations will run
76
+
77
+ set :keep_releases, 3
78
+
79
+ # Be more verbose by uncommenting the following line
80
+ # logger.level = Logger::MAX_LEVEL
81
+ set :use_sudo, false
82
+
83
+
84
+ # Choique settings
85
+ #set :choique_name, application
86
+ #set :choique_backend_port, 8000
87
+ #set :choique_frontend_url, "http://\#{domain}/"
88
+ #set :choique_backend_url, "https://\#{domain}:\#{choique_backend_port}/"
89
+ #set :choique_testing, false
90
+ FILE
91
+ }
92
+
93
+ files.each do |file, content|
94
+ file = File.join(base, file)
95
+ if File.exists?(file)
96
+ warn "[skip] '#{file}' already exists"
97
+ elsif File.exists?(file.downcase)
98
+ warn "[skip] '#{file.downcase}' exists, which could conflict with `#{file}'"
99
+ else
100
+ unless File.exists?(File.dirname(file))
101
+ puts "[add] making directory '#{File.dirname(file)}'"
102
+ FileUtils.mkdir_p(File.dirname(file))
103
+ end
104
+ puts "[add] writing '#{file}'"
105
+ File.open(file, "w") { |f| f.write(content) }
106
+ end
107
+ end
108
+
109
+ puts "[done] choique project capified!"
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'capistrano-choique/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "capistrano-choique"
8
+ gem.version = Capistrano::Choique::VERSION
9
+ gem.authors = ["Christian Rodriguez"]
10
+ gem.email = ["car@cespi.unlp.edu.ar"]
11
+ gem.description = %q{Capistrano extension to deploy Choique CMS}
12
+ gem.summary = %q{Capify Choique CMS}
13
+ gem.homepage = "https://github.com/Desarrollo-CeSPI/capistrano-choique"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_development_dependency 'rake'
21
+
22
+ gem.add_dependency('capistrano','> 2.0')
23
+ end
@@ -0,0 +1,76 @@
1
+ all:
2
+ choique:
3
+ version: <?php echo file_get_contents(sfConfig::get('sf_root_dir').'/VERSION');?>
4
+
5
+ instance_name: "<%= choique_name %>"
6
+ url:
7
+ frontend: <%= choique_frontend_url %>
8
+ backend: <%= choique_backend_url %>
9
+ default_flavor_dir: %SF_ROOT_DIR%/data/default-flavor
10
+ #La siguiente solapa muestra u oculta un cartel indicando que esta es una version de prueba
11
+ testing: <%= choique_testing %>
12
+ testing_text: Version de PRUEBA
13
+
14
+
15
+
16
+ lucene:
17
+ index: CMSIndex
18
+ advanced: false
19
+ categories: false
20
+ per_page: 20
21
+ pager_radius: 10
22
+ result_size: 200
23
+ result_highlighter: |
24
+ <strong class="highlight">%s</strong>
25
+ extractors:
26
+ doc: /usr/bin/catdoc %s
27
+ pdf: /usr/bin/pdftotext %s -
28
+ ppt: /usr/bin/catppt %s
29
+ xls: /usr/bin/xls2csv %s
30
+ odt: /usr/bin/odt2txt %s
31
+ ods: /usr/bin/ods2txt %s
32
+ odp: /usr/bin/odp2txt %s
33
+
34
+ valid_mime_types:
35
+ text:
36
+ txt: text/plain
37
+ editor:
38
+ css:
39
+ css: [text/plain, text/x-c charset=us-ascii, text/plain charset=us-ascii]
40
+ images:
41
+ jpg: image/jpeg
42
+ jpeg: image/jpeg
43
+ png: image/png
44
+ gif: image/gif
45
+ ico: [image/png, image/gif, image/x-ico]
46
+ link:
47
+ swf: application/x-shockwave-flash
48
+ jpg: image/jpeg
49
+ jpeg: image/jpeg
50
+ png: image/png
51
+ gif: image/gif
52
+ document:
53
+ doc: [application/msword, application/vnd.ms-office]
54
+ docx: application/zip
55
+ xls: application/vnd.ms-excel
56
+ ppt: application/vnd.ms-office
57
+ pps: application/vnd.ms-office
58
+ pdf: application/pdf
59
+ rar: application/x-rar
60
+ zip: application/zip
61
+ rtf: text/rtf
62
+ multimedia:
63
+ images:
64
+ jpg: [image/jpeg ]
65
+ jpeg: [image/jpeg ]
66
+ png: [image/png ]
67
+ gif: [image/gif ]
68
+ videos:
69
+ mpg: [video/mpeg ]
70
+ mpeg: [video/mpeg ]
71
+ flv: [video/x-flv ]
72
+ swf: [application/x-shockwave-flash ]
73
+ audio:
74
+ mp3: [application/octet-stream, audio/mpeg ]
75
+ mp2: [ audio/mpeg ]
76
+ wav: [ audio/x-wav ]
@@ -0,0 +1,41 @@
1
+ cli:
2
+ controller:
3
+ class: sfConsoleController
4
+ request:
5
+ class: sfConsoleRequest
6
+ response:
7
+ class: sfConsoleResponse
8
+
9
+ test:
10
+ storage:
11
+ class: sfSessionTestStorage
12
+
13
+ all:
14
+ storage:
15
+ class: sfSessionStorage
16
+ param:
17
+ session_name: choiqueCMS-b4ck3nd-<%= choique_name.gsub("\s","-") %>
18
+
19
+ #all:
20
+ # controller:
21
+ # class: sfFrontWebController
22
+ #
23
+ # request:
24
+ # class: sfWebRequest
25
+ #
26
+ # response:
27
+ # class: sfWebResponse
28
+ #
29
+ # user:
30
+ # class: myUser
31
+ #
32
+ # storage:
33
+ # class: sfSessionStorage
34
+ # param:
35
+ # session_name: symfony
36
+ #
37
+ # view_cache:
38
+ # class: sfFileCache
39
+ # param:
40
+ # automaticCleaningFactor: 0
41
+ # cacheDir: %SF_TEMPLATE_CACHE_DIR%
@@ -0,0 +1,10 @@
1
+ all:
2
+ propel:
3
+ class: sfPropelDatabase
4
+ param:
5
+ phptype: <%= db_type %>
6
+ port: <%= db_port %>
7
+ hostspec: <%= db_host %>
8
+ database: <%= db_name%>
9
+ username: <%= db_user%>
10
+ password: <%= db_password%>
@@ -0,0 +1,46 @@
1
+ propel.targetPackage = lib.model
2
+ propel.packageObjectModel = true
3
+ propel.project = choique
4
+ propel.database = mysql
5
+ propel.database.createUrl = <%= "#{db_type}://#{db_user}:#{db_password}@#{db_host}:#{db_port}" %>/
6
+ propel.database.url = <%= "#{db_type}://#{db_user}:#{db_password}@#{db_host}:#{db_port}/#{db_name}" %>
7
+
8
+ propel.mysql.tableType = InnoDB
9
+
10
+ propel.addGenericAccessors = true
11
+ propel.addGenericMutators = true
12
+ propel.addTimeStamp = false
13
+
14
+ propel.schema.validate = false
15
+
16
+ ; directories
17
+ propel.home = .
18
+ propel.output.dir = ; Base dir
19
+ propel.schema.dir = ${propel.output.dir}/config
20
+ propel.conf.dir = ${propel.output.dir}/config
21
+ propel.phpconf.dir = ${propel.output.dir}/config
22
+ propel.sql.dir = ${propel.output.dir}/data/sql
23
+ propel.runtime.conf.file = runtime-conf.xml
24
+ propel.php.dir = ${propel.output.dir}
25
+ propel.default.schema.basename = schema
26
+ propel.datadump.mapper.from = *schema.xml
27
+ propel.datadump.mapper.to = *data.xml
28
+
29
+ ; builder settings
30
+ propel.builder.peer.class = addon.propel.builder.SfPeerBuilder
31
+ propel.builder.object.class = addon.propel.builder.SfObjectBuilder
32
+
33
+ propel.builder.objectstub.class = addon.propel.builder.SfExtensionObjectBuilder
34
+ propel.builder.peerstub.class = addon.propel.builder.SfExtensionPeerBuilder
35
+ propel.builder.objectmultiextend.class = addon.propel.builder.SfMultiExtendObjectBuilder
36
+ propel.builder.mapbuilder.class = addon.propel.builder.SfMapBuilderBuilder
37
+ propel.builder.interface.class = propel.engine.builder.om.php5.PHP5InterfaceBuilder
38
+ propel.builder.node.class = propel.engine.builder.om.php5.PHP5NodeBuilder
39
+ propel.builder.nodepeer.class = propel.engine.builder.om.php5.PHP5NodePeerBuilder
40
+ propel.builder.nodestub.class = propel.engine.builder.om.php5.PHP5ExtensionNodeBuilder
41
+ propel.builder.nodepeerstub.class = propel.engine.builder.om.php5.PHP5ExtensionNodePeerBuilder
42
+
43
+ propel.builder.addIncludes = false
44
+ propel.builder.addComments = false
45
+
46
+ propel.builder.addBehaviors = true
@@ -0,0 +1,195 @@
1
+ namespace :choique do
2
+ # Needs to initialize db?
3
+ def need_init?
4
+ config = ""
5
+ run "#{try_sudo} cat #{shared_path}/config/databases.yml" do |ch, st, data|
6
+ config = load_database_config data, :prod
7
+ end
8
+ sql_dump_cmd = generate_sql_command('dump', config)
9
+ logger.debug sql_dump_cmd.gsub(/(--password=)([^ ]+)/, '\1\'********\'') # Log the command with a masked password
10
+ saved_log_level = logger.level
11
+ logger.level = Capistrano::Logger::IMPORTANT # Change log level so that the real command (containing a plaintext password) is not displayed
12
+ ret = 'true' != capture("if `#{sql_dump_cmd} 2> /dev/null | grep -q article`; then echo true; fi").chomp
13
+ logger.level = saved_log_level
14
+ ret
15
+ end
16
+
17
+ # Needs to create a default flavor?
18
+ def flavors_initialize?
19
+ capture("ls #{shared_path}/flavors | wc -l").chomp.to_i == 0
20
+ end
21
+
22
+
23
+ desc "Creates model classes. It will not touch database"
24
+ task :build_model do
25
+ stream "cd #{latest_release} && #{php_bin} ./symfony propel-build-model"
26
+ end
27
+
28
+ desc "Creates model classes and destroy and initialize database with default data"
29
+ task :data_init do
30
+ stream "cd #{latest_release} && #{php_bin} ./symfony propel-build-all-load backend"
31
+ choique.reindex
32
+ end
33
+
34
+ desc "Rebuild search index"
35
+ task :reindex do
36
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-reindex"
37
+ end
38
+
39
+ desc "Fix file permission"
40
+ task :fix_permissions do
41
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-fix-perms"
42
+ end
43
+
44
+ desc "Clear symfony cache"
45
+ task :cc do
46
+ stream "cd #{latest_release} && #{php_bin} ./symfony cc"
47
+ end
48
+
49
+ desc "Package current version of choique including dump and download"
50
+ task :package do
51
+ name = "choique-#{Time.now.strftime('%F')}"
52
+ run "cat #{current_release}/VERSION" do |ch, st, data|
53
+ name += "-" + data.gsub(/ build.*/,'').gsub(/^\d{4}-\d{2}-\d{2} (v[\w.-_]+)/,'\1')
54
+ end
55
+ run "test -d #{remote_tmp_dir}/#{name} && rm -fr #{remote_tmp_dir}/#{name}; true"
56
+ run "mkdir #{remote_tmp_dir}/#{name}"
57
+ run "cd #{latest_release}; tar cf - * | (cd #{remote_tmp_dir}/#{name}; tar xfp -)"
58
+ dereference = (shared_children + shared_files).join(' ')
59
+ run "cd #{latest_release}; tar cf - #{dereference} -h | (cd #{remote_tmp_dir}/#{name}; tar xfp -)"
60
+ run "rm #{remote_tmp_dir}/#{name}/config/databases.yml #{remote_tmp_dir}/#{name}/config/propel.ini"
61
+ run "rm -fr #{remote_tmp_dir}/#{name}/cache/*;"
62
+ run "rm -fr #{remote_tmp_dir}/#{name}/log/*;"
63
+
64
+ # Dump database
65
+ file = "#{remote_tmp_dir}/#{name}/dump-#{name}.sql"
66
+ config = ""
67
+ run "#{try_sudo} cat #{shared_path}/config/databases.yml" do |ch, st, data|
68
+ config = load_database_config data, symfony_env_prod
69
+ end
70
+ sql_dump_cmd = generate_sql_command('dump', config)
71
+ logger.debug sql_dump_cmd.gsub(/(--password=)([^ ]+)/, '\1\'********\'') # Log the command with a masked password
72
+ saved_log_level = logger.level
73
+ logger.level = Capistrano::Logger::IMPORTANT # Change log level so that the real command (containing a plaintext password) is not displayed
74
+ try_sudo "#{sql_dump_cmd} | gzip -c > #{file}"
75
+ logger.level = saved_log_level
76
+
77
+ # Package and transfer
78
+ run "cd #{remote_tmp_dir}/; tar cfz #{name}.tgz #{name}"
79
+ require "fileutils"
80
+ FileUtils.mkdir_p("backups")
81
+ get "#{remote_tmp_dir}/#{name}.tgz", "backups/#{name}.tgz"
82
+ begin
83
+ FileUtils.ln_sf("#{name}.tgz", "backups/package-latest.tgz")
84
+ rescue Exception # fallback for file systems that don't support symlinks
85
+ FileUtils.cp_r("#{name}.tgz", "backups/package-latest.tgz")
86
+ end
87
+ run "rm -fr #{remote_tmp_dir}/#{name}.tgz #{remote_tmp_dir}/#{name}"
88
+ end
89
+
90
+ namespace :app do
91
+
92
+ desc "Disable a aplication"
93
+ task :disable do
94
+ app_name = Capistrano::CLI.ui.ask "Enter application name (frontend|backend):"
95
+ env_name = Capistrano::CLI.ui.ask "Enter enviroment name (prod|dev):"
96
+ stream "cd #{latest_release} && #{php_bin} ./symfony disable '#{app_name}' '#{env_name}'"
97
+ end
98
+
99
+ desc "Enable a aplication"
100
+ task :enable do
101
+ app_name = Capistrano::CLI.ui.ask "Enter application name (frontend|backend):"
102
+ env_name = Capistrano::CLI.ui.ask "Enter enviroment name (prod|dev):"
103
+ stream "cd #{latest_release} && #{php_bin} ./symfony enable '#{app_name}' '#{env_name}'"
104
+ end
105
+
106
+ end
107
+
108
+ namespace :user do
109
+
110
+ desc "Create/Update user"
111
+ task :update_or_create_admin do
112
+ username = Capistrano::CLI.ui.ask "Enter username:"
113
+ password = Capistrano::CLI.password_prompt
114
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-user-update-or-create-admin '#{username}' '#{password}'"
115
+ end
116
+
117
+ desc "Enable user"
118
+ task :enable do
119
+ username = Capistrano::CLI.ui.ask "Enter username:"
120
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-user-enable '#{username}'"
121
+ end
122
+
123
+ desc "Disable user"
124
+ task :disable do
125
+ username = Capistrano::CLI.ui.ask "Enter username:"
126
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-user-disable '#{username}'"
127
+ end
128
+ end
129
+
130
+ namespace :flavors do
131
+
132
+ desc "Set default flavor"
133
+ task :init do
134
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-flavors-initialize"
135
+ end
136
+
137
+ desc "Download current flavor"
138
+ task :download_current do
139
+ choique_config = {}
140
+ run "#{try_sudo} cat #{current_dir}/config/choique.yml" do |ch, st, data|
141
+ choique_config = YAML::load(data)
142
+ end
143
+ current = choique_config['choique']['flavors']['current']
144
+ filename = "#{application}.remote_current_flavor.#{Time.now.strftime("%Y-%m-%d_%H-%M-%S")}.zip"
145
+ file = "#{remote_tmp_dir}/#{filename}"
146
+ try_sudo "cd #{shared_path}/flavors/#{current}; zip -r #{file} *"
147
+ require "fileutils"
148
+ FileUtils.mkdir_p("backups")
149
+ get file, "backups/#{filename}"
150
+ begin
151
+ FileUtils.ln_sf(filename, "backups/#{application}.remote_current_flavor.latest.zip")
152
+ rescue Exception # fallback for file systems that don't support symlinks
153
+ FileUtils.cp_r("backups/#{filename}", "backups/#{application}.remote_current_flavor.latest.zip")
154
+ end
155
+ run "#{try_sudo} rm #{file}"
156
+ end
157
+
158
+ desc "Download flavors folder and install it locally"
159
+ task :to_local do
160
+ choique_config = {}
161
+ run "#{try_sudo} cat #{current_dir}/config/choique.yml" do |ch, st, data|
162
+ choique_config = YAML::load(data)
163
+ end
164
+ run_locally("rm -fr flavors/*")
165
+ current = choique_config['choique']['flavors']['current']
166
+ download("#{shared_path}/flavors", ".", :via => :scp, :recursive => true)
167
+ run_locally("php symfony choique-flavor-select #{current}")
168
+ end
169
+
170
+ desc "Upload flavors folder and install it remotelly"
171
+ task :to_remote do
172
+ choique_config = {}
173
+ run "#{try_sudo} cat #{current_dir}/config/choique.yml" do |ch, st, data|
174
+ choique_config = YAML::load(data)
175
+ end
176
+ current = choique_config['choique']['flavors']['current']
177
+ run "#{try_sudo} rm -fr #{shared_path}/flavors/*"
178
+ upload("flavors", "#{shared_path}", :via => :scp, :recursive => true)
179
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-flavor-select #{current}"
180
+ end
181
+
182
+
183
+ desc "Fix flavor after deploy"
184
+ task :fix_flavor do
185
+ choique_config = {}
186
+ run "#{try_sudo} cat #{shared_path}/config/choique.yml" do |ch, st, data|
187
+ choique_config = YAML::load(data)
188
+ end
189
+ current = choique_config['choique']['flavors']['current']
190
+ stream "cd #{latest_release} && #{php_bin} ./symfony choique-flavor-select #{current}"
191
+ end
192
+ end
193
+
194
+ end
195
+
@@ -0,0 +1,118 @@
1
+ namespace :database do
2
+ namespace :dump do
3
+ desc "Dump remote database"
4
+ task :remote, :roles => :db, :only => { :primary => true } do
5
+ filename = "#{application}.remote_dump.#{Time.now.strftime("%Y-%m-%d_%H-%M-%S")}.sql.gz"
6
+ file = "#{remote_tmp_dir}/#{filename}"
7
+ sqlfile = "#{application}_dump.sql"
8
+ config = ""
9
+
10
+ run "#{try_sudo} cat #{shared_path}/config/databases.yml" do |ch, st, data|
11
+ config = load_database_config data, symfony_env_prod
12
+ end
13
+
14
+ sql_dump_cmd = generate_sql_command('dump', config)
15
+ logger.debug sql_dump_cmd.gsub(/(--password=)([^ ]+)/, '\1\'********\'') # Log the command with a masked password
16
+ saved_log_level = logger.level
17
+ logger.level = Capistrano::Logger::IMPORTANT # Change log level so that the real command (containing a plaintext password) is not displayed
18
+ try_sudo "#{sql_dump_cmd} | gzip -c > #{file}"
19
+ logger.level = saved_log_level
20
+
21
+ require "fileutils"
22
+ FileUtils.mkdir_p("backups")
23
+ get file, "backups/#{filename}"
24
+ begin
25
+ FileUtils.ln_sf(filename, "backups/#{application}.remote_dump.latest.sql.gz")
26
+ rescue Exception # fallback for file systems that don't support symlinks
27
+ FileUtils.cp_r("backups/#{filename}", "backups/#{application}.remote_dump.latest.sql.gz")
28
+ end
29
+ run "#{try_sudo} rm #{file}"
30
+ end
31
+
32
+ desc "Dump local database"
33
+ task :local do
34
+ filename = "#{application}.local_dump.#{Time.now.strftime("%Y-%m-%d_%H-%M-%S")}.sql.gz"
35
+ tmpfile = "backups/#{application}_dump_tmp.sql"
36
+ file = "backups/#{filename}"
37
+ config = load_database_config IO.read('config/databases.yml'), symfony_env_local
38
+ sqlfile = "#{application}_dump.sql"
39
+
40
+ require "fileutils"
41
+ FileUtils::mkdir_p("backups")
42
+
43
+ sql_dump_cmd = generate_sql_command('dump', config)
44
+ run_locally "#{sql_dump_cmd} > #{tmpfile}"
45
+
46
+ File.open(tmpfile, "r+") do |f|
47
+ gz = Zlib::GzipWriter.open(file)
48
+ while (line = f.gets)
49
+ gz << line
50
+ end
51
+ gz.flush
52
+ gz.close
53
+ end
54
+
55
+ begin
56
+ FileUtils.ln_sf(filename, "backups/#{application}.local_dump.latest.sql.gz")
57
+ rescue Exception # fallback for file systems that don't support symlinks
58
+ FileUtils.cp_r("backups/#{filename}", "backups/#{application}.local_dump.latest.sql.gz")
59
+ end
60
+ FileUtils.rm(tmpfile)
61
+ end
62
+ end
63
+
64
+ namespace :move do
65
+ desc "Dump remote database, download it to local & populate here"
66
+ task :to_local, :roles => :db, :only => { :primary => true } do
67
+
68
+ database.dump.remote
69
+
70
+ begin
71
+ zipped_file_path = `readlink -f backups/#{application}.remote_dump.latest.sql.gz`.chop # gunzip does not work with a symlink
72
+ rescue Exception # fallback for file systems that don't support symlinks
73
+ zipped_file_path = "backups/#{application}.remote_dump.latest.sql.gz"
74
+ end
75
+ unzipped_file_path = "backups/#{application}_dump.sql"
76
+
77
+ run_locally "gunzip -c #{zipped_file_path} > #{unzipped_file_path}"
78
+
79
+ config = load_database_config IO.read('config/databases.yml'), symfony_env_local
80
+
81
+ run_locally generate_sql_command('drop', config)
82
+ run_locally generate_sql_command('create', config)
83
+
84
+ sql_import_cmd = generate_sql_command('import', config)
85
+ run_locally "#{sql_import_cmd} < #{unzipped_file_path}"
86
+
87
+ FileUtils.rm("#{unzipped_file_path}")
88
+ end
89
+
90
+ desc "Dump local database, load it to remote & populate there"
91
+ task :to_remote, :roles => :db, :only => { :primary => true } do
92
+
93
+ filename = "#{application}.local_dump.latest.sql.gz"
94
+ file = "backups/#{filename}"
95
+ sqlfile = "#{application}_dump.sql"
96
+ config = ""
97
+
98
+ database.dump.local
99
+
100
+ upload(file, "#{remote_tmp_dir}/#{filename}", :via => :scp)
101
+ run "#{try_sudo} gunzip -c #{remote_tmp_dir}/#{filename} > #{remote_tmp_dir}/#{sqlfile}"
102
+
103
+ run "#{try_sudo} cat #{shared_path}/config/databases.yml" do |ch, st, data|
104
+ config = load_database_config data, symfony_env_prod
105
+ end
106
+
107
+ try_sudo generate_sql_command('drop', config)
108
+ try_sudo generate_sql_command('create', config)
109
+
110
+ sql_import_cmd = generate_sql_command('import', config)
111
+
112
+ try_sudo "#{sql_import_cmd} < #{remote_tmp_dir}/#{sqlfile}"
113
+
114
+ run "#{try_sudo} rm #{remote_tmp_dir}/#{filename}"
115
+ run "#{try_sudo} rm #{remote_tmp_dir}/#{sqlfile}"
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,58 @@
1
+ # Extend deploy tasks from original
2
+ namespace :deploy do
3
+
4
+ desc <<-DESC
5
+ Prepares one or more servers for deployment. Before you can use any \
6
+ of the Capistrano deployment tasks with your project, you will need to \
7
+ make sure all of your servers have been prepared with `cap deploy:setup'. When \
8
+ you add a new server to your cluster, you can easily run the setup task \
9
+ on just that server by specifying the HOSTS environment variable:
10
+
11
+ $ cap HOSTS=new.server.com deploy:setup
12
+
13
+ It is safe to run this task on servers that have already been set up; it \
14
+ will not destroy any deployed revisions or data.
15
+ DESC
16
+ task :setup, :except => { :no_release => true } do
17
+ dirs = [deploy_to, releases_path, shared_path]
18
+ dirs += shared_children.map { |d| File.join(shared_path, d) }
19
+ run "#{try_sudo} mkdir -p #{dirs.join(' ')}"
20
+ run "#{try_sudo} chmod g+w #{dirs.join(' ')}" if fetch(:group_writable, true)
21
+ end
22
+
23
+ desc "Symlink static directories and static files that need to remain between deployments."
24
+ task :share_childs do
25
+ if shared_children
26
+ shared_children.each do |link|
27
+ run "#{try_sudo} mkdir -p #{shared_path}/#{link}"
28
+ run "#{try_sudo} sh -c 'if [ -d #{release_path}/#{link} ] ; then rm -rf #{release_path}/#{link}; fi'"
29
+ run "#{try_sudo} ln -nfs #{shared_path}/#{link} #{release_path}/#{link}"
30
+ end
31
+ end
32
+ if shared_files
33
+ shared_files.each do |link|
34
+ link_dir = File.dirname("#{shared_path}/#{link}")
35
+ run "#{try_sudo} mkdir -p #{link_dir}"
36
+ run "#{try_sudo} touch #{shared_path}/#{link}"
37
+ run "#{try_sudo} ln -nfs #{shared_path}/#{link} #{release_path}/#{link}"
38
+ end
39
+ end
40
+ end
41
+
42
+ desc "Customize the finalize_update task to work with symfony."
43
+ task :finalize_update, :except => { :no_release => true } do
44
+ run "#{try_sudo} chmod -R g+w #{latest_release}" if fetch(:group_writable, true)
45
+ run "#{try_sudo} mkdir -p #{latest_release}/cache"
46
+ run "#{try_sudo} chmod -R g+w #{latest_release}/cache"
47
+
48
+ # Share common files & folders
49
+ share_childs
50
+
51
+ if fetch(:normalize_asset_timestamps, true)
52
+ stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S")
53
+ asset_paths = asset_children.map { |p| "#{latest_release}/#{p}" }.join(" ")
54
+ run "#{try_sudo} find #{asset_paths} -exec touch -t #{stamp} {} ';'; true", :env => { "TZ" => "UTC" }
55
+ end
56
+ end
57
+ end
58
+
@@ -0,0 +1,13 @@
1
+ namespace :choique do
2
+ namespace :uploads do
3
+ desc "Download all files from remote web-frontend/uploads folder to local one"
4
+ task :to_local do
5
+ download("#{shared_path}/web-frontend/uploads", "web-frontend", :via => :scp, :recursive => true)
6
+ end
7
+
8
+ desc "Upload all files from local web/uploads folder to remote one"
9
+ task :to_remote do
10
+ upload("web-frontend/uploads", "#{shared_path}/web-frontend", :via => :scp, :recursive => true)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module Capistrano
2
+ module Choique
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,162 @@
1
+ require 'capistrano'
2
+ require 'capistrano-choique/version'
3
+
4
+
5
+ module Capistrano
6
+ module Choique
7
+ def self.load_into(configuration)
8
+ configuration.load do
9
+ load_paths.push File.expand_path('../', __FILE__)
10
+ Dir.glob(File.join(File.dirname(__FILE__), '/capistrano-choique/recipes/*.rb')).sort.each { |f| load f }
11
+
12
+ set :repository, "https://github.com/Desarrollo-CeSPI/choique.git"
13
+ set :deploy_via, :remote_cache
14
+ set :scm, :git
15
+
16
+ set(:choique_tag) { branch }
17
+
18
+ set :branch do
19
+ default_tag = /tags\/([\w.\d]+).*?$/.match(`git ls-remote -t #{repository}`.split("\n").last)
20
+ default_tag = if default_tag
21
+ default_tag[1]
22
+ else
23
+ "master"
24
+ end
25
+ tag = Capistrano::CLI.ui.ask "Tag to deploy (Press enter when done): [#{default_tag}]"
26
+ tag = default_tag if tag.empty?
27
+ tag
28
+ end
29
+
30
+ set(:user) { application }
31
+
32
+ set :php_bin, "php"
33
+
34
+ set :db_type, "mysql"
35
+ set :db_host, "localhost"
36
+ set :db_port, "3306"
37
+ set(:db_name) { application }
38
+ set(:db_user) { application }
39
+
40
+ set :symfony_env_prod, :prod
41
+ set :symfony_env_local, :dev
42
+
43
+ set (:remote_tmp_dir) { "#{deploy_to}/tmp" }
44
+
45
+ set(:choique_name) { application }
46
+ set :choique_backend_port, "8000"
47
+ set(:choique_frontend_url) { "http://#{domain}/" }
48
+ set(:choique_backend_url) { "https://#{domain}:#{choique_backend_port}/" }
49
+ set :choique_testing, false
50
+
51
+ set :shared_children, %w(log web-frontend/uploads flavors data/index)
52
+ set :shared_files, %w(apps/backend/config/factories.yml config/databases.yml config/propel.ini config/app.yml config/choique.yml)
53
+ set :asset_children, %w(web-frontend/css web-frontend/images web-frontend/js web-backend/css web-backend/images web-backend/js)
54
+
55
+ # helper function
56
+ def deep_merge(hash1, hash2)
57
+
58
+ #if both 'all' and env keys are nil break
59
+ if(hash1 == nil && hash2 == nil)
60
+ return nil
61
+ end
62
+
63
+ #the config.yml may not have 'all' key but instead 'dev' 'prod' and so on
64
+ if(hash1 == nil && hash2 != nil)
65
+ return hash2 # no need to merge
66
+ end
67
+
68
+ #if only the 'all' key is specified
69
+ #There might not be a second has to cascade to
70
+ if(hash2 == nil && hash1 != nil)
71
+ return hash1;
72
+ end
73
+ hash1.merge(hash2){|key, subhash1, subhash2|
74
+ if (subhash1.is_a?(Hash) && subhash2.is_a?(Hash))
75
+ next deep_merge(subhash1, subhash2)
76
+ end
77
+ subhash2
78
+ }
79
+ end
80
+
81
+ # load database params from databases.yml to build mysql/pgsql commands
82
+ def load_database_config(data, env)
83
+ db_config = YAML::load(data)
84
+
85
+ connections = deep_merge(db_config['all'], db_config[env.to_s])
86
+
87
+ db_param = connections['propel']['param']
88
+
89
+ {
90
+ 'type' => db_param['phptype'],
91
+ 'user' => db_param['username'],
92
+ 'pass' => db_param['password'],
93
+ 'db' => db_param['database'],
94
+ 'host' => db_param['hostspec'],
95
+ 'port' => db_param['port']
96
+ }
97
+ end
98
+
99
+ # generate mysql / pgsql commands
100
+ def generate_sql_command(cmd_type, config)
101
+ db_type = config['type']
102
+ cmd_conf = {
103
+ 'mysql' => {
104
+ 'create' => "mysqladmin -u #{config['user']} --password='#{config['pass']}' create",
105
+ 'dump' => "mysqldump -u #{config['user']} --password='#{config['pass']}'",
106
+ 'drop' => "mysqladmin -f -u #{config['user']} --password='#{config['pass']}' drop",
107
+ 'import' => "mysql -u #{config['user']} --password='#{config['pass']}'"
108
+ },
109
+ 'pgsql' => {
110
+ 'create' => "createdb -U #{config['user']}",
111
+ 'dump' => "pg_dump -U #{config['user']}",
112
+ 'drop' => "dropdb -U #{config['user']}",
113
+ 'import' => "psql -U #{config['user']} --password='#{config['pass']}'"
114
+ }
115
+ }
116
+
117
+ cmd = cmd_conf[db_type][cmd_type]
118
+ cmd+= " --host=#{config['host']}" if config['host']
119
+ cmd+= " --port=#{config['port']}" if config['port']
120
+ cmd+= " #{config['db']}"
121
+
122
+ cmd
123
+ end
124
+
125
+ after "deploy:finalize_update" do
126
+ choique.flavors.init if choique.flavors_initialize?
127
+ choique.build_model
128
+ choique.fix_permissions
129
+ choique.data_init if choique.need_init?
130
+ choique.flavors.fix_flavor unless choique.flavors_initialize?
131
+ choique.cc
132
+ end
133
+
134
+ after "deploy:setup" do
135
+ prefix = File.join(File.dirname(__FILE__), '/../data/templates/')
136
+ database_conf = ERB.new(File.read("#{prefix}/databases.yml.erb")).result(binding)
137
+ propel_conf = ERB.new(File.read("#{prefix}/propel.ini.erb")).result(binding)
138
+ app_conf = ERB.new(File.read("#{prefix}/app.yml.erb")).result(binding)
139
+ factories_conf = ERB.new(File.read("#{prefix}/backend_factories.yml.erb")).result(binding)
140
+ run "#{try_sudo} mkdir -p #{shared_path}/config #{shared_path}/apps/backend/config"
141
+ put database_conf, "#{shared_path}/config/databases.yml"
142
+ put propel_conf, "#{shared_path}/config/propel.ini"
143
+ put app_conf, "#{shared_path}/config/app.yml"
144
+ put factories_conf, "#{shared_path}/apps/backend/config/factories.yml"
145
+ run "#{try_sudo} mkdir -p #{remote_tmp_dir}"
146
+ end
147
+
148
+ after "deploy:create_symlink" do
149
+ deploy_date = Time.now.strftime('%F')
150
+ build_version = "#{deploy_date} #{choique_tag} build+#{current_revision}"
151
+ put(build_version,"#{current_release}/VERSION")
152
+ end
153
+
154
+ end
155
+ end
156
+ end
157
+ end
158
+
159
+ if Capistrano::Configuration.instance
160
+ Capistrano::Choique.load_into(Capistrano::Configuration.instance)
161
+ end
162
+
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-choique
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Christian Rodriguez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-05-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: capistrano
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>'
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>'
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ description: Capistrano extension to deploy Choique CMS
42
+ email:
43
+ - car@cespi.unlp.edu.ar
44
+ executables:
45
+ - capify-choique
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - bin/capify-choique
55
+ - capistrano-choique.gemspec
56
+ - data/templates/app.yml.erb
57
+ - data/templates/backend_factories.yml.erb
58
+ - data/templates/databases.yml.erb
59
+ - data/templates/propel.ini.erb
60
+ - lib/capistrano-choique.rb
61
+ - lib/capistrano-choique/recipes/choique.rb
62
+ - lib/capistrano-choique/recipes/database.rb
63
+ - lib/capistrano-choique/recipes/deploy.rb
64
+ - lib/capistrano-choique/recipes/shared.rb
65
+ - lib/capistrano-choique/version.rb
66
+ homepage: https://github.com/Desarrollo-CeSPI/capistrano-choique
67
+ licenses: []
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 2.0.3
86
+ signing_key:
87
+ specification_version: 4
88
+ summary: Capify Choique CMS
89
+ test_files: []