clone-af-cli-plugin 0.0.0.1

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.
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: []