clone-af-cli-plugin 0.0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ require "rake"
2
+
3
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
4
+ require "clone-af-cli-plugin/version"
5
+
6
+ task :default => :spec
7
+
8
+ desc "Run specs"
9
+ task :spec => ["bundler:install", "test:spec"]
10
+
11
+ desc "Run integration tests"
12
+ task :test => ["bundler:install", "test:integration"]
13
+
14
+ task :build do
15
+ sh "gem build clone-af-cli-plugin.gemspec"
16
+ end
17
+
18
+ task :install => :build do
19
+ sh "gem install --local clone-af-cli-plugin-#{AFCLIClone::VERSION}.gem"
20
+ end
21
+
22
+ task :uninstall do
23
+ sh "gem uninstall clone-af-cli-plugin"
24
+ end
25
+
26
+ task :reinstall => [:uninstall, :install]
27
+
28
+ task :release => :build do
29
+ sh "gem push clone-af-cli-plugin-#{AFCLIClone::VERSION}.gem"
30
+ end
31
+
32
+ namespace "bundler" do
33
+ desc "Install gems"
34
+ task "install" do
35
+ sh("bundle install")
36
+ end
37
+ end
38
+
39
+ namespace "test" do
40
+ task "spec" do |t|
41
+ # nothing
42
+ end
43
+
44
+ task "integration" do |t|
45
+ sh("cd spec && bundle exec rake spec")
46
+ end
47
+ end
@@ -0,0 +1,134 @@
1
+ require "vmc/cli"
2
+
3
+ module AFCLIClone
4
+ class Clone < VMC::CLI
5
+ desc "Clone the application and services"
6
+ group :apps, :manage
7
+ input :src_app, :desc => "Source application", :argument => :optional,
8
+ :from_given => by_name(:app)
9
+ input :name, :desc => "Application name", :argument => :optional
10
+ input :infra, :desc => "Infrastructure to use", :from_given => by_name(:infra)
11
+ input :url, :desc => "Application url", :argument => :optional
12
+ input :nostart, :desc => "Do not start app", :default => false
13
+ def clone
14
+ src_app = input[:src_app]
15
+ dest_infra = input[:infra]
16
+ dest_app_name = input[:name, "#{src_app.name}-#{"%04x" % [rand(0x0100000)]}"]
17
+ app = client.app_by_name(dest_app_name)
18
+ fail "Application '#{dest_app_name}' already exists" unless app.nil?
19
+ dest_url = input[:url, "#{dest_app_name}.#{dest_infra.base}"]
20
+
21
+ # Start Clone
22
+ Dir.mktmpdir do |dir|
23
+
24
+ # Download source
25
+ zip_path = File.join(dir, src_app.name)
26
+ with_progress("Pulling last pushed source code") do
27
+ client.app_pull(src_app.name, zip_path)
28
+ end
29
+
30
+ # manifest = {
31
+ # :name => "#{dest_appname}",
32
+ # :staging => app[:staging],
33
+ # :uris => [ url ],
34
+ # :instances => app[:instances],
35
+ # :resources => app[:resources]
36
+ # }
37
+ # manifest[:staging][:command] = app[:staging][:command] if app[:staging][:command]
38
+ # manifest[:infra] = { :provider => dest_infra.name } if dest_infra
39
+
40
+ dest_app = client.app
41
+ dest_app.name = dest_app_name
42
+ dest_app.infra = dest_infra
43
+ dest_app.url = dest_url
44
+ dest_app.uris = [dest_url]
45
+ dest_app.total_instances = 1
46
+ dest_app.framework = src_app.framework
47
+ dest_app.command = src_app.command unless src_app.command.nil?
48
+ dest_app.runtime = src_app.runtime
49
+ dest_app.memory = src_app.memory
50
+ dest_app.env = src_app.env
51
+ dest_app = filter(:create_app, dest_app)
52
+ with_progress("Creating #{c(dest_app.name, :name)}") do
53
+ dest_app.create!
54
+ end
55
+
56
+ # Upload source
57
+ with_progress("Uploading source to #{c(dest_app.name, :name)}") do
58
+ dest_app.upload(zip_path)
59
+ end
60
+
61
+ # Clone services
62
+ src_app.services.each do |src_service|
63
+
64
+ # Export service data
65
+ export_info =
66
+ with_progress("Exporting service #{c(src_service.name, :name)}") do
67
+ client.export_service(src_service.name)
68
+ end
69
+
70
+ export_url = export_info[:uri]
71
+
72
+ # Create new service
73
+ cloned_service_name = generate_cloned_service_name(src_app.name, dest_app_name, src_service.name, dest_infra.name)
74
+ dest_service = client.service_instance
75
+ dest_service.infra_name = dest_infra.name
76
+ dest_service.name = cloned_service_name
77
+ dest_service.type = src_service.type
78
+ dest_service.vendor = src_service.vendor
79
+ dest_service.version = src_service.version.to_s
80
+ dest_service.tier = src_service.tier
81
+ with_progress("Creating service #{c(dest_service.name, :name)}") do
82
+ dest_service.create!
83
+ end
84
+
85
+ # Bind new service to app
86
+ with_progress("Binding service #{c(dest_service.name, :name)} to #{c(dest_app.name, :name)}") do
87
+ dest_app.bind(dest_service)
88
+ end
89
+
90
+ # Import service data
91
+ import_info =
92
+ with_progress("Importing data to service #{c(dest_service.name, :name)}") do
93
+ client.import_service(dest_service.name, export_url)
94
+ end
95
+ end
96
+
97
+ if !input[:nostart]
98
+ with_progress("Starting #{c(dest_app.name, :name)}") do
99
+ dest_app.start!
100
+ end
101
+ end
102
+
103
+ end
104
+ end
105
+
106
+ private
107
+
108
+ def ask_url(default)
109
+ ask("New application url?", :default => default)
110
+ end
111
+
112
+ def ask_name(default)
113
+ ask("New application name?", :default => default)
114
+ end
115
+
116
+ def ask_infra
117
+ ask("Which Infrastructure?", :choices => client.infras,
118
+ :display => proc(&:name))
119
+ end
120
+
121
+ def generate_cloned_service_name(src_appname, dest_appname, src_servicename, dest_infra)
122
+ r = "%04x" % [rand(0x0100000)]
123
+ dest_servicename = src_servicename.sub(src_appname, dest_appname).sub(/-[0-9A-Fa-f]{4,5}/,"-#{r}")
124
+ if src_servicename == dest_servicename
125
+ if dest_infra
126
+ dest_servicename = "#{dest_servicename}-#{dest_infra}"
127
+ else
128
+ dest_servicename = "#{dest_servicename}-#{r}"
129
+ end
130
+ end
131
+ dest_servicename
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,3 @@
1
+ module AFCLIClone
2
+ VERSION = "0.0.0.1".freeze
3
+ end
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: clone-af-cli-plugin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tim Santeford
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: cfoundry
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.5.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.5.0
30
+ description:
31
+ email:
32
+ - tim@appfog.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - Rakefile
38
+ - lib/clone-af-cli-plugin/plugin.rb
39
+ - lib/clone-af-cli-plugin/version.rb
40
+ homepage: http://www.appfog.com/
41
+ licenses: []
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ requirements: []
59
+ rubyforge_project: clone-af-cli-plugin
60
+ rubygems_version: 1.8.23
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: Clones applications between infras
64
+ test_files: []