dister 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog ADDED
@@ -0,0 +1,9 @@
1
+ Fri May 06 16:46:10 CEST 2011 Flavio Castelli <flavio@castelli.name>
2
+
3
+ * appliance building: ask the user what to do when there's already an
4
+ image with the same version.
5
+ * release version 1.0.1
6
+
7
+ Wed May 04 16:00:00 CEST 2011 Flavio Castelli <flavio@castelli.name>
8
+
9
+ * released first version 1.0.0
data/dister.gemspec CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.authors = ['Flavio Castelli', 'Dominik Mayer']
9
9
  s.email = ['flavio@castelli.name','dmayer@novell.com']
10
- s.homepage = "https://features.opensuse.org/311133"
10
+ s.homepage = "https://github.com/flavio/dister"
11
11
  s.summary = "Heroku like solution for SUSE Studio"
12
12
  s.description = "Turn your rails app into a SUSE Studio appliance in a few steps."
13
13
 
@@ -16,7 +16,7 @@ Gem::Specification.new do |s|
16
16
 
17
17
  s.add_dependency "curb"
18
18
  s.add_dependency "progressbar"
19
- s.add_dependency "studio_api", "~>3.1.0"
19
+ s.add_dependency "studio_api", "~>3.1.1"
20
20
  s.add_dependency "thor", "~>0.14.0"
21
21
 
22
22
  s.add_development_dependency "bundler", "~>1.0.0"
data/lib/dister.rb CHANGED
@@ -7,6 +7,7 @@ require 'bundler'
7
7
  require 'curb'
8
8
 
9
9
  require File.expand_path('../dister/cli', __FILE__)
10
+ require File.expand_path('../dister/constants', __FILE__)
10
11
  require File.expand_path('../dister/core', __FILE__)
11
12
  require File.expand_path('../dister/options', __FILE__)
12
13
  require File.expand_path('../dister/utils', __FILE__)
data/lib/dister/cli.rb CHANGED
@@ -1,11 +1,6 @@
1
1
  module Dister
2
2
 
3
3
  class Cli < Thor
4
-
5
- VALID_TEMPLATES = %w(JeOS Server X Gnome KDE)
6
- VALID_FOMATS = %w(oem vmx iso xen) #TODO: add other formats
7
- VALID_ARCHS = %w(i686 x86_64)
8
-
9
4
  include Thor::Actions
10
5
 
11
6
  # Returns Dister's root directory.
@@ -32,17 +27,38 @@ module Dister
32
27
  ensure_valid_option options[:arch], VALID_ARCHS, "arch"
33
28
  ensure_valid_option options[:template], VALID_TEMPLATES, "template"
34
29
  basesystems = @core.basesystems
35
- basesystem = options[:basesystem] || basesystems.find_all{|a| a =~ /\d+\.\d+/}.sort.last
30
+ if basesystems.empty?
31
+ STDERR.puts "No basesystem found, contact server administrator"
32
+ exit 1
33
+ end
34
+
35
+ if options[:basesystem].nil?
36
+ # attempt to find latest version of openSUSE
37
+ basesystem = basesystems.find_all{|a| a =~ /\d+\.\d+/}.sort.last
38
+ if basesystem.nil?
39
+ # apparently this server doesn't offer openSUSE basesystem
40
+ @shell.say "Available base systems:"
41
+ basesystems.each_with_index { |b,i| @shell.say "#{i+1} - #{b}" }
42
+ begin
43
+ choice = @shell.ask("Which base system do you want to use?"\
44
+ "[1-#{basesystems.size}]")
45
+ end while (choice.to_i > basesystems.size || choice.to_i < 1)
46
+ basesystem = basesystems[choice.to_i - 1]
47
+ end
48
+ else
49
+ basesystem = options[:basesystem]
50
+ end
36
51
  ensure_valid_option basesystem, basesystems, "base system"
37
52
  # Create appliance and add patterns required to build native gems.
38
53
  @core.create_appliance(appliance_name, options[:template], basesystem, options[:arch])
39
54
  end
40
55
 
41
56
  desc "build", "Build the appliance."
