sync_stage 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,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: []