oneds-mrproper 0.1.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 (38) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +18 -0
  5. data/.travis.yml +9 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +13 -0
  9. data/README.md +79 -0
  10. data/Rakefile +17 -0
  11. data/bin/oneds-mrproper +4 -0
  12. data/lib/oneds/mrproper.rb +14 -0
  13. data/lib/oneds/mrproper/cleaners.rb +11 -0
  14. data/lib/oneds/mrproper/cleaners/cleaner.rb +13 -0
  15. data/lib/oneds/mrproper/cleaners/directory_cleaner.rb +48 -0
  16. data/lib/oneds/mrproper/cleaners/image_cleaner.rb +56 -0
  17. data/lib/oneds/mrproper/cleaners/system_cleaner.rb +49 -0
  18. data/lib/oneds/mrproper/cli.rb +66 -0
  19. data/lib/oneds/mrproper/errors.rb +9 -0
  20. data/lib/oneds/mrproper/errors/one.rb +14 -0
  21. data/lib/oneds/mrproper/errors/one/authentication_error.rb +10 -0
  22. data/lib/oneds/mrproper/errors/one/resource_not_found_error.rb +10 -0
  23. data/lib/oneds/mrproper/errors/one/resource_retrieval_error.rb +10 -0
  24. data/lib/oneds/mrproper/errors/one/resource_state_error.rb +10 -0
  25. data/lib/oneds/mrproper/errors/one/stub_error.rb +10 -0
  26. data/lib/oneds/mrproper/errors/one/user_not_authorized_error.rb +10 -0
  27. data/lib/oneds/mrproper/errors/opennebula_error.rb +8 -0
  28. data/lib/oneds/mrproper/errors/standard_error.rb +8 -0
  29. data/lib/oneds/mrproper/one.rb +8 -0
  30. data/lib/oneds/mrproper/one/helper.rb +33 -0
  31. data/lib/oneds/mrproper/one/managers.rb +12 -0
  32. data/lib/oneds/mrproper/one/managers/datastore_manager.rb +32 -0
  33. data/lib/oneds/mrproper/one/managers/image_manager.rb +23 -0
  34. data/lib/oneds/mrproper/one/managers/manager.rb +26 -0
  35. data/lib/oneds/mrproper/one/managers/virtual_machine_manager.rb +28 -0
  36. data/lib/oneds/mrproper/version.rb +5 -0
  37. data/oneds-mrproper.gemspec +34 -0
  38. metadata +221 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NDgwZDhkYmZiZDZhMGM5YmMyMjRlYWEzNzY4MWFjOTA4NmQ3MzA1Yw==
5
+ data.tar.gz: !binary |-
6
+ MjJlOTE2Yjg0Y2VhNDI0NGM0ZmZkNGM1ZTg2NGRlMTRjNmY0OTlkZg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ NjQ2ZTFhOTA1OTJjMmZmMzFiMDFkMDE2ZTMyNWIxZWQzYjI1ZjZmZDViNjk4
10
+ ODE0ZTJkOWRhODk3NGFhZTEyNTljNzVhYzY5NTA4YWViODdlOWY1MzNjMDc1
11
+ YWIyODg5NzA5YjZlOTYwZjFiNjRlMmJlN2QyZmI3ZWZjMjEyMDI=
12
+ data.tar.gz: !binary |-
13
+ ZTVjZGQxNDViNDY4OTZjZmEzZTQ2ODRhYjkwNDg2ZTU5YWZjOGU0NTA3Nzdm
14
+ MGM1NDcxYjYwNGM1YjNjYzRkZTFhODkyNzAyMWNkMTZjNDg2ZjVmNzE2N2Yz
15
+ MDlkMTdlODhiYmQ4YjliNzYwNjQyM2QxZjUyMTk4ZmY4MWY0ZjY=
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ example
11
+ /vendor/
12
+ /coverage/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.rubocop.yml ADDED
@@ -0,0 +1,18 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.0
3
+
4
+ Metrics/LineLength:
5
+ Max: 135
6
+
7
+ Style/Documentation:
8
+ Enabled: false
9
+
10
+ Metrics/MethodLength:
11
+ Max: 15
12
+
13
+ Metrics/BlockLength:
14
+ Exclude:
15
+ - 'Rakefile'
16
+ - '**/*.rake'
17
+ - 'spec/**/*.rb'
18
+ - '*.gemspec'
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 1.9
5
+ - 2.0
6
+ - 2.1
7
+ - 2.2
8
+ - 2.3.3
9
+ before_install: gem install bundler -v 1.13.7
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at kimle.michal@gmail.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in oneds-mrproper.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2016 Michal Kimle
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # oneds-mrproper
2
+
3
+ Cleaning utility for OpenNebula datastores.
4
+
5
+ Cleans forgotten images of image datastores, directories of system datastores and empty unused datastore directories.
6
+
7
+ [![Gem Version](https://fury-badge.herokuapp.com/rb/oneds-mrproper.png)](https://badge.fury.io/rb/oneds-mrproper)
8
+
9
+ ##Requirements
10
+ * Ruby >= 1.9.3
11
+
12
+ ###OpenNebula backend
13
+ * [OpenNebula](http://opennebula.org/) >= 5.2 (doesn't have to be present on the same machine)
14
+
15
+ ## Installation
16
+ ###From RubyGems.org
17
+ To install the most recent stable version
18
+ ```bash
19
+ gem install oneds-mrproper
20
+ ```
21
+
22
+ ###From source (dev)
23
+ **Installation from source should never be your first choice! Especially, if you are not
24
+ familiar with RVM, Bundler, Rake and other dev tools for Ruby!**
25
+
26
+ **However, if you wish to contribute to our project, this is the right way to start.**
27
+
28
+ To build and install the bleeding edge version from master
29
+
30
+ ```bash
31
+ git clone git://github.com/Misenko/oneds-mrproper.git
32
+ cd oneds-mrproper
33
+ gem install bundler
34
+ bundle install
35
+ ```
36
+
37
+ ##Usage
38
+ oneds-mrproper is run with executable `oneds-mrproper`. For further assistance run `oneds-mrproper help`:
39
+ ```bash
40
+ $ oneds-mrproper help
41
+
42
+ Commands:
43
+ oneds-mrproper clean # Cleaning datastores
44
+ oneds-mrproper help [COMMAND] # Describe available commands or one specific command
45
+
46
+ Options:
47
+ [--dry-run], [--no-dry-run] # Runs oneds-mrproper without modifying anything
48
+ [--debug], [--no-debug] # Runs oneds-mrproper in debug mode
49
+ [--info], [--no-info] # Runs oneds-mrproper in info mode
50
+ ```
51
+ oneds-mrproper cleaning is started with `clean` command (command is default and can be omitted)
52
+ ```bash
53
+ $ oneds-mrproper help clean
54
+
55
+ Usage:
56
+ oneds-mrproper clean
57
+
58
+ Options:
59
+ [--system], [--no-system] # Clean also system datastores
60
+ # Default: true
61
+ [--image], [--no-image] # Clean also image datastores
62
+ # Default: true
63
+ [--directory], [--no-directory] # Clean also forgotten datastore directories
64
+ # Default: true
65
+ [--one-endpoint=ONE-ENDPOINT] # OpenNebula endpoint
66
+ [--one-secret=ONE-SECRET] # OpenNebula endpoint
67
+ [--dry-run], [--no-dry-run] # Runs oneds-mrproper without modifying anything
68
+ [--debug], [--no-debug] # Runs oneds-mrproper in debug mode
69
+ [--info], [--no-info] # Runs oneds-mrproper in info mode
70
+
71
+ Cleaning datastores
72
+ ```
73
+
74
+ ## Contributing
75
+ 1. Fork it ( https://github.com/Misenko/oneds-mrproper/fork )
76
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
77
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
78
+ 4. Push to the branch (`git push origin my-new-feature`)
79
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require 'rspec/core/rake_task'
2
+ require 'rubocop/rake_task'
3
+ require 'bundler/gem_tasks'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ RuboCop::RakeTask.new
7
+
8
+ task default: :spec
9
+
10
+ desc 'Run acceptance tests (RSpec + Rubocop)'
11
+ task test: 'acceptance'
12
+
13
+ desc 'Run acceptance tests (RSpec + Rubocop)'
14
+ task :acceptance do |_t|
15
+ Rake::Task['spec'].invoke
16
+ Rake::Task['rubocop'].invoke
17
+ end
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'oneds/mrproper'
3
+
4
+ Oneds::Mrproper::CLI.start(ARGV)
@@ -0,0 +1,14 @@
1
+ require 'active_support/all'
2
+ require 'opennebula'
3
+ require 'pry'
4
+ require 'fileutils'
5
+
6
+ module Oneds
7
+ module Mrproper
8
+ autoload :Version, 'oneds/mrproper/version'
9
+ autoload :Errors, 'oneds/mrproper/errors'
10
+ autoload :CLI, 'oneds/mrproper/cli'
11
+ autoload :Cleaners, 'oneds/mrproper/cleaners'
12
+ autoload :One, 'oneds/mrproper/one'
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+
2
+ module Oneds
3
+ module Mrproper
4
+ module Cleaners
5
+ autoload :Cleaner, 'oneds/mrproper/cleaners/cleaner'
6
+ autoload :SystemCleaner, 'oneds/mrproper/cleaners/system_cleaner'
7
+ autoload :ImageCleaner, 'oneds/mrproper/cleaners/image_cleaner'
8
+ autoload :DirectoryCleaner, 'oneds/mrproper/cleaners/directory_cleaner'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module Cleaners
4
+ class Cleaner
5
+ attr_reader :dry_run
6
+
7
+ def initialize(dry_run = false)
8
+ @dry_run = dry_run
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,48 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module Cleaners
4
+ class DirectoryCleaner < Oneds::Mrproper::Cleaners::Cleaner
5
+ attr_reader :datastore_manager
6
+
7
+ def initialize(client, dry_run)
8
+ super(dry_run)
9
+
10
+ @datastore_manager = Oneds::Mrproper::One::Managers::DatastoreManager.new client
11
+ end
12
+
13
+ def clean
14
+ logger.info 'Cleaning forgotten datastore directories'
15
+ datastores = datastore_manager.datastore_paths.sort
16
+ base_path = File.dirname(datastores.first)
17
+ logger.debug "Datasores registered in OpenNebula: #{datastores.inspect}"
18
+ directories = Dir[File.join(base_path, '*')].sort
19
+ logger.debug "Directories present on filesystem: #{directories.inspect}"
20
+
21
+ dirs_to_remove = directories - datastores
22
+ logger.debug "Directories that will be removed: #{dirs_to_remove.inspect}"
23
+
24
+ remove_directories dirs_to_remove
25
+ end
26
+
27
+ private
28
+
29
+ def remove_directories(directories)
30
+ directories.each do |dir|
31
+ unless File.directory? dir
32
+ logger.warn "Skipping file #{dir.inspect}, not a directory"
33
+ next
34
+ end
35
+
36
+ unless Dir[File.join(dir, '*')].empty?
37
+ logger.warn "Skipping not empty directory #{dir.inspect} which is not registered in OpenNebula"
38
+ next
39
+ end
40
+
41
+ logger.info "Removing empty directory #{dir.inspect}"
42
+ FileUtils.rm_r dir unless dry_run
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,56 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module Cleaners
4
+ class ImageCleaner < Oneds::Mrproper::Cleaners::Cleaner
5
+ attr_reader :datastore_manager, :image_manager
6
+
7
+ def initialize(client, dry_run)
8
+ super(dry_run)
9
+
10
+ @datastore_manager = Oneds::Mrproper::One::Managers::DatastoreManager.new client
11
+ @image_manager = Oneds::Mrproper::One::Managers::ImageManager.new client
12
+ end
13
+
14
+ def clean
15
+ logger.info 'Cleaning image datastores'
16
+ datastores = datastore_manager.image_datastores
17
+ datastores.each { |datastore| clean_datastore datastore }
18
+ end
19
+
20
+ def clean_datastore(datastore)
21
+ ds_path = datastore['BASE_PATH']
22
+ logger.info "Cleaning datastore #{datastore.name.inspect} with path #{ds_path.inspect}"
23
+
24
+ unless File.exist? ds_path
25
+ logger.warn "Path #{ds_path.inspect} not found on headnode, skipping"
26
+ return
27
+ end
28
+
29
+ fs_files = Dir[File.join(ds_path, '*')].reject { |name| name =~ /^.*\.snap$/ }.sort
30
+ logger.debug "Files available on filesystem: #{fs_files.inspect}"
31
+ ds_files = datastore.img_ids.map { |id| image_manager.image_file id }.compact.sort
32
+ logger.debug "Files registered in OpenNebula: #{ds_files.inspect}"
33
+
34
+ files_to_remove = fs_files - ds_files
35
+ logger.debug "Files that will be removed: #{files_to_remove.inspect}"
36
+
37
+ remove_files files_to_remove
38
+ end
39
+
40
+ private
41
+
42
+ def remove_files(files)
43
+ files.each do |file|
44
+ logger.info "Removing file #{file.inspect}"
45
+ File.delete file unless dry_run
46
+ snap_dir = "#{file}.snap"
47
+ if File.exist? snap_dir
48
+ logger.info "Removing snapshot directory #{snap_dir.inspect}"
49
+ FileUtils.rm_r snap_dir unless dry_run
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,49 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module Cleaners
4
+ class SystemCleaner < Oneds::Mrproper::Cleaners::Cleaner
5
+ attr_reader :datastore_manager, :vm_manager
6
+
7
+ def initialize(client, dry_run)
8
+ super(dry_run)
9
+
10
+ @datastore_manager = Oneds::Mrproper::One::Managers::DatastoreManager.new client
11
+ @vm_manager = Oneds::Mrproper::One::Managers::VirtualMachineManager.new client
12
+ end
13
+
14
+ def clean
15
+ logger.info 'Cleaning system datastores'
16
+ datastores = datastore_manager.system_datastores
17
+ datastores.each { |datastore| clean_datastore datastore }
18
+ end
19
+
20
+ def clean_datastore(datastore)
21
+ ds_path = datastore['BASE_PATH']
22
+ logger.info "Cleaning datastore #{datastore.name.inspect} with path #{ds_path.inspect}"
23
+
24
+ unless File.exist? ds_path
25
+ logger.warn "Path #{ds_path.inspect} not found on headnode, skipping"
26
+ return
27
+ end
28
+
29
+ fs_vm_ids = Dir.entries(ds_path).select { |dir| dir =~ /^[0-9]*$/ }.sort
30
+ logger.debug "Directories available on filesystem: #{fs_vm_ids.inspect}"
31
+
32
+ remove_vm_directories fs_vm_ids, ds_path
33
+ end
34
+
35
+ private
36
+
37
+ def remove_vm_directories(directories, ds_path)
38
+ directories.each do |vm_id|
39
+ vm = vm_manager.virtual_machine(vm_id)
40
+ if vm && vm_manager.done?(vm)
41
+ logger.info "Removing virtual machine directory with id #{vm.id.inspect}"
42
+ FileUtils.rm_r File.join(ds_path, vm_id) unless dry_run
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,66 @@
1
+ require 'thor'
2
+ require 'yell'
3
+
4
+ module Oneds
5
+ module Mrproper
6
+ class CLI < Thor
7
+ class_option :'dry-run',
8
+ default: false,
9
+ type: :boolean,
10
+ desc: 'Runs oneds-mrproper without modifying anything'
11
+ class_option :debug,
12
+ default: false,
13
+ type: :boolean,
14
+ desc: 'Runs oneds-mrproper in debug mode'
15
+ class_option :info,
16
+ default: false,
17
+ type: :boolean,
18
+ desc: 'Runs oneds-mrproper in info mode'
19
+
20
+ method_option :system,
21
+ default: true,
22
+ type: :boolean,
23
+ desc: 'Clean also system datastores'
24
+ method_option :image,
25
+ default: true,
26
+ type: :boolean,
27
+ desc: 'Clean also image datastores'
28
+ method_option :directory,
29
+ default: true,
30
+ type: :boolean,
31
+ desc: 'Clean also forgotten datastore directories'
32
+ method_option :'one-endpoint',
33
+ default: nil,
34
+ type: :string,
35
+ desc: 'OpenNebula endpoint'
36
+ method_option :'one-secret',
37
+ default: nil,
38
+ type: :string,
39
+ desc: 'OpenNebula endpoint'
40
+
41
+ desc 'clean', 'Cleaning datastores'
42
+ def clean
43
+ initialize_logger(options)
44
+ client = Oneds::Mrproper::One::Helper.client options[:'one-secret'], options[:'one-endpoint']
45
+ Oneds::Mrproper::Cleaners::SystemCleaner.new(client, options[:'dry-run']).clean if options[:system]
46
+ Oneds::Mrproper::Cleaners::ImageCleaner.new(client, options[:'dry-run']).clean if options[:image]
47
+ Oneds::Mrproper::Cleaners::DirectoryCleaner.new(client, options[:'dry-run']).clean if options[:directory]
48
+ end
49
+
50
+ default_task :clean
51
+
52
+ private
53
+
54
+ def initialize_logger(options)
55
+ level = 'ERROR'
56
+ level = 'INFO' if options[:info] || options[:'dry-run']
57
+ level = 'DEBUG' if options[:debug]
58
+
59
+ Yell.new :stdout, name: Object, level: level.downcase, format: Yell::DefaultFormat
60
+ Object.send :include, Yell::Loggable
61
+
62
+ logger.info 'DRY RUN ENABLED' if options[:'dry-run']
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,9 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module Errors
4
+ autoload :StandardError, 'oneds/mrproper/errors/standard_error'
5
+ autoload :OpennebulaError, 'oneds/mrproper/errors/opennebula_error'
6
+ autoload :One, 'oneds/mrproper/errors/one'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,14 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module Errors
4
+ module One
5
+ autoload :StubError, 'oneds/mrproper/errors/one/stub_error'
6
+ autoload :AuthenticationError, 'oneds/mrproper/errors/one/authentication_error'
7
+ autoload :ResourceNotFoundError, 'oneds/mrproper/errors/one/resource_not_found_error'
8
+ autoload :ResourceRetrievalError, 'oneds/mrproper/errors/one/resource_retrieval_error'
9
+ autoload :ResourceStateError, 'oneds/mrproper/errors/one/resource_state_error'
10
+ autoload :UserNotAuthorizedError, 'oneds/mrproper/errors/one/user_not_authorized_error'
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module Errors
4
+ module One
5
+ class AuthenticationError < Oneds::Mrproper::Errors::OpennebulaError
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module Errors
4
+ module One
5
+ class ResourceNotFoundError < Oneds::Mrproper::Errors::OpennebulaError
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module Errors
4
+ module One
5
+ class ResourceRetrievalError < Oneds::Mrproper::Errors::OpennebulaError
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module Errors
4
+ module One
5
+ class ResourceStateError < Oneds::Mrproper::Errors::OpennebulaError
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module Errors
4
+ module One
5
+ class StubError < Oneds::Mrproper::Errors::OpennebulaError
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module Errors
4
+ module One
5
+ class UserNotAuthorizedError < Oneds::Mrproper::Errors::OpennebulaError
6
+ end
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module Errors
4
+ class OpennebulaError < Oneds::Mrproper::Errors::StandardError
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module Errors
4
+ class StandardError < ::StandardError
5
+ end
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module One
4
+ autoload :Helper, 'oneds/mrproper/one/helper'
5
+ autoload :Managers, 'oneds/mrproper/one/managers'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,33 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module One
4
+ class Helper
5
+ class << self
6
+ def client(secret = nil, endpoint = nil)
7
+ OpenNebula::Client.new(secret, endpoint)
8
+ end
9
+
10
+ def handle_opennebula_error
11
+ raise Oneds::Mrproper::Errors::One::StubError, 'OpenNebula service-wrapper was called without a block!' unless block_given?
12
+
13
+ return_value = yield
14
+ return return_value unless OpenNebula.is_error?(return_value)
15
+
16
+ case return_value.errno
17
+ when OpenNebula::Error::EAUTHENTICATION
18
+ raise Oneds::Mrproper::Errors::One::AuthenticationError, return_value.message
19
+ when OpenNebula::Error::EAUTHORIZATION
20
+ raise Oneds::Mrproper::Errors::One::UserNotAuthorizedError, return_value.message
21
+ when OpenNebula::Error::ENO_EXISTS
22
+ raise Oneds::Mrproper::Errors::One::ResourceNotFoundError, return_value.message
23
+ when OpenNebula::Error::EACTION
24
+ raise Oneds::Mrproper::Errors::One::ResourceStateError, return_value.message
25
+ else
26
+ raise Oneds::Mrproper::Errors::One::ResourceRetrievalError, return_value.message
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,12 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module One
4
+ module Managers
5
+ autoload :Manager, 'oneds/mrproper/one/managers/manager'
6
+ autoload :DatastoreManager, 'oneds/mrproper/one/managers/datastore_manager'
7
+ autoload :VirtualMachineManager, 'oneds/mrproper/one/managers/virtual_machine_manager'
8
+ autoload :ImageManager, 'oneds/mrproper/one/managers/image_manager'
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,32 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module One
4
+ module Managers
5
+ class DatastoreManager < Oneds::Mrproper::One::Managers::Manager
6
+ def initialize(client)
7
+ super(client)
8
+ @pool = OpenNebula::DatastorePool.new client
9
+ end
10
+
11
+ def datastore_paths
12
+ reload!
13
+
14
+ pool.map { |datastore| datastore['BASE_PATH'] }
15
+ end
16
+
17
+ def image_datastores
18
+ reload!
19
+
20
+ pool.find_all { |datastore| datastore.type_str == 'IMAGE' }
21
+ end
22
+
23
+ def system_datastores
24
+ reload!
25
+
26
+ pool.find_all { |datastore| datastore.type_str == 'SYSTEM' }
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,23 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module One
4
+ module Managers
5
+ class ImageManager < Oneds::Mrproper::One::Managers::Manager
6
+ def initialize(client)
7
+ super(client)
8
+ @pool = OpenNebula::ImagePool.new client
9
+ end
10
+
11
+ def image_file(image_id)
12
+ image = OpenNebula::Image.new(OpenNebula::Image.build_xml(image_id.to_i), client)
13
+ Oneds::Mrproper::One::Helper.handle_opennebula_error { image.info }
14
+
15
+ image['SOURCE']
16
+ rescue Oneds::Mrproper::Errors::One::ResourceNotFoundError => ex
17
+ logger.error "Image not found: #{ex.message}"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module One
4
+ module Managers
5
+ class Manager
6
+ attr_reader :client, :pool
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ def reload!
13
+ return unless pool
14
+
15
+ if pool.respond_to?('info_all!')
16
+ Oneds::Mrproper::One::Helper.handle_opennebula_error { pool.info_all! }
17
+ return
18
+ end
19
+
20
+ Oneds::Mrproper::One::Helper.handle_opennebula_error { pool.info! }
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ module Oneds
2
+ module Mrproper
3
+ module One
4
+ module Managers
5
+ class VirtualMachineManager < Oneds::Mrproper::One::Managers::Manager
6
+ VM_DONE_STATE = 6
7
+
8
+ def initialize(client)
9
+ super(client)
10
+ end
11
+
12
+ def virtual_machine(vm_id)
13
+ vm = OpenNebula::VirtualMachine.new(OpenNebula::VirtualMachine.build_xml(vm_id), client)
14
+ Oneds::Mrproper::One::Helper.handle_opennebula_error { vm.info }
15
+
16
+ vm
17
+ rescue Oneds::Mrproper::Errors::One::ResourceNotFoundError => ex
18
+ logger.error "Virtual Machine not found: #{ex.message}"
19
+ end
20
+
21
+ def done?(vm)
22
+ vm.state == VM_DONE_STATE
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ module Oneds
2
+ module Mrproper
3
+ VERSION = '0.1.0'.freeze
4
+ end
5
+ end
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'oneds/mrproper/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'oneds-mrproper'
8
+ spec.version = Oneds::Mrproper::VERSION
9
+ spec.authors = ['Michal Kimle']
10
+ spec.email = ['kimle.michal@gmail.com']
11
+
12
+ spec.summary = 'Cleaning utility for OpenNebula datastores'
13
+ spec.description = 'Cleaning utility for OpenNebula datastores'
14
+ spec.homepage = 'https://github.com/Misenko/oneds-mrproper'
15
+ spec.license = 'Apache License, Version 2.0'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.13'
22
+ spec.add_development_dependency 'rake', '~> 11.2'
23
+ spec.add_development_dependency 'rspec', '~> 3.5'
24
+ spec.add_development_dependency 'rubocop', '~> 0.41.0'
25
+ spec.add_development_dependency 'pry', '~> 0.10'
26
+
27
+ spec.add_runtime_dependency 'thor', '~> 0.19'
28
+ spec.add_runtime_dependency 'yell', '~> 2.0'
29
+ spec.add_runtime_dependency 'activesupport', '~> 4.0'
30
+ spec.add_runtime_dependency 'opennebula', '~> 5.2'
31
+ spec.add_runtime_dependency 'nokogiri', '~> 1.6.8'
32
+
33
+ spec.required_ruby_version = '>= 1.9.3'
34
+ end
metadata ADDED
@@ -0,0 +1,221 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oneds-mrproper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Michal Kimle
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.13'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '11.2'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '11.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '3.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '3.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.41.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: 0.41.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '0.10'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '0.10'
83
+ - !ruby/object:Gem::Dependency
84
+ name: thor
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '0.19'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '0.19'
97
+ - !ruby/object:Gem::Dependency
98
+ name: yell
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: '2.0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: '2.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: activesupport
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '4.0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ~>
123
+ - !ruby/object:Gem::Version
124
+ version: '4.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: opennebula
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ~>
130
+ - !ruby/object:Gem::Version
131
+ version: '5.2'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ~>
137
+ - !ruby/object:Gem::Version
138
+ version: '5.2'
139
+ - !ruby/object:Gem::Dependency
140
+ name: nokogiri
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ~>
144
+ - !ruby/object:Gem::Version
145
+ version: 1.6.8
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ~>
151
+ - !ruby/object:Gem::Version
152
+ version: 1.6.8
153
+ description: Cleaning utility for OpenNebula datastores
154
+ email:
155
+ - kimle.michal@gmail.com
156
+ executables:
157
+ - oneds-mrproper
158
+ extensions: []
159
+ extra_rdoc_files: []
160
+ files:
161
+ - .gitignore
162
+ - .rspec
163
+ - .rubocop.yml
164
+ - .travis.yml
165
+ - CODE_OF_CONDUCT.md
166
+ - Gemfile
167
+ - LICENSE.txt
168
+ - README.md
169
+ - Rakefile
170
+ - bin/oneds-mrproper
171
+ - lib/oneds/mrproper.rb
172
+ - lib/oneds/mrproper/cleaners.rb
173
+ - lib/oneds/mrproper/cleaners/cleaner.rb
174
+ - lib/oneds/mrproper/cleaners/directory_cleaner.rb
175
+ - lib/oneds/mrproper/cleaners/image_cleaner.rb
176
+ - lib/oneds/mrproper/cleaners/system_cleaner.rb
177
+ - lib/oneds/mrproper/cli.rb
178
+ - lib/oneds/mrproper/errors.rb
179
+ - lib/oneds/mrproper/errors/one.rb
180
+ - lib/oneds/mrproper/errors/one/authentication_error.rb
181
+ - lib/oneds/mrproper/errors/one/resource_not_found_error.rb
182
+ - lib/oneds/mrproper/errors/one/resource_retrieval_error.rb
183
+ - lib/oneds/mrproper/errors/one/resource_state_error.rb
184
+ - lib/oneds/mrproper/errors/one/stub_error.rb
185
+ - lib/oneds/mrproper/errors/one/user_not_authorized_error.rb
186
+ - lib/oneds/mrproper/errors/opennebula_error.rb
187
+ - lib/oneds/mrproper/errors/standard_error.rb
188
+ - lib/oneds/mrproper/one.rb
189
+ - lib/oneds/mrproper/one/helper.rb
190
+ - lib/oneds/mrproper/one/managers.rb
191
+ - lib/oneds/mrproper/one/managers/datastore_manager.rb
192
+ - lib/oneds/mrproper/one/managers/image_manager.rb
193
+ - lib/oneds/mrproper/one/managers/manager.rb
194
+ - lib/oneds/mrproper/one/managers/virtual_machine_manager.rb
195
+ - lib/oneds/mrproper/version.rb
196
+ - oneds-mrproper.gemspec
197
+ homepage: https://github.com/Misenko/oneds-mrproper
198
+ licenses:
199
+ - Apache License, Version 2.0
200
+ metadata: {}
201
+ post_install_message:
202
+ rdoc_options: []
203
+ require_paths:
204
+ - lib
205
+ required_ruby_version: !ruby/object:Gem::Requirement
206
+ requirements:
207
+ - - ! '>='
208
+ - !ruby/object:Gem::Version
209
+ version: 1.9.3
210
+ required_rubygems_version: !ruby/object:Gem::Requirement
211
+ requirements:
212
+ - - ! '>='
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ requirements: []
216
+ rubyforge_project:
217
+ rubygems_version: 2.6.8
218
+ signing_key:
219
+ specification_version: 4
220
+ summary: Cleaning utility for OpenNebula datastores
221
+ test_files: []