dkdeploy-core 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.rubocop.yml +18 -0
- data/Berksfile +3 -0
- data/Berksfile.lock +46 -0
- data/CONTRIBUTORS.md +16 -0
- data/Gemfile +4 -0
- data/LICENSE +7 -0
- data/README.md +88 -0
- data/Rakefile +5 -0
- data/Vagrantfile +60 -0
- data/config/vm/cookbooks/dkdeploy-core/metadata.rb +10 -0
- data/config/vm/cookbooks/dkdeploy-core/recipes/default.rb +56 -0
- data/dkdeploy-core.gemspec +34 -0
- data/features/apache.feature +35 -0
- data/features/assets.feature +100 -0
- data/features/bower.feature +52 -0
- data/features/current_folder.feature +17 -0
- data/features/db.feature +93 -0
- data/features/deploy.feature +48 -0
- data/features/enhanced_symlinks.feature +17 -0
- data/features/error_handlers.feature +59 -0
- data/features/file_access.feature +120 -0
- data/features/maintenance.feature +25 -0
- data/features/project_version.feature +42 -0
- data/features/support/env.rb +22 -0
- data/features/utils.feature +81 -0
- data/lib/capistrano/copy.rb +2 -0
- data/lib/capistrano/dkdeploy/core.rb +88 -0
- data/lib/dkdeploy/constants.rb +156 -0
- data/lib/dkdeploy/copy.rb +121 -0
- data/lib/dkdeploy/core/version.rb +15 -0
- data/lib/dkdeploy/dsl.rb +23 -0
- data/lib/dkdeploy/helpers/assets.rb +50 -0
- data/lib/dkdeploy/helpers/common.rb +31 -0
- data/lib/dkdeploy/helpers/db.rb +49 -0
- data/lib/dkdeploy/helpers/file_system.rb +76 -0
- data/lib/dkdeploy/i18n.rb +143 -0
- data/lib/dkdeploy/interaction_handler/password.rb +27 -0
- data/lib/dkdeploy/rollback_manager.rb +18 -0
- data/lib/dkdeploy/tasks/apache.rake +29 -0
- data/lib/dkdeploy/tasks/assets.rake +96 -0
- data/lib/dkdeploy/tasks/bower.rake +54 -0
- data/lib/dkdeploy/tasks/copy.rake +26 -0
- data/lib/dkdeploy/tasks/current_folder.rake +16 -0
- data/lib/dkdeploy/tasks/db.rake +412 -0
- data/lib/dkdeploy/tasks/deploy.rake +77 -0
- data/lib/dkdeploy/tasks/enhanced_symlinks.rake +74 -0
- data/lib/dkdeploy/tasks/fail.rake +8 -0
- data/lib/dkdeploy/tasks/file_access.rake +89 -0
- data/lib/dkdeploy/tasks/maintenance.rake +73 -0
- data/lib/dkdeploy/tasks/project_version.rake +32 -0
- data/lib/dkdeploy/tasks/utils.rake +141 -0
- data/lib/dkdeploy.rb +1 -0
- data/spec/fixtures/application/Capfile +11 -0
- data/spec/fixtures/application/Gemfile +11 -0
- data/spec/fixtures/application/Version +1 -0
- data/spec/fixtures/application/config/assets_exclude_file.txt +1 -0
- data/spec/fixtures/application/config/deploy/dev.rb +35 -0
- data/spec/fixtures/application/config/deploy.rb +18 -0
- data/spec/fixtures/application/config/etc/apache2/conf/.htaccess.erb +12 -0
- data/spec/fixtures/application/config/etc/apache2/conf/dev.htaccess.erb +3 -0
- data/spec/fixtures/application/config/preseed/default_content.sql.gz +0 -0
- data/spec/fixtures/application/config/preseed/default_structure.sql.gz +0 -0
- data/spec/fixtures/application/config/preseed/fileadmin.tar.gz +0 -0
- data/spec/fixtures/application/config/preseed/uploads.tar.gz +0 -0
- data/spec/fixtures/application/htdocs/.hidden/.gitkeep +0 -0
- data/spec/fixtures/application/htdocs/Gemfile +0 -0
- data/spec/fixtures/application/htdocs/bower.json +15 -0
- data/spec/fixtures/application/htdocs/catalog/.hidden/.gitkeep +0 -0
- data/spec/fixtures/application/htdocs/catalog/index.html +1 -0
- data/spec/fixtures/application/htdocs/index.html +1 -0
- data/spec/fixtures/application/htdocs/stylesheets/test1/config.rb +3 -0
- data/spec/fixtures/application/htdocs/stylesheets/test1/css/.gitkeep +0 -0
- data/spec/fixtures/application/htdocs/stylesheets/test1/src/source.scss +5 -0
- data/spec/fixtures/application/htdocs/stylesheets/test2/config.rb +3 -0
- data/spec/fixtures/application/htdocs/stylesheets/test2/css/.gitkeep +0 -0
- data/spec/fixtures/application/htdocs/stylesheets/test2/src/source.scss +5 -0
- data/spec/fixtures/application/temp/dkdeploy_core.sql.gz +0 -0
- data/spec/fixtures/capistrano/configuration/add_output_after_create_symlink.rb +7 -0
- data/spec/fixtures/capistrano/configuration/custom_compass_sources.rb +4 -0
- data/spec/fixtures/capistrano/configuration/custom_file_access.rb +13 -0
- data/spec/fixtures/capistrano/configuration/default_deployment_behaviour.rb +9 -0
- metadata +346 -0
data/lib/dkdeploy/dsl.rb
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Dkdeploy
|
|
2
|
+
# TYPO3 dsl api
|
|
3
|
+
module DSL
|
|
4
|
+
# Execute a rake/capistrano task only for given server
|
|
5
|
+
#
|
|
6
|
+
# @param server [Capistrano::Configuration::Server] Server to execute task
|
|
7
|
+
# @param task [String] Name of rake/capistrano task
|
|
8
|
+
# @param args [Array] Arguments of rake/capistrano task
|
|
9
|
+
def invoke_for_server(server, task, *args) # rubocop:disable Metrics/AbcSize
|
|
10
|
+
backup_filter = fetch :filter, {}
|
|
11
|
+
new_server_filter = Marshal.load(Marshal.dump(backup_filter))
|
|
12
|
+
new_server_filter[:host] = server.hostname
|
|
13
|
+
set :filter, new_server_filter
|
|
14
|
+
env.setup_filters
|
|
15
|
+
info I18n.t('dsl.invoke_for_server.set_filter', task: task, host: server.hostname, scope: :dkdeploy)
|
|
16
|
+
invoke task, *args
|
|
17
|
+
Rake::Task[task].reenable
|
|
18
|
+
ensure
|
|
19
|
+
set :filter, backup_filter
|
|
20
|
+
env.setup_filters
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
include Capistrano::DSL
|
|
2
|
+
include SSHKit::DSL
|
|
3
|
+
|
|
4
|
+
module Dkdeploy
|
|
5
|
+
module Helpers
|
|
6
|
+
# Helpers for Assets Tasks
|
|
7
|
+
module Assets
|
|
8
|
+
def assets_upload(name, folder = File.join('temp', 'assets')) # rubocop:disable Metrics/AbcSize
|
|
9
|
+
FileUtils.mkdir_p folder
|
|
10
|
+
on release_roles :web do
|
|
11
|
+
targz = name + '.tar.gz'
|
|
12
|
+
info I18n.t('tasks.assets.upload', file: targz, scope: :dkdeploy)
|
|
13
|
+
execute :mkdir, '-p', assets_path
|
|
14
|
+
upload! File.join(folder, targz), assets_path
|
|
15
|
+
within assets_path do
|
|
16
|
+
info I18n.t('tasks.assets.upload_extract', file: targz, scope: :dkdeploy)
|
|
17
|
+
execute :tar, 'xzfp', targz
|
|
18
|
+
execute :rm, '-f', targz
|
|
19
|
+
end
|
|
20
|
+
invoke 'file_access:set_custom_access'
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def assets_download(folder) # rubocop:disable Metrics/AbcSize
|
|
25
|
+
FileUtils.mkdir_p File.join('temp', 'assets')
|
|
26
|
+
assets_exclude_file = fetch(:asset_exclude_file) || ''
|
|
27
|
+
on release_roles :web do
|
|
28
|
+
if File.exist?(assets_exclude_file)
|
|
29
|
+
exclude_filename = File.basename(assets_exclude_file)
|
|
30
|
+
execute :rm, '-f', File.join(assets_path, exclude_filename)
|
|
31
|
+
upload! assets_exclude_file, assets_path
|
|
32
|
+
exclude_option = "-X #{File.join(assets_path, exclude_filename)}"
|
|
33
|
+
else
|
|
34
|
+
info I18n.t('tasks.assets.exclude_file_not_found', scope: :dkdeploy)
|
|
35
|
+
end
|
|
36
|
+
within assets_path do
|
|
37
|
+
if test "[ -d #{assets_path}/#{folder} ]"
|
|
38
|
+
info I18n.t('tasks.assets.download', folder: folder, scope: :dkdeploy)
|
|
39
|
+
execute :tar, 'czfp', "#{folder}.tar.gz", exclude_option || '', folder
|
|
40
|
+
download! File.join(assets_path, "#{folder}.tar.gz"), File.join('temp', 'assets')
|
|
41
|
+
execute :rm, '-f', "#{folder}.tar.gz"
|
|
42
|
+
else
|
|
43
|
+
info I18n.t('tasks.assets.folder_not_found', folder: folder, scope: :dkdeploy)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'highline'
|
|
2
|
+
|
|
3
|
+
module Dkdeploy
|
|
4
|
+
module Helpers
|
|
5
|
+
# common helpers, which are not task specific
|
|
6
|
+
module Common
|
|
7
|
+
def terminal
|
|
8
|
+
@terminal ||= HighLine.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def ask_via_terminal(question_selector, &block)
|
|
12
|
+
question = I18n.t(question_selector, scope: :dkdeploy)
|
|
13
|
+
answer = terminal.ask(question, &block)
|
|
14
|
+
String.new(answer)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def ask_variable(args, variable_name_symbol, question_selector, &block)
|
|
18
|
+
ENV[variable_name_symbol.to_s.upcase] || args[variable_name_symbol] ||
|
|
19
|
+
fetch(variable_name_symbol) || ask_via_terminal(question_selector, &block)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def ask_array_variable(args, variable_name_symbol, question_selector, &block)
|
|
23
|
+
variable_content = ask_variable(args, variable_name_symbol, question_selector, &block)
|
|
24
|
+
return variable_content if variable_content.is_a?(Array)
|
|
25
|
+
return variable_content.split if variable_content.is_a?(String)
|
|
26
|
+
|
|
27
|
+
raise(I18n.t('errors.variable_content_is_neither_string_nor_array', variable_name: variable_name_symbol, scope: :dkdeploy))
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
|
|
3
|
+
include Capistrano::DSL
|
|
4
|
+
|
|
5
|
+
module Dkdeploy
|
|
6
|
+
module Helpers
|
|
7
|
+
# DB related helpers
|
|
8
|
+
module DB
|
|
9
|
+
def db_dump_file(infix = '')
|
|
10
|
+
date = DateTime.now.strftime(datetime_format)
|
|
11
|
+
['database', fetch(:stage), infix, date].join('-') << '.sql'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def db_dump_file_content(table_name = nil)
|
|
15
|
+
db_dump_file ['content', table_name].compact.join('-')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def db_dump_file_structure(table_name = nil)
|
|
19
|
+
db_dump_file ['structure', table_name].compact.join('-')
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def db_settings_hash
|
|
23
|
+
{
|
|
24
|
+
'database' => {
|
|
25
|
+
'host' => fetch(:db_host),
|
|
26
|
+
'port' => fetch(:db_port),
|
|
27
|
+
'name' => fetch(:db_name),
|
|
28
|
+
'username' => fetch(:db_username),
|
|
29
|
+
'password' => fetch(:db_password),
|
|
30
|
+
'charset' => fetch(:db_charset)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Read db settings for given context
|
|
36
|
+
#
|
|
37
|
+
# @param context [SSHKit::Backend::Netssh] SSHKit context
|
|
38
|
+
# @return [Hash] Hash with database settings
|
|
39
|
+
def read_db_settings_for_context(context)
|
|
40
|
+
unless context.test("[ -f #{remote_database_config_path} ]")
|
|
41
|
+
context.error I18n.t('errors.database_config_file_missing', scope: :dkdeploy)
|
|
42
|
+
return
|
|
43
|
+
end
|
|
44
|
+
json_string = context.download! remote_database_config_path
|
|
45
|
+
YAML.load(json_string).fetch('database')
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
include Capistrano::DSL
|
|
2
|
+
|
|
3
|
+
module Dkdeploy
|
|
4
|
+
module Helpers
|
|
5
|
+
# Class for the capistrano copy
|
|
6
|
+
#
|
|
7
|
+
module FileSystem
|
|
8
|
+
# Adds the absolute path prefix to the given relative path depending whether this needs to be in shared or release path.
|
|
9
|
+
#
|
|
10
|
+
# @param release_or_shared_path [Symbol] symbol of :shared_path or :release_path
|
|
11
|
+
# @param path [String] the relative path
|
|
12
|
+
# @return [String] absolute path
|
|
13
|
+
def map_path_in_release_or_shared_path(release_or_shared_path, path)
|
|
14
|
+
prefix_path = release_or_shared_path == :shared_path ? shared_path : release_path
|
|
15
|
+
prefix_path.join(path)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Resolves the symlink path to its target, otherwise returns the path without any changing
|
|
19
|
+
# Note: the function can only be run within SSHKit context
|
|
20
|
+
#
|
|
21
|
+
# @param context [SSHKit::Backend::Netssh] SSHKit context
|
|
22
|
+
# @param path [String] path to resolve
|
|
23
|
+
# @return [String]
|
|
24
|
+
def resolve_path_if_symlink(context, path)
|
|
25
|
+
if context.test " [ -L #{path} ] "
|
|
26
|
+
return context.capture :readlink, '-f', path
|
|
27
|
+
end
|
|
28
|
+
path
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Iterates over the given paths' array, resolves symlinks and merges them together
|
|
32
|
+
# Example merge_paths_with_resolved_symlinks [p_1, symlink_1, p_2], 'dkdeploy-core.dev' -> [p_1, symlink_1, p_2, resolved_symlink_1]
|
|
33
|
+
# Note: the function can only be run within SSHKit context
|
|
34
|
+
|
|
35
|
+
# @param context [SSHKit::Backend::Netssh] SSHKit context
|
|
36
|
+
# @param paths [Array] array with paths to resolve
|
|
37
|
+
# @return [Array] the merged array with paths
|
|
38
|
+
def merge_paths_with_resolved_symlinks(context, *paths)
|
|
39
|
+
paths.each do |path|
|
|
40
|
+
resolved_path = resolve_path_if_symlink context, path
|
|
41
|
+
paths.push resolved_path unless paths.include? resolved_path
|
|
42
|
+
end
|
|
43
|
+
paths
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Applies file owner/group/mode permissions to path on host via Capistrano - optionally recursively
|
|
47
|
+
def apply_file_access_permissions(context, host, path, access_properties, force_recursive = false) # rubocop:disable Metrics/AbcSize
|
|
48
|
+
unless context.test " [ -e #{path} ] "
|
|
49
|
+
context.error I18n.t('resource.not_exists_on_host', resource: path, host: host.hostname, scope: :dkdeploy)
|
|
50
|
+
return
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# if the access properties should be applied recursively
|
|
54
|
+
recursive = access_properties.fetch(:recursive, false) || force_recursive
|
|
55
|
+
recursive = recursive ? '-R' : ''
|
|
56
|
+
|
|
57
|
+
resolved_path = resolve_path_if_symlink(context, path)
|
|
58
|
+
|
|
59
|
+
# change owner if set
|
|
60
|
+
if access_properties.key?(:owner)
|
|
61
|
+
context.execute :chown, recursive, access_properties.fetch(:owner), resolved_path
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# change group if set
|
|
65
|
+
if access_properties.key?(:group)
|
|
66
|
+
context.execute :chgrp, recursive, access_properties.fetch(:group), resolved_path
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# change mode if set
|
|
70
|
+
if access_properties.key?(:mode) # rubocop:disable Style/GuardClause
|
|
71
|
+
context.execute :chmod, recursive, access_properties.fetch(:mode), resolved_path
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
require 'i18n'
|
|
2
|
+
|
|
3
|
+
en = {
|
|
4
|
+
file: {
|
|
5
|
+
not_exists: 'File %{file} does not exist.',
|
|
6
|
+
not_exists_on_host: 'File %{file} does not exit on host %{host}.',
|
|
7
|
+
upload: 'Uploading %{file} to %{target}.',
|
|
8
|
+
download: 'Downloading %{file} to %{target}.',
|
|
9
|
+
copy: 'Copying %{file} to %{target}.',
|
|
10
|
+
remove: 'Removing %{path}.'
|
|
11
|
+
},
|
|
12
|
+
directory: {
|
|
13
|
+
create: 'Creating directory %{directory}.',
|
|
14
|
+
not_exists: 'Directory %{directory} does not exist.',
|
|
15
|
+
not_exists_on_host: 'Directory %{directory} does not exit on host %{host}.'
|
|
16
|
+
},
|
|
17
|
+
dsl: {
|
|
18
|
+
invoke_for_server: {
|
|
19
|
+
set_filter: "Invoking task '%{task}' for server '%{host}'"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
resource: {
|
|
23
|
+
not_exists_on_host: 'The resource %{resource} does not exist on host %{host}.',
|
|
24
|
+
empty_selected_custom_file_access: "The variable 'selected_custom_file_access' is empty. Aborting task...",
|
|
25
|
+
skipping_selected_custom_file_access: "Skipped setting custom_file_access permissions for '%{path}' because it is not mentioned in selected_custom_file_access!"
|
|
26
|
+
},
|
|
27
|
+
configuration: {
|
|
28
|
+
argument_missing: "The '%{name}' argument missing.",
|
|
29
|
+
argument_or_configuration_missing: "The '%{name}' argument or '%{variable}' configuration variable missing."
|
|
30
|
+
},
|
|
31
|
+
questions: {
|
|
32
|
+
database: {
|
|
33
|
+
host: 'Please enter the hostname/IP of the database server',
|
|
34
|
+
port: 'Please enter the port of the database server',
|
|
35
|
+
name: 'Please enter the database name',
|
|
36
|
+
username: 'Please enter the database username',
|
|
37
|
+
password: 'Please enter the database password',
|
|
38
|
+
table_name: 'Please enter the table name',
|
|
39
|
+
table_names: 'Please enter a list of table names (entries separated by spaces)',
|
|
40
|
+
charset: 'Please enter the database character set',
|
|
41
|
+
zipped_db_file: 'Please enter the name of the zipped SQL script file'
|
|
42
|
+
},
|
|
43
|
+
bower: {
|
|
44
|
+
command: 'Please enter the command you want to run',
|
|
45
|
+
path: 'Please enter the path to the bower.json file',
|
|
46
|
+
paths: 'Please enter the paths bower.json files (separated by spaces)'
|
|
47
|
+
},
|
|
48
|
+
selected_custom_file_access: {
|
|
49
|
+
paths: 'Please enter a list of paths (entries separated by spaces)'
|
|
50
|
+
},
|
|
51
|
+
path: 'Please enter a local path',
|
|
52
|
+
file_name: 'Please enter a file name',
|
|
53
|
+
username: 'Please enter a username',
|
|
54
|
+
password: 'Please enter a password',
|
|
55
|
+
compass_sources: 'Please enter compass sources (entries separated by spaces)',
|
|
56
|
+
compass_compile_arguments: 'Please enter compass compile arguments (entries separated by spaces)',
|
|
57
|
+
asset_folders: 'Please enter asset folders (entries separated by spaces)',
|
|
58
|
+
asset_default_content: 'Please enter asset default content (entries separated by spaces)',
|
|
59
|
+
local_web_root_path: 'Please enter a local web root path',
|
|
60
|
+
version_file_path: 'Please enter a version file path',
|
|
61
|
+
dir_names: 'Please specify the direcotory names you wish to create'
|
|
62
|
+
},
|
|
63
|
+
success: {
|
|
64
|
+
settings_uploaded: 'The given database settings have been uploaded'
|
|
65
|
+
},
|
|
66
|
+
errors: {
|
|
67
|
+
file_not_found: 'File not found.',
|
|
68
|
+
password_was_empty: 'Password was empty. Please enter a password.',
|
|
69
|
+
connection_failed: 'Connection to database could not be established',
|
|
70
|
+
database_config_file_missing: 'Unable to locate database config file on remote server.',
|
|
71
|
+
variable_content_is_neither_string_nor_array: "Error setting value of variable '%{variable_name}'. This is neither a (by space splittable) string nor an array!"
|
|
72
|
+
},
|
|
73
|
+
info: {
|
|
74
|
+
local_md5: 'Local MD5 hash: %{md5_hash}',
|
|
75
|
+
remote_md5: 'Remote MD5 hash: %{md5_hash}',
|
|
76
|
+
md5_match: 'Local MD5 hash matches remote MD5 hash. Nothing to do!',
|
|
77
|
+
ignoring_current_folder: 'Ignoring current folder because either it does not exist or it is symlinked.'
|
|
78
|
+
},
|
|
79
|
+
tasks: {
|
|
80
|
+
apache: {
|
|
81
|
+
htaccess: {
|
|
82
|
+
render: 'Rendering .htaccess file.'
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
assets: {
|
|
86
|
+
add_htpasswd: {
|
|
87
|
+
successfully_created: 'htpasswd file successfully created.'
|
|
88
|
+
},
|
|
89
|
+
cleanup: 'Cleaning folder %{folder}.',
|
|
90
|
+
download: 'Downloading %{folder}',
|
|
91
|
+
upload: 'Uploading %{file}',
|
|
92
|
+
upload_extract: 'Extracting %{file}',
|
|
93
|
+
exclude_file_not_found: "No exclude file found. To use set variable 'assets_exclude_file'"
|
|
94
|
+
},
|
|
95
|
+
bower: {
|
|
96
|
+
skipping_missing_directory: 'Skipping directory %{bower_path} because it does not exist.',
|
|
97
|
+
skipping_directory_with_missing_bower_file: 'Skipping directory %{bower_path} because it does not contain a bower.json file.'
|
|
98
|
+
},
|
|
99
|
+
copy: {
|
|
100
|
+
archive: {
|
|
101
|
+
generate: 'Generating the tar archive.',
|
|
102
|
+
extract: 'Extracting archive to %{target}.'
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
maintenance: {
|
|
106
|
+
enabled: 'The %{mode} maintenance mode has successfully been enabled.',
|
|
107
|
+
disabled: 'The %{mode} maintenance mode has successfully been disabled.',
|
|
108
|
+
can_not_disable_by_reason_of_permanent: "Maintenance permanent mode has been enabled. Please call the task 'maintenance:disable_permanent'."
|
|
109
|
+
},
|
|
110
|
+
project_version: {
|
|
111
|
+
update: {
|
|
112
|
+
update: 'Updating the Version file.'
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
utils: {
|
|
116
|
+
rsync: {
|
|
117
|
+
no_host: 'No hosts for rsync found. Please check configuration "rsync_roles".',
|
|
118
|
+
use_host: "Use host '%{host}' for rsync."
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
log: {
|
|
123
|
+
revision_log_message: "Local deployment for directory '%{copy_source}' at '%{time}'"
|
|
124
|
+
},
|
|
125
|
+
error_during_deployment: 'Error occurred at deployment. Rollback to old release',
|
|
126
|
+
rollback_tasks: "Calling tasks '%{tasks_for_rollback}' for rollback action",
|
|
127
|
+
failing_on_purpose: 'Failing this deployment on purpose!',
|
|
128
|
+
rollback_finished: 'Rollback finished',
|
|
129
|
+
keep_rollback_archives: 'Keeping %{keep_rollback_archives} of %{rollback_archives} rolled back releases on %{host}',
|
|
130
|
+
setting_verbosity: 'Setting verbosity level to: %{verbosity_level} (from: %{old_verbosity})',
|
|
131
|
+
resetting_verbosity: 'Reset verbosity level to: %{old_verbosity} (from: %{verbosity_level})'
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
capistrano_i18n_overwritten = {
|
|
135
|
+
revision_log_message: "%{sha} on release '%{release}' by '%{user}'"
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
I18n.backend.store_translations(:en, dkdeploy: en)
|
|
139
|
+
I18n.backend.store_translations(:en, capistrano: capistrano_i18n_overwritten)
|
|
140
|
+
|
|
141
|
+
if I18n.respond_to?(:enforce_available_locales=)
|
|
142
|
+
I18n.enforce_available_locales = true
|
|
143
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Dkdeploy
|
|
2
|
+
module InteractionHandler
|
|
3
|
+
# Interaction handler for password
|
|
4
|
+
#
|
|
5
|
+
# @attr [String] password The password to send to terminal
|
|
6
|
+
class Password
|
|
7
|
+
def initialize(password)
|
|
8
|
+
@password = password
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Method to send password to terminal
|
|
12
|
+
#
|
|
13
|
+
# @param [SSHKit::Command] _command
|
|
14
|
+
# @param [Symbol] _stream_name
|
|
15
|
+
# @param [String] data
|
|
16
|
+
# @param [Net::SSH::Connection::Channel] channel
|
|
17
|
+
def on_data(_command, _stream_name, data, channel)
|
|
18
|
+
if data =~ /.*password.*/i
|
|
19
|
+
channel.send_data("#{@password}\n")
|
|
20
|
+
else
|
|
21
|
+
channel.close
|
|
22
|
+
raise 'Unexpected data from stream. Can not send password to undefined stream'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Dkdeploy
|
|
2
|
+
# The RollbackManager module is a mixin for managing rollback tasks.
|
|
3
|
+
module RollbackManager
|
|
4
|
+
# Getter for rollback_tasks
|
|
5
|
+
#
|
|
6
|
+
# @return [Array]
|
|
7
|
+
def rollback_tasks
|
|
8
|
+
@rollback_tasks ||= []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Add new rollback task
|
|
12
|
+
#
|
|
13
|
+
# @param [String]
|
|
14
|
+
def add_rollback_task(task_name)
|
|
15
|
+
rollback_tasks << task_name if Rake::Task.task_defined? task_name
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
require 'capistrano/i18n'
|
|
3
|
+
require 'dkdeploy/i18n'
|
|
4
|
+
|
|
5
|
+
include Capistrano::DSL
|
|
6
|
+
include SSHKit::DSL
|
|
7
|
+
|
|
8
|
+
namespace :apache do
|
|
9
|
+
desc 'Render .htaccess to web root from erb template(s)'
|
|
10
|
+
task :htaccess do |_, args|
|
|
11
|
+
local_web_root_path = ask_array_variable(args, :local_web_root_path, 'questions.local_web_root_path')
|
|
12
|
+
|
|
13
|
+
run_locally do
|
|
14
|
+
apache_configuration_path = File.join 'config', 'etc', 'apache2', 'conf'
|
|
15
|
+
htaccess_file_path = File.join apache_configuration_path, '.htaccess.erb'
|
|
16
|
+
destination_htaccess_file_path = File.join local_web_root_path, '.htaccess'
|
|
17
|
+
|
|
18
|
+
if File.exist? htaccess_file_path
|
|
19
|
+
info I18n.t('tasks.apache.htaccess.render', scope: :dkdeploy)
|
|
20
|
+
htaccess_template = ERB.new File.read(htaccess_file_path)
|
|
21
|
+
|
|
22
|
+
# write the new htaccess file content to the target .htaccess file
|
|
23
|
+
File.open(destination_htaccess_file_path, 'w') do |io|
|
|
24
|
+
io.write htaccess_template.result(binding)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|