sync_stage 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4e34cfd09708a90565acd4bdb43e1f3830033afc
4
+ data.tar.gz: 9929baa91e3561aa29aa5d37d06a151aa1cc0e4e
5
+ SHA512:
6
+ metadata.gz: 2f628cf1467eb82d12da6dc5b1e30d5b2f707bdeb8f9609b638d0a99d473b555f672c5dffc15929ac1ebc97de51badee3369ded72d1f76b61cc1759611e8592d
7
+ data.tar.gz: f504916ed256d5e270ca2f955281afc94104c3892ac5461541f0262c2034a0cf73dbec9b5c03ec2f7a18e9b87f0a02c06ad22d93dc37869bc8c550e572db9aa0
data/bin/sync_stage ADDED
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'sync_stage'
4
+ require 'getoptlong'
5
+ require 'ostruct'
6
+
7
+ opts = GetoptLong.new(
8
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
9
+ [ '--init', '-i', GetoptLong::NO_ARGUMENT ],
10
+ [ '--run', '-r', GetoptLong::NO_ARGUMENT ],
11
+ [ '--restore', GetoptLong::NO_ARGUMENT ],
12
+ [ '--explain', GetoptLong::NO_ARGUMENT],
13
+ [ '--app', '-a', GetoptLong::REQUIRED_ARGUMENT ]
14
+ )
15
+
16
+ app = nil
17
+ init = nil
18
+ run = nil
19
+ restore = nil
20
+ explain = nil
21
+
22
+ if ARGV.length == 0
23
+ puts "missing argument try --help"
24
+ end
25
+
26
+ opts.each do |opt, arg|
27
+ case opt
28
+ when '--help'
29
+ puts <<-EOF
30
+ sync_stage [OPTION]
31
+
32
+ -h, --help:
33
+ show help
34
+
35
+ --init, -i:
36
+ initializes sync_stage config in current directory
37
+ or in --dir if --dir is given
38
+
39
+ --explain:
40
+ print out what would happen, but dont actually run the commands
41
+
42
+ --run, -r:
43
+ actually start the dump, pack, copy over to destination
44
+
45
+
46
+ --app DIR, -a DIR:
47
+ use given Directory
48
+
49
+ --restore:
50
+ pg_restore the database and unpack shared/public
51
+ on destination system
52
+
53
+ EOF
54
+ exit 0
55
+ when '--app'
56
+ app = arg
57
+ when '--init'
58
+ init = true
59
+ when '--run'
60
+ run = true
61
+ when '--restore'
62
+ restore = true
63
+ when '--explain'
64
+ explain = true
65
+ end
66
+ end
67
+
68
+
69
+ if init && run
70
+ puts "incompatible arguments -i and -r"
71
+ exit 0
72
+ end
73
+
74
+ if init
75
+ cfg = OpenStruct.new(app: app||Dir.pwd, init: true)
76
+ st = SyncStage::Worker.new(cfg)
77
+ exit 0
78
+ end
79
+
80
+ if app && !run
81
+ puts "missing argument -r to run"
82
+ end
83
+
84
+ if run
85
+ cfg = OpenStruct.new(app: app||Dir.pwd, run: run, restore: restore, explain: explain)
86
+ st = SyncStage::Worker.new(cfg)
87
+ end
@@ -0,0 +1,13 @@
1
+ :source:
2
+ :host: www.example.com
3
+ :user: deploymentuser
4
+ :db: app_production
5
+ :dbuser: user
6
+ :shared_dir: /var/www/www.example.com/shared
7
+
8
+ :destination:
9
+ :host: staging.example.com
10
+ :user: deploymentuser
11
+ :db: app_staging
12
+ :dbuser: user
13
+ :shared_dir: /var/www/staging.example.com/shared
data/lib/sync_stage.rb ADDED
@@ -0,0 +1,194 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'yaml'
4
+ require 'pp'
5
+
6
+ module SyncStage
7
+ class Worker
8
+
9
+ def initialize(cfg)
10
+ s = Time.now
11
+ Dir.chdir(cfg.app) do
12
+ if !File.exist?('sync_stage.yml')
13
+ if ! cfg.init
14
+ puts "Directory not initialized - try argument --init or see --help"
15
+ exit 1
16
+ end
17
+ if cfg.init
18
+ create_example_config(cfg.app)
19
+ end
20
+ else
21
+ read_config
22
+ end
23
+ end
24
+ if cfg.explain
25
+ explain(cfg.restore)
26
+ exit 0
27
+ end
28
+ if cfg.run
29
+ run(cfg.restore)
30
+ end
31
+ duration = Time.now - s
32
+ puts "synced data \nfrom #{@config[:source].fetch(:host)} to #{@config[:destination].fetch(:host)} \n
33
+ done in #{duration.ceil} seconds."
34
+ end
35
+
36
+ private
37
+
38
+ def explain(restore)
39
+ puts "sync_stage would use following settings: \n\n"
40
+ pp @config
41
+
42
+ cmds = []
43
+ cmds.push(ssh_cmd(@config[:source]) << "'" << pg_dump_cmd(@config[:source]) << "'")
44
+ cmds.push(ssh_cmd(@config[:source]) << "'" << pack_assets_cmd(@config[:source]) << "'")
45
+ cmds.push(copy_db_cmd(@config[:source], @config[:destination]))
46
+ cmds.push(copy_assets_cmd(@config[:source], @config[:destination]))
47
+ if restore
48
+ cmds.push(ssh_cmd(@config[:destination]) << "-t '" <<
49
+ pg_restore_cmd(@config[:source], @config[:destination]) << "'")
50
+ cmds.push(ssh_cmd(@config[:destination]) << "'" <<
51
+ unpack_assets_cmd(@config[:source], @config[:destination]) << "'")
52
+ end
53
+ puts "\nand run the following commands in order: \n\n"
54
+ cmds.each_with_index do |c,i|
55
+ puts "#{i} $: " << c
56
+ end
57
+ end
58
+
59
+
60
+ def run(restore)
61
+ puts "this could take a while....\n"
62
+ execute_db_dump
63
+ execute_asset_packing
64
+ execute_db_copying
65
+ execute_asset_copying
66
+ if restore
67
+ execute_db_restoring
68
+ execute_asset_unpacking
69
+ end
70
+ end
71
+
72
+ def execute_db_dump
73
+ ret = system(ssh_cmd(@config[:source]) << "'" << pg_dump_cmd(@config[:source]) << "'")
74
+ if ret
75
+ puts "done dumping database"
76
+ else
77
+ raise "error dumping database"
78
+ end
79
+ end
80
+
81
+ def execute_asset_packing
82
+ ret = system(ssh_cmd(@config[:source]) << "'" << pack_assets_cmd(@config[:source]) << "'")
83
+ if ret
84
+ puts "done packing shared directory"
85
+ else
86
+ raise "error packing shared directory"
87
+ end
88
+ end
89
+
90
+ def execute_db_copying
91
+ ret = system(copy_db_cmd(@config[:source], @config[:destination]))
92
+ if ret
93
+ puts "done copying database over"
94
+ else
95
+ raise "error copying database over"
96
+ end
97
+ end
98
+
99
+ def execute_asset_copying
100
+ puts "start to copy over shared dir... be patient..."
101
+ ret = system(copy_assets_cmd(@config[:source], @config[:destination]))
102
+ if ret
103
+ puts "done copying assets"
104
+ else
105
+ raise "error copying assets over"
106
+ end
107
+ end
108
+
109
+ def execute_db_restoring
110
+ ret = system(ssh_cmd(@config[:destination]) << " -t '" <<
111
+ pg_restore_cmd(@config[:source], @config[:destination]) << "'")
112
+ if ret
113
+ puts "done restoring database"
114
+ else
115
+ raise "error restoring database"
116
+ end
117
+ end
118
+
119
+ def execute_asset_unpacking
120
+ ret = system(ssh_cmd(@config[:destination]) << "'" << unpack_assets_cmd(@config[:source], @config[:destination]) << "'")
121
+ if ret
122
+ puts "done unpacking shared dir"
123
+ else
124
+ raise "error unpacking shared dir"
125
+ end
126
+ end
127
+
128
+ def pg_dump_cmd(opts)
129
+ str = "pg_dump -U #{opts.fetch(:dbuser)} -h localhost -Fc #{opts.fetch(:db)} -f ~/#{opts.fetch(:db)}.sql"
130
+ str
131
+ end
132
+
133
+ def pack_assets_cmd(opts)
134
+ str = "cd #{opts.fetch(:shared_dir)} && tar cvfzp ~/#{opts.fetch(:host)}-shared.tgz ./public"
135
+ str
136
+ end
137
+
138
+ def ssh_cmd(opts)
139
+ "ssh -l #{opts.fetch(:user)} #{opts.fetch(:host)} "
140
+ end
141
+
142
+ def copy_db_cmd(from_opts, to_opts)
143
+ str = "scp #{from_opts.fetch(:user)}@#{from_opts.fetch(:host)}:~/#{from_opts.fetch(:db)}.sql "
144
+ str << " #{to_opts.fetch(:user)}@#{to_opts.fetch(:host)}:~/"
145
+ str
146
+ end
147
+
148
+ def copy_assets_cmd(from_opts, to_opts)
149
+ str = "scp #{from_opts.fetch(:user)}@#{from_opts.fetch(:host)}:~/#{from_opts.fetch(:host)}-shared.tgz "
150
+ str << " #{to_opts.fetch(:user)}@#{to_opts.fetch(:host)}:#{to_opts.fetch(:shared_dir)}/"
151
+ str
152
+ end
153
+
154
+ def pg_restore_cmd(src, dest)
155
+ str = "sudo -u postgres pg_restore -U postgres -v -d #{dest.fetch(:db)} -c #{src.fetch(:db)}.sql"
156
+ str
157
+ end
158
+
159
+ def unpack_assets_cmd(src, dest)
160
+ str = "cd #{dest.fetch(:shared_dir)} &&
161
+ mv public public-#{Time.now.to_i} &&
162
+ tar xvfzp #{src.fetch(:host)}-shared.tgz"
163
+ str
164
+ end
165
+
166
+ def create_example_config(dir)
167
+ puts Dir.pwd
168
+ _example = YAML::load_file(File.join(File.dirname(__FILE__),'config', 'sync_stage.yml'))
169
+ File.open('sync_stage.yml', 'w') do |f|
170
+ f.puts YAML::dump(_example)
171
+ end
172
+ end
173
+
174
+ def read_config
175
+ @config = YAML::load_file('sync_stage.yml')
176
+ end
177
+ end
178
+ end
179
+
180
+
181
+ # pack the assets
182
+ #ret = system(ssh_cmd(PRODUCTION) << "'" << pack_assets_cmd(PRODUCTION) << "'")
183
+ #ret = system(copy_assets_cmd(PRODUCTION, STAGING))
184
+
185
+ # dump the database
186
+ #ret = system(ssh_cmd(PRODUCTION) << "'" << pg_dump_cmd(PRODUCTION) << "'")
187
+
188
+ # copy db-dump to other host
189
+ #ret = system(copy_db_cmd(PRODUCTION, STAGING))
190
+
191
+ # restore db from dump
192
+ #puts "you need to be a sudoer"
193
+ #ret = system(ssh_cmd(STAGING) << " -t '" << pg_restore_cmd(PRODUCTION, STAGING) << "'")
194
+
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sync_stage
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - rene paulokat
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-11 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: dumps and restores postgres database and packs shared/public over to
14
+ staging server
15
+ email: rene@so36.net
16
+ executables:
17
+ - sync_stage
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - bin/sync_stage
22
+ - lib/config/sync_stage.yml
23
+ - lib/sync_stage.rb
24
+ homepage: https://github.com/erpe/sync_stage
25
+ licenses:
26
+ - GPLv3
27
+ metadata: {}
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 2.4.5
45
+ signing_key:
46
+ specification_version: 4
47
+ summary: Sync your Rails-App data back from production to staging
48
+ test_files: []