machinery-tool 1.12.0 → 1.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/NEWS +20 -0
  3. data/export_helpers/containerize_readme.md +28 -11
  4. data/html/comparison.html.haml +3 -3
  5. data/lib/build_task.rb +8 -6
  6. data/lib/cli.rb +69 -17
  7. data/lib/compare_task.rb +1 -1
  8. data/lib/config_base.rb +1 -1
  9. data/lib/config_task.rb +4 -1
  10. data/lib/containerize_task.rb +15 -1
  11. data/lib/containerized_app.rb +27 -0
  12. data/lib/hint.rb +18 -6
  13. data/lib/html.rb +17 -0
  14. data/lib/inspect_task.rb +6 -0
  15. data/lib/inspector.rb +2 -1
  16. data/lib/kiwi_config.rb +14 -1
  17. data/lib/logged_cheetah.rb +1 -20
  18. data/lib/machinery.rb +1 -0
  19. data/lib/remote_system.rb +2 -1
  20. data/lib/scope.rb +22 -2
  21. data/lib/serve_html_task.rb +1 -1
  22. data/lib/show_task.rb +1 -1
  23. data/lib/system.rb +6 -0
  24. data/lib/system_description.rb +4 -3
  25. data/lib/version.rb +1 -1
  26. data/lib/workload_mapper.rb +1 -0
  27. data/man/generated/machinery.1.gz +0 -0
  28. data/man/generated/machinery.1.html +16 -4
  29. data/plugins/changed_managed_files/schema/system-description-changed-managed-files.schema-v5.json +126 -0
  30. data/plugins/config_files/schema/system-description-config-files.schema-v5.json +126 -0
  31. data/plugins/environment/environment.md +1 -0
  32. data/plugins/environment/environment_inspector.rb +50 -0
  33. data/plugins/environment/environment_model.rb +22 -0
  34. data/plugins/environment/schema/system-description-environment.schema-v5.json +13 -0
  35. data/plugins/groups/schema/system-description-groups.schema-v5.json +30 -0
  36. data/plugins/os/os_model.rb +4 -0
  37. data/plugins/os/schema/system-description-os.schema-v5.json +21 -0
  38. data/plugins/packages/schema/system-description-packages.schema-v5.json +34 -0
  39. data/plugins/patterns/schema/system-description-patterns.schema-v5.json +24 -0
  40. data/plugins/repositories/schema/system-description-repositories.schema-v5.json +45 -0
  41. data/plugins/services/schema/system-description-services.schema-v5.json +30 -0
  42. data/plugins/unmanaged_files/schema/system-description-unmanaged-files.schema-v5.json +144 -0
  43. data/plugins/unmanaged_files/unmanaged_files_inspector.rb +45 -23
  44. data/plugins/users/schema/system-description-users.schema-v5.json +61 -0
  45. data/schema/migrations/migrate4to5.rb +28 -0
  46. data/schema/system-description-global.schema-v5.json +43 -0
  47. data/workload_mapper/docker-registry/clue.rb +14 -0
  48. data/workload_mapper/docker-registry/compose-template.yml +5 -0
  49. data/workload_mapper/docker-registry/container/Dockerfile +12 -0
  50. data/workload_mapper/mariadb/clue.rb +5 -0
  51. data/workload_mapper/mariadb/compose-template.yml +9 -0
  52. data/workload_mapper/mariadb/container/Dockerfile +13 -0
  53. data/workload_mapper/mariadb/container/scripts/config_mariadb.sh +49 -0
  54. data/workload_mapper/mariadb/container/scripts/start.sh +11 -0
  55. data/workload_mapper/rails/clue.rb +16 -0
  56. data/workload_mapper/rails/compose-template.yml +5 -0
  57. data/workload_mapper/rails/config/config/database.yml +7 -0
  58. data/workload_mapper/rails/container/Dockerfile +48 -0
  59. data/workload_mapper/rails/container/apache2/httpd.conf.local +5 -0
  60. data/workload_mapper/rails/container/apache2/listen.conf +1 -0
  61. data/workload_mapper/rails/container/apache2/rails_app_vhost.conf +13 -0
  62. data/workload_mapper/rails/container/apache2/sysconfig_apache2 +280 -0
  63. data/workload_mapper/rails/setup/setup.rb.erb +72 -0
  64. metadata +248 -214
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 59b0cae046e00683fea873260999de11ce3ad562
4
- data.tar.gz: 295b43b9d42e832be6f78363cee7f8c91c25a47d
3
+ metadata.gz: f8e32d15586f31cf49aae783ee024ec80441361d
4
+ data.tar.gz: b25baa2048d9e5842f21813156e44b67ad833fd6
5
5
  SHA512:
6
- metadata.gz: be116d55112cf6d945db98ce6ce4723644df3753904d5811b9c7abe05f0dfc4b4199bb574025d9b3833b4fc642df6132103937b0a4aeb48fe551627a024d0253
7
- data.tar.gz: 76221ef972ded4ce554d3b4e7e085477b7071057ef26847a6d40cf20ef94142aced57b5109cad75274135b8a0fe7573c3d815eab092d91066fcfe95131d217a8
6
+ metadata.gz: 113477103631ae51730ea31d2da454aaf867e5c1576a87c41e00941af2704c0ccaedc9ea734366d7ddf9a4814ee98d25592bf5f632d04c8f3d6e398b0b68e4a1
7
+ data.tar.gz: 1867b37cec854da010e00429704f02b179b5fd3cd32a6baf6e2b69ac0de827d094c74111ba42bb9463c8a151136319e933864419228d26ce30eb4279a0b962bf
data/NEWS CHANGED
@@ -1,6 +1,26 @@
1
1
  # Machinery Release Notes
2
2
 
3
3
 
4
+ ## Version 1.13.0 - Tue Sep 15 18:06:00 CEST 2015 - thardeck@suse.de
5
+
6
+ * Fix: Show `Files extracted` status in `compare --html` when both
7
+ status are the same (gh#SUSE/machinery#1218)
8
+ * Fix: Validate port option in the `show`, `compare`, and `serve`
9
+ commands (gh#SUSE/machinery#1316)
10
+ * Align output of `machinery config`
11
+ * Add rpc_pipefs to filtered filesystems (gh#SUSE/machinery#1250)
12
+ * Handle socket errors for `-i` option
13
+ * Add `containerize` command to the experimental features
14
+ * Export of autoyast files is now possible with system descriptions,
15
+ which have empty repository scopes (gh#SUSE/machinery#1268)
16
+ * Inspection of unmanaged-files is now also using the faster machinery-helper
17
+ when the files are extracted
18
+ * Introduce format version 5 which adds the "environment" scope (see
19
+ https://github.com/SUSE/machinery/blob/master/docs/System-Description-Format.md#version-5).
20
+ This scope is a hidden scope which is used internally by Machinery.
21
+ * Only print binary path if it's not first in PATH (gh#SUSE/machinery#1284)
22
+ * Do not exclude files with broken UTF-8 filenames anymore
23
+
4
24
  ## Version 1.12.0 - Fri Sep 04 16:51:10 CEST 2015 - cschum@suse.de
5
25
 
6
26
  * The x86_64 machinery-helper is now shipped with machinery. It speeds up
@@ -6,39 +6,56 @@ Machinery.
6
6
  The user is expected to be familiar with using Docker.
7
7
  Details on Docker can be found at https://www.docker.com/.
8
8
 
9
+ This is an experimental feature and for now we **require to run every command as
10
+ root**. If you encounter any issues please submit them to
11
+ https://github.com/SUSE/machinery/issues
12
+
9
13
  ## Requirements
10
14
 
11
15
  Docker and docker-compose are required. Packages are available in the Virtualization repository.
12
16
 
13
17
  Install on openSUSE 13.2:
14
18
 
15
- sudo zypper ar -f http://download.opensuse.org/repositories/Virtualization:/containers/openSUSE_13.2/ virt
16
- sudo zypper refresh
17
- sudo zypper in docker docker-compose
18
- sudo usermod -aG docker $(whoami)
19
- sudo systemctl start docker
19
+ zypper ar -f http://download.opensuse.org/repositories/Virtualization:/containers/openSUSE_13.2/ virt
20
+ zypper refresh
21
+ zypper in docker docker-compose
22
+ systemctl start docker
23
+
24
+ ## Set Up
25
+
26
+ When necessary, we've included a `setup.rb` script in your new containerized
27
+ application. This script uses the ruby client for the Docker Remote API so you
28
+ will need to install it as a gem.
20
29
 
21
- Log out and in again to refresh the user's group.
30
+ gem install docker-api
31
+
32
+ Once installed please make sure to run the setup script before running
33
+ `docker-compose up`.
34
+
35
+ ./setup.rb
22
36
 
23
37
  ## Managing Docker containers
24
38
 
25
- Run container:
39
+ Start the application:
26
40
 
27
41
  docker-compose up
28
42
 
29
- Run container as daemon in background:
43
+ _When started this way you can hit `ctrl-c` and the application will be
44
+ stopped.)_
45
+
46
+ Start the application as daemon in background:
30
47
 
31
48
  docker-compose up -d
32
49
 
33
- Shows list of all running containers:
50
+ Shows a list of all running containers:
34
51
 
35
52
  docker-compose ps
36
53
 
37
- Stop the container:
54
+ Stop the application:
38
55
 
39
56
  docker-compose kill
40
57
 
41
- Remove the container image:
58
+ Remove all containers:
42
59
 
43
60
  docker-compose rm -vf
44
61
 
@@ -269,7 +269,7 @@
269
269
 
270
270
  %script#scope_unmanaged_files_partial{:type => "text/ng-template"}
271
271
  %p
272
- <strong>Files extracted:</strong> {{object.extracted}}
272
+ <strong>Files extracted:</strong> {{object.extracted ? "yes" : "no"}}
273
273
  %table.table.table-striped.table-hover.table-condensed.files-table{{"ng-show" => "object.files"}}
274
274
  %thead
275
275
  %tr
@@ -457,7 +457,7 @@
457
457
 
458
458
  %script#scope_changed_managed_files_partial{:type => "text/ng-template"}
459
459
  %p
460
- <strong>Files extracted:</strong> {{object.extracted}}
460
+ <strong>Files extracted:</strong> {{object.extracted ? "yes" : "no"}}
461
461
  %table.table.table-striped.table-hover.table-condensed.files-table{{"ng-show" => "object.files"}}
462
462
  %thead
463
463
  %tr
@@ -524,7 +524,7 @@
524
524
 
525
525
  %script#scope_config_files_partial{:type => "text/ng-template"}
526
526
  %p
527
- <strong>Files extracted:</strong> {{object.extracted}}
527
+ <strong>Files extracted:</strong> {{object.extracted ? "yes" : "no"}}
528
528
  %table.table.table-striped.table-hover.table-condensed.files-table{{"ng-show" => "object.files"}}
529
529
  %thead
530
530
  %tr
data/lib/build_task.rb CHANGED
@@ -34,12 +34,14 @@ class BuildTask
34
34
  output_path, img_extension)
35
35
 
36
36
  begin
37
- LoggedCheetah.run_with_c(
38
- "sudo",
39
- tmp_script.path,
40
- stdout: $stdout,
41
- stderr: $stderr
42
- )
37
+ with_c_locale do
38
+ LoggedCheetah.run(
39
+ "sudo",
40
+ tmp_script.path,
41
+ stdout: $stdout,
42
+ stderr: $stderr
43
+ )
44
+ end
43
45
  rescue SignalException => e
44
46
  # Handle SIGHUP(1), SIGINT(2) and SIGTERM(15) gracefully
45
47
  if [1, 2, 15].include?(e.signo)
data/lib/cli.rb CHANGED
@@ -240,6 +240,18 @@ class Cli
240
240
  end
241
241
  end
242
242
 
243
+ def self.check_port_validity(port)
244
+ if port < 2 || port > 65535
245
+ raise Machinery::Errors::InvalidCommandLine.new("Please choose a port between 2 and " \
246
+ "65535.")
247
+ else
248
+ if port >= 2 && port <= 1023 && !CurrentUser.new.is_root?
249
+ raise Machinery::Errors::InvalidCommandLine.new("You need root rights when you want " \
250
+ "to use a port between 2 and 65535.")
251
+ end
252
+ end
253
+ end
254
+
243
255
  AVAILABLE_SCOPE_LIST = Machinery::Ui.internal_scope_list_to_string(
244
256
  Inspector.all_scopes
245
257
  )
@@ -254,7 +266,7 @@ class Cli
254
266
  the package for the modified config files
255
267
  LONGDESC
256
268
  arg "NAME"
257
- command :analyze do |c|
269
+ command "analyze" do |c|
258
270
  c.flag [:operation, :o], type: String, required: true,
259
271
  desc: "The analyze operation to perform", arg_name: "OPERATION"
260
272
 
@@ -288,7 +300,7 @@ class Cli
288
300
  #{buildable_distributions}
289
301
  LONGDESC
290
302
  arg "NAME"
291
- command :build do |c|
303
+ command "build" do |c|
292
304
  c.flag ["image-dir", :i], type: String, required: true,
293
305
  desc: "Store the image under the specified path", arg_name: "DIRECTORY"
294
306
  c.switch ["enable-dhcp", :d], required: false, negatable: false,
@@ -321,7 +333,7 @@ class Cli
321
333
  LONGDESC
322
334
  arg "NAME1"
323
335
  arg "NAME2"
324
- command :compare do |c|
336
+ command "compare" do |c|
325
337
  c.flag [:scope, :s], type: String, required: false,
326
338
  desc: "Compare specified scopes", arg_name: "SCOPE_LIST"
327
339
  c.flag ["exclude-scope", :e], type: String, required: false,
@@ -330,9 +342,13 @@ class Cli
330
342
  desc: "Show also common properties"
331
343
  if @config.experimental_features
332
344
  c.flag [:port, :p], type: Integer, required: false, default_value: @config.http_server_port,
333
- desc: "Listen on port PORT", arg_name: "PORT"
345
+ desc: "Listen on port PORT. Ports can be selected in a range between 2-65535. Ports between
346
+ 2 and 1023 can only be chosen when `machinery` will be executed as `root` user.",
347
+ arg_name: "PORT"
334
348
  c.flag [:ip, :i], type: String, required: false, default_value: "127.0.0.1",
335
- desc: "Listen on ip address IP", arg_name: "IP"
349
+ desc: "Listen on ip address IP. It's only possible to use an IP address (or hostnames
350
+ resolving to an IP address) which is assigned to a network interface on the local
351
+ machine.", arg_name: "IP"
336
352
  c.switch "html", required: false, negatable: false,
337
353
  desc: "Open comparison in HTML format in your web browser."
338
354
  end
@@ -344,6 +360,9 @@ class Cli
344
360
 
345
361
  name1 = shift_arg(args, "NAME1")
346
362
  name2 = shift_arg(args, "NAME2")
363
+
364
+ check_port_validity(options[:port]) if options[:html]
365
+
347
366
  store = system_description_store
348
367
  description1 = SystemDescription.load(name1, store)
349
368
  description2 = SystemDescription.load(name2, store)
@@ -370,7 +389,7 @@ class Cli
370
389
  LONGDESC
371
390
  arg "FROM_NAME"
372
391
  arg "TO_NAME"
373
- command :copy do |c|
392
+ command "copy" do |c|
374
393
  c.action do |global_options,options,args|
375
394
  from = shift_arg(args, "FROM_NAME")
376
395
  to = shift_arg(args, "TO_NAME")
@@ -388,7 +407,7 @@ class Cli
388
407
  specified an image will be built from the description before deployment.
389
408
  LONGDESC
390
409
  arg "NAME"
391
- command :deploy do |c|
410
+ command "deploy" do |c|
392
411
  c.flag ["cloud-config", :c], type: String, required: true, arg_name: "FILE",
393
412
  desc: "Path to file where the cloud config (openrc.sh) is located"
394
413
  c.flag ["image-dir", :i], type: String, required: false,
@@ -478,7 +497,7 @@ class Cli
478
497
  Available scopes: #{AVAILABLE_SCOPE_LIST}
479
498
  LONGDESC
480
499
  arg "HOSTNAME"
481
- command :inspect do |c|
500
+ command "inspect" do |c|
482
501
  supports_filtering(c)
483
502
  c.flag [:name, :n], type: String, required: false, arg_name: "NAME",
484
503
  desc: "Store system description under the specified name"
@@ -571,7 +590,7 @@ class Cli
571
590
  The date of modification for each scope can be shown with the verbose
572
591
  option.
573
592
  LONGDESC
574
- command :list do |c|
593
+ command "list" do |c|
575
594
  c.switch :verbose, required: false, negatable: false,
576
595
  desc: "Display additional information about origin of scopes"
577
596
  c.switch :short, required: false, negatable: false,
@@ -588,7 +607,7 @@ class Cli
588
607
  Shows the man page of the machinery tool.
589
608
 
590
609
  LONGDESC
591
- command :man do |c|
610
+ command "man" do |c|
592
611
  c.action do
593
612
  task = ManTask.new
594
613
  task.man
@@ -605,7 +624,7 @@ class Cli
605
624
  LONGDESC
606
625
  arg "NAME", [:multiple, :optional]
607
626
 
608
- command :remove do |c|
627
+ command "remove" do |c|
609
628
  c.switch :all, negatable: false,
610
629
  desc: "Remove all system descriptions"
611
630
  c.switch :verbose, required: false, negatable: false,
@@ -633,16 +652,20 @@ class Cli
633
652
  Available scopes: #{AVAILABLE_SCOPE_LIST}
634
653
  LONGDESC
635
654
  arg "NAME"
636
- command :show do |c|
655
+ command "show" do |c|
637
656
  supports_filtering(c)
638
657
  c.flag [:scope, :s], type: String, required: false,
639
658
  desc: "Show specified scopes", arg_name: "SCOPE_LIST"
640
659
  c.flag ["exclude-scope", :e], type: String, required: false,
641
660
  desc: "Exclude specified scopes", arg_name: "SCOPE_LIST"
642
661
  c.flag [:port, :p], type: Integer, required: false, default_value: @config.http_server_port,
643
- desc: "Listen on port PORT", arg_name: "PORT"
662
+ desc: "Listen on port PORT. Ports can be selected in a range between 2-65535. Ports between
663
+ 2 and 1023 can only be chosen when `machinery` will be executed as `root` user.",
664
+ arg_name: "PORT"
644
665
  c.flag [:ip, :i], type: String, required: false, default_value: "127.0.0.1",
645
- desc: "Listen on ip address IP", arg_name: "IP"
666
+ desc: "Listen on ip address IP. It's only possible to use an IP address (or hostnames
667
+ resolving to an IP address) which is assigned to a network interface on the local
668
+ machine.", arg_name: "IP"
646
669
  c.switch "pager", required: false, default_value: true,
647
670
  desc: "Pipe output into a pager"
648
671
  c.switch "show-diffs", required: false, negatable: false,
@@ -659,6 +682,9 @@ class Cli
659
682
  if name == "localhost" && !CurrentUser.new.is_root?
660
683
  Machinery::Ui.puts "You need root rights to access the system description of your locally inspected system."
661
684
  end
685
+
686
+ check_port_validity(options[:port]) if options[:html]
687
+
662
688
  description = SystemDescription.load(name, system_description_store)
663
689
  scope_list = process_scope_option(options[:scope], options["exclude-scope"])
664
690
 
@@ -695,7 +721,7 @@ class Cli
695
721
  Validate system description stored under the specified name.
696
722
  LONGDESC
697
723
  arg "NAME"
698
- command :validate do |c|
724
+ command "validate" do |c|
699
725
  c.action do |global_options,options,args|
700
726
  name = shift_arg(args, "NAME")
701
727
  if name == "localhost" && !CurrentUser.new.is_root?
@@ -774,19 +800,45 @@ class Cli
774
800
  command "serve" do |c|
775
801
  c.flag [:port, :p], type: Integer, required: false,
776
802
  default_value: Machinery::Config.new.http_server_port,
777
- desc: "Listen on port PORT", arg_name: "PORT"
803
+ desc: "Listen on port PORT. Ports can be selected in a range between 2-65535. Ports between
804
+ 2 and 1023 can only be chosen when `machinery` will be executed as `root` user.",
805
+ arg_name: "PORT"
778
806
  c.flag [:ip, :i], type: String, required: false, default_value: "127.0.0.1",
779
- desc: "Listen on ip IP", arg_name: "IP"
807
+ desc: "Listen on ip address IP. It's only possible to use an IP address (or hostnames
808
+ resolving to an IP address) which is assigned to a network interface on the local
809
+ machine.", arg_name: "IP"
780
810
 
781
811
  c.action do |_global_options, options, args|
782
812
  name = shift_arg(args, "NAME")
783
813
 
814
+ check_port_validity(options[:port])
815
+
784
816
  description = SystemDescription.load(name, system_description_store)
785
817
  task = ServeHtmlTask.new
786
818
  task.serve(description, options[:ip], options[:port])
787
819
  end
788
820
  end
789
821
 
822
+ if @config.experimental_features
823
+ desc "Containerize a system description"
824
+ long_desc <<-LONGDESC
825
+ Detects workloads from a system description and creates a recommendation for a corresponding
826
+ container setup
827
+ LONGDESC
828
+ arg "NAME"
829
+ command "containerize" do |c|
830
+ c.flag ["output-dir", :o], type: String, required: true,
831
+ desc: "Location where the container files will be stored", arg_name: "DIRECTORY"
832
+
833
+ c.action do |_global_options, options, args|
834
+ name = shift_arg(args, "NAME")
835
+ description = SystemDescription.load(name, system_description_store)
836
+ task = ContainerizeTask.new
837
+ task.containerize(description, File.expand_path(options["output-dir"]))
838
+ end
839
+ end
840
+ end
841
+
790
842
  def self.system_description_store
791
843
  if ENV.has_key?("MACHINERY_DIR")
792
844
  SystemDescriptionStore.new(ENV["MACHINERY_DIR"])
data/lib/compare_task.rb CHANGED
@@ -34,7 +34,7 @@ class CompareTask
34
34
 
35
35
  Machinery::Ui.use_pager = false
36
36
  Machinery::Ui.puts <<EOF
37
- There is a web server running, serving the comparison result on #{url}.
37
+ Trying to start a web server for serving the comparison result on #{url}.
38
38
 
39
39
  The server can be closed with Ctrl+C.
40
40
  EOF
data/lib/config_base.rb CHANGED
@@ -20,7 +20,7 @@
20
20
  # the file 'machinery_config.rb'.
21
21
 
22
22
  class ConfigBase
23
- attr_reader :file
23
+ attr_reader :file, :entries
24
24
 
25
25
  def initialize(file = default_config_file)
26
26
  @entries = {}
data/lib/config_task.rb CHANGED
@@ -23,8 +23,11 @@ class ConfigTask
23
23
  def config(key = nil, value_string = nil)
24
24
  if !key
25
25
  # show all config entries
26
+ max_length = @config.entries.keys.map(&:length).max
26
27
  @config.each do |key, value|
27
- Machinery::Ui.puts "#{key}=#{value[:value]} (#{value[:description]})"
28
+ Machinery::Ui.puts (
29
+ "%-#{max_length}s %s %s %s" % [key, "=", value[:value], "(#{value[:description]})"]
30
+ )
28
31
  end
29
32
  elsif !value_string
30
33
  # show one specific config entry
@@ -26,9 +26,10 @@ class ContainerizeTask
26
26
  Machinery::Ui.puts "No workloads detected."
27
27
  else
28
28
  FileUtils.mkdir_p(output_path)
29
- mapper.save(workloads, output_path)
29
+ services = mapper.save(workloads, output_path)
30
30
  mapper.extract(description, workloads, output_path)
31
31
  write_readme_file(output_path)
32
+ copy_workload_setup_files(description, workloads, services, output_path)
32
33
 
33
34
  workloads.each do |workload|
34
35
  Machinery::Ui.puts "Detected workload '#{workload[0]}'."
@@ -43,4 +44,17 @@ class ContainerizeTask
43
44
  File.join(dir, "README.md")
44
45
  )
45
46
  end
47
+
48
+ private
49
+
50
+ def copy_workload_setup_files(description, workloads, services, path)
51
+ app = ContainerizedApp.new(description.name, workloads, services)
52
+ workloads.each do |workload, _|
53
+ Dir[File.join(Machinery::ROOT, "workload_mapper", workload, "setup", "*.erb")].each do |file|
54
+ setup_script = ERB.new(File.read(file))
55
+ File.write(File.join(path, File.basename(file, ".*")), setup_script.result(app.get_binding))
56
+ FileUtils.chmod "+x", File.join(path, File.basename(file, ".*"))
57
+ end
58
+ end
59
+ end
46
60
  end
@@ -0,0 +1,27 @@
1
+ # Copyright (c) 2013-2015 SUSE LLC
2
+ #
3
+ # This program is free software; you can redistribute it and/or
4
+ # modify it under the terms of version 3 of the GNU General Public License as
5
+ # published by the Free Software Foundation.
6
+ #
7
+ # This program is distributed in the hope that it will be useful,
8
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
+ # GNU General Public License for more details.
11
+ #
12
+ # You should have received a copy of the GNU General Public License
13
+ # along with this program; if not, contact SUSE LLC.
14
+ #
15
+ # To contact SUSE about this file by physical or electronic mail,
16
+ # you may find current contact information at www.suse.com
17
+ class ContainerizedApp
18
+ def initialize(name, workloads, services)
19
+ @name = name
20
+ @services = services
21
+ @workloads = workloads
22
+ end
23
+
24
+ def get_binding
25
+ binding
26
+ end
27
+ end