57
+ method_option :force, :type => :boolean, :default => false, :required => false
42
58
  def build
43
59
  access_core
44
60
  ensure_appliance_exists
45
- if @core.build
61
+ if @core.build options
46
62
  puts "Appliance successfully built."
47
63
  else
48
64
  puts "Build failed."
@@ -70,14 +86,14 @@ module Dister
70
86
  def format(operation,format = nil)
71
87
  access_core
72
88
  ensure_valid_option operation, %w(add rm list), "operation"
73
- if operation == 'list' and options[:all]
89
+ if operation == 'list'
74
90
  puts "Available formats:"
75
- puts VALID_FOMATS
91
+ puts VALID_FORMATS
76
92
  else
77
93
  existing_types = @core.options.build_types || []
78
94
  chosen_types = case operation
79
95
  when "add"
80
- ensure_valid_option format, VALID_FOMATS, "format"
96
+ ensure_valid_option format, VALID_FORMATS, "format"
81
97
  @core.options.build_types = (existing_types + [format]).uniq
82
98
  when "rm"
83
99
  @core.options.build_types = (existing_types - [format])
@@ -0,0 +1,5 @@
1
+ module Dister
2
+ VALID_TEMPLATES = %w(JeOS Server X Gnome KDE)
3
+ VALID_FORMATS = [ 'xen', 'oem', 'vmx', 'iso', 'ec2', 'net', 'oemiso' ]
4
+ VALID_ARCHS = %w(i686 x86_64)
5
+ end
data/lib/dister/core.rb CHANGED
@@ -75,13 +75,31 @@ module Dister
75
75
  app
76
76
  end
77
77
 
78
- def build
78
+ def build build_options = {}
79
79
  verify_status
80
- #TODO: build using another format
81
- build = StudioApi::RunningBuild.create(
82
- :appliance_id => @options.appliance_id,
83
- :image_type => "oem"
84
- )
80
+ #TODO:
81
+ # * build using another format
82
+ force = build_options[:force]
83
+ version = nil
84
+ begin
85
+ params = {
86
+ :appliance_id => @options.appliance_id,
87
+ :image_type => "oem"
88
+ }
89
+ params[:force] = force if force
90
+ params[:version] = version if version
91
+ build = StudioApi::RunningBuild.create(params)
92
+ rescue StudioApi::ImageAlreadyExists
93
+ @shell.say 'An image with the same version already exists'
94
+ overwrite = @shell.ask? 'Do you want to overwrite it? (y/n)'
95
+ if overwrite == 'y'
96
+ force = true
97
+ retry
98
+ else
99
+ version = @shell.ask? 'Enter new version number:'
100
+ retry
101
+ end
102
+ end
85
103
 
86
104
  build.reload
87
105
  if build.state == "queued"
@@ -291,7 +309,7 @@ module Dister
291
309
  begin
292
310
  choice = @shell.ask("Which repo do you want to use? "\
293
311
  "[1-#{repositories.size+1}]")
294
- end while (choice.to_i > (repositories.size+1))
312
+ end while (choice.to_i > (repositories.size+1) || choice.to_i < 1)
295
313
  if (choice.to_i == (repositories.size+1))
296
314
  abort("Package not added.")
297
315
  else
@@ -1,4 +1,3 @@
1
- require 'ruby-debug'
2
1
  module Dister
3
2
  class Downloader
4
3
  attr_reader :filename
@@ -1,5 +1,5 @@
1
1
  module Dister
2
2
 
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.1"
4
4
 
5
5
  end
data/test/cli_test.rb CHANGED
@@ -114,6 +114,49 @@ class CliTest < Test::Unit::TestCase
114
114
  end
115
115
  end
116
116
 
117
+ should "exit if no base system is available" do
118
+ STDERR.stubs(:puts)
119
+ Dister::Core.any_instance.stubs(:basesystems).returns([])
120
+ assert_raise SystemExit do
121
+ Dister::Cli.start(['create', 'foo'])
122
+ end
123
+ end
124
+
125
+ context "openSUSE base system is not available" do
126
+ setup do
127
+ @basesystems = ["SLED10_SP2", "SLES10_SP2", "SLED11", "SLES11",
128
+ "SLES11_SP1", "SLED11_SP1", "SLED10_SP3",
129
+ "SLES10_SP3", "SLES11_SP1_VMware"]
130
+ Dister::Core.any_instance.stubs(:basesystems).returns(@basesystems)
131
+ end
132
+
133
+ should "ask the user which base system to use" do
134
+ Thor::Shell::Color.any_instance.stubs(:say)
135
+ Thor::Shell::Color.any_instance.expects(:ask).returns(1)
136
+ fake_app = mock()
137
+ fake_app.stubs(:edit_url).returns("http://susestudio.com")
138
+ Dister::Core.any_instance.expects(:create_appliance).\
139
+ with("foo", "JeOS", @basesystems[0], "i686").\
140
+ returns(fake_app)
141
+
142
+ assert_nothing_raised do
143
+ Dister::Cli.start(['create', 'foo'])
144
+ end
145
+ end
146
+
147
+ should "not ask the user which base system to use if there's a preference" do
148
+ Thor::Shell::Color.any_instance.expects(:ask).never
149
+ fake_app = mock()
150
+ fake_app.stubs(:edit_url).returns("http://susestudio.com")
151
+ Dister::Core.any_instance.expects(:create_appliance).\
152
+ with("foo", "JeOS", @basesystems[0], "i686").\
153
+ returns(fake_app)
154
+ assert_nothing_raised do
155
+ Dister::Cli.start(['create', 'foo', "--basesystem", @basesystems[0]])
156
+ end
157
+ end
158
+ end
159
+
117
160
  should "detect bad combination of template and basesystem" do
118
161
  STDERR.stubs(:puts)
119
162
  assert_raise(SystemExit) do
data/test/core_test.rb CHANGED
@@ -3,6 +3,11 @@ require File.expand_path('../test_helper', __FILE__)
3
3
  class CoreTest < Test::Unit::TestCase
4
4
  context "Using FakeFS -" do
5
5
  setup do
6
+ @core = Dister::Core.new
7
+ @core.stubs(:puts)
8
+ @core.options.appliance_id = 1
9
+ STDERR.stubs(:puts)
10
+
6
11
  FakeFS.activate!
7
12
  end
8
13
 
@@ -12,22 +17,19 @@ class CoreTest < Test::Unit::TestCase
12
17
 
13
18
  context "file uploading" do
14
19
  should "not upload non-existing files" do
15
- STDERR.stubs(:puts)
16
- core = Dister::Core.new
17
- assert !core.file_upload("foo")
20
+ assert !@core.file_upload("foo")
18
21
  end
19
22
 
20
23
  should "upload an existing files" do
24
+ Dister::Utils.stubs(:print)
21
25
  STDOUT.stubs(:puts)
22
26
  FileUtils.touch "foo"
23
- core = Dister::Core.new
24
- core.stubs(:puts)
25
27
  StudioApi::File.expects(:find).once.returns([])
26
28
  StudioApi::File.expects(:upload).\
27
- with(is_a(File), nil, {}).\
29
+ with(is_a(File), @core.options.appliance_id, {}).\
28
30
  once.\
29
31
  returns(true)
30
- assert core.file_upload("foo", {})
32
+ assert @core.file_upload("foo", {})
31
33
  end
32
34
  end
33
35
 
@@ -54,6 +56,79 @@ class CoreTest < Test::Unit::TestCase
54
56
  end
55
57
  end
56
58
 
59
+ context "Build an appliance" do
60
+ setup do
61
+ @core = Dister::Core.new
62
+ @core.options.appliance_id = 1
63
+ @core.stubs(:puts)
64
+ Dister::Utils.stubs(:print)
65
+
66
+ # do not clutter unit test results with a progress bar
67
+ silent_pbar = mock()
68
+ silent_pbar.stubs(:set)
69
+ silent_pbar.stubs(:finish)
70
+ ProgressBar.stubs(:new).returns(silent_pbar)
71
+
72
+ @core.expects(:verify_status).returns(true)
73
+ end
74
+
75
+ context 'an image with the same version already exists' do
76
+ should 'overwrite it if the user wants' do
77
+ build_sequence = sequence('build_sequence')
78
+ StudioApi::RunningBuild.expects(:create).\
79
+ with( { :appliance_id => @core.options.appliance_id,
80
+ :image_type => 'oem' } ).\
81
+ once.\
82
+ raises(StudioApi::ImageAlreadyExists).\
83
+ in_sequence(build_sequence)
84
+ @core.shell.expects(:say).in_sequence(build_sequence)
85
+ @core.shell.expects(:ask?).in_sequence(build_sequence).\
86
+ returns('y')
87
+ fake_build = mock()
88
+ StudioApi::RunningBuild.expects(:create).\
89
+ with( { :appliance_id => @core.options.appliance_id,
90
+ :image_type => 'oem',
91
+ :force => true } ).\
92
+ once.\
93
+ returns(fake_build).\
94
+ in_sequence(build_sequence)
95
+
96
+ fake_build.stubs(:reload)
97
+ fake_build.stubs(:state).returns('finished')
98
+ @core.build
99
+ end
100
+
101
+ should 'use the new version specified by the user' do
102
+ new_version = '1.0.1'
103
+ build_sequence = sequence('build_sequence')
104
+ StudioApi::RunningBuild.expects(:create).\
105
+ with( { :appliance_id => @core.options.appliance_id,
106
+ :image_type => 'oem' } ).\
107
+ once.\
108
+ raises(StudioApi::ImageAlreadyExists).\
109
+ in_sequence(build_sequence)
110
+ @core.shell.expects(:say).in_sequence(build_sequence)
111
+ @core.shell.expects(:ask?).in_sequence(build_sequence).\
112
+ returns('n')
113
+ @core.shell.expects(:ask?).in_sequence(build_sequence).\
114
+ returns(new_version)
115
+ fake_build = mock()
116
+ StudioApi::RunningBuild.expects(:create).\
117
+ with( { :appliance_id => @core.options.appliance_id,
118
+ :image_type => 'oem',
119
+ :version => new_version } ).\
120
+ once.\
121
+ returns(fake_build).\
122
+ in_sequence(build_sequence)
123
+
124
+ fake_build.stubs(:reload)
125
+ fake_build.stubs(:state).returns('finished')
126
+ @core.build
127
+ end
128
+
129
+ end
130
+ end
131
+
57
132
  context "verify status" do
58
133
  setup do
59
134
  @core = Dister::Core.new
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dister
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 25
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 0
10
- version: 0.1.0
9
+ - 1
10
+ version: 0.1.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Flavio Castelli
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-05-05 00:00:00 +02:00
19
+ date: 2011-05-06 00:00:00 +02:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -55,12 +55,12 @@ dependencies:
55
55
  requirements:
56
56
  - - ~>
57
57
  - !ruby/object:Gem::Version
58
- hash: 3
58
+ hash: 1
59
59
  segments:
60
60
  - 3
61
61
  - 1
62
- - 0
63
- version: 3.1.0
62
+ - 1
63
+ version: 3.1.1
64
64
  type: :runtime
65
65
  version_requirements: *id003
66
66
  - !ruby/object:Gem::Dependency
@@ -165,6 +165,7 @@ extra_rdoc_files: []
165
165
 
166
166
  files:
167
167
  - .gitignore
168
+ - Changelog
168
169
  - Gemfile
169
170
  - LICENSE
170
171
  - README.rdoc
@@ -177,6 +178,7 @@ files:
177
178
  - lib/adapters/sqlite3.yml
178
179
  - lib/dister.rb
179
180
  - lib/dister/cli.rb
181
+ - lib/dister/constants.rb
180
182
  - lib/dister/core.rb
181
183
  - lib/dister/db_adapter.rb
182
184
  - lib/dister/downloader.rb
@@ -196,7 +198,7 @@ files:
196
198
  - test/options_test.rb
197
199
  - test/test_helper.rb
198
200
  has_rdoc: true
199
- homepage: https://features.opensuse.org/311133
201
+ homepage: https://github.com/flavio/dister
200
202
  licenses: []
201
203
 
202
204
  post_install_message: