machinery-tool 1.12.0 → 1.13.0

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.
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