vagrant-unbundled 2.2.6.2 → 2.2.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.hashibot.hcl +12 -0
  3. data/CHANGELOG.md +37 -2
  4. data/contrib/bash/completion.sh +13 -1
  5. data/lib/vagrant/action.rb +1 -0
  6. data/lib/vagrant/action/builtin/box_add.rb +9 -3
  7. data/lib/vagrant/action/builtin/box_check_outdated.rb +12 -15
  8. data/lib/vagrant/action/builtin/disk.rb +39 -0
  9. data/lib/vagrant/action/builtin/mixin_provisioners.rb +19 -1
  10. data/lib/vagrant/action/builtin/ssh_run.rb +21 -3
  11. data/lib/vagrant/action/warden.rb +9 -0
  12. data/lib/vagrant/box_metadata.rb +17 -3
  13. data/lib/vagrant/errors.rb +4 -0
  14. data/lib/vagrant/ui.rb +8 -3
  15. data/lib/vagrant/util/file_checksum.rb +6 -2
  16. data/lib/vagrant/util/is_port_open.rb +1 -2
  17. data/lib/vagrant/util/numeric.rb +61 -0
  18. data/plugins/commands/box/command/outdated.rb +14 -2
  19. data/plugins/commands/cloud/publish.rb +1 -1
  20. data/plugins/commands/snapshot/command/save.rb +13 -8
  21. data/plugins/guests/alpine/cap/rsync.rb +1 -1
  22. data/plugins/guests/alpine/plugin.rb +16 -0
  23. data/plugins/guests/darwin/cap/mount_vmware_shared_folder.rb +86 -13
  24. data/plugins/guests/linux/cap/reboot.rb +42 -0
  25. data/plugins/guests/linux/plugin.rb +10 -0
  26. data/plugins/guests/redhat/cap/nfs_client.rb +2 -2
  27. data/plugins/guests/suse/cap/change_host_name.rb +2 -2
  28. data/plugins/hosts/darwin/cap/nfs.rb +11 -0
  29. data/plugins/hosts/darwin/plugin.rb +5 -0
  30. data/plugins/hosts/linux/cap/nfs.rb +20 -2
  31. data/plugins/kernel_v2/config/disk.rb +168 -0
  32. data/plugins/kernel_v2/config/vm.rb +82 -1
  33. data/plugins/kernel_v2/config/vm_provisioner.rb +4 -1
  34. data/plugins/providers/docker/driver.rb +22 -10
  35. data/plugins/providers/docker/errors.rb +4 -0
  36. data/plugins/providers/docker/executor/local.rb +7 -1
  37. data/plugins/providers/virtualbox/action.rb +1 -0
  38. data/plugins/providers/virtualbox/action/clean_machine_folder.rb +10 -1
  39. data/plugins/providers/virtualbox/driver/meta.rb +1 -0
  40. data/plugins/providers/virtualbox/driver/version_6_1.rb +16 -0
  41. data/plugins/providers/virtualbox/plugin.rb +1 -0
  42. data/plugins/provisioners/ansible/cap/guest/arch/ansible_install.rb +20 -3
  43. data/plugins/provisioners/ansible/cap/guest/debian/ansible_install.rb +4 -5
  44. data/plugins/provisioners/ansible/cap/guest/fedora/ansible_install.rb +2 -2
  45. data/plugins/provisioners/ansible/cap/guest/freebsd/ansible_install.rb +2 -2
  46. data/plugins/provisioners/ansible/cap/guest/pip/pip.rb +8 -4
  47. data/plugins/provisioners/ansible/cap/guest/redhat/ansible_install.rb +2 -2
  48. data/plugins/provisioners/ansible/cap/guest/suse/ansible_install.rb +2 -1
  49. data/plugins/provisioners/ansible/cap/guest/ubuntu/ansible_install.rb +3 -3
  50. data/templates/commands/init/Vagrantfile.erb +1 -1
  51. data/templates/locales/en.yml +32 -2
  52. data/templates/locales/providers_docker.yml +2 -0
  53. data/templates/nfs/exports_darwin.erb +7 -0
  54. data/vagrant.gemspec +3 -4
  55. data/version.txt +1 -1
  56. metadata +7273 -773
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9bbf0332bbe6ca456380199ded15ef9328a2ebaa00f92ba7d112fb4c5b43bf15
4
- data.tar.gz: 5a524b4d511179f37c729faa12a9af27b622783a0298815e5527575f51a0e0ed
3
+ metadata.gz: 5c1283ff34586e6a2607abd40cd3e31715639e0700fe9430c1efa7b8087e2473
4
+ data.tar.gz: 0ad8e0b9d1b606802db43d803b28d9e3d168243168e3092c5ba37bcab7571bde
5
5
  SHA512:
6
- metadata.gz: fc695c903cb52ca50c9d50530c0d461164210608d2ffae6961a00d252606dbcf2b5cc4b8cc9124bad784b7e655b980939c694dfce6e8dbf2ef2ac9475fac77fd
7
- data.tar.gz: 9fabb62a9cdd8fb3070de6b6a0488e55216578725b802be4933f45dd65704a9564bc0885c4647abf7a3e6aac4a3f848d855702c735a3ba380c38c09b3dab658a
6
+ metadata.gz: 323983d2f71ed25fd578143f77f912621ba5631bdd7d7c68409c249831ed925507e47d91f2b4403fd9a54503ac84c3d086535c87e122fcdeb3fe97e2dcc0679b
7
+ data.tar.gz: dfe2cb8904ad0bf9ebd1391afac0df82064cbd760c3db372e9aa6d103986c7c64e18b0efe729da3dbe21b3ed0be8106da5f5d5d65723a8386ebb0d569e8af68a
data/.hashibot.hcl ADDED
@@ -0,0 +1,12 @@
1
+ poll "closed_issue_locker" "locker" {
2
+ schedule = "0 50 1 * * *"
3
+ closed_for = "720h" # 30 days
4
+ max_issues = 500
5
+ sleep_between_issues = "5s"
6
+
7
+ message = <<-EOF
8
+ I'm going to lock this issue because it has been closed for _30 days_ ⏳. This helps our maintainers find and focus on the active issues.
9
+
10
+ If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.
11
+ EOF
12
+ }
data/CHANGELOG.md CHANGED
@@ -1,3 +1,38 @@
1
+ ## 2.2.7 (January 27, 2020)
2
+
3
+ IMPROVEMENTS:
4
+
5
+ - guest/opensuse: Check for basename hostname prior to setting hostname [GH-11170]
6
+ - host/linux: Check for modinfo in /sbin if it's not on PATH [GH-11178]
7
+ - core: Show guest name in hostname error message [GH-11175]
8
+ - provisioners/shell: Linux guests now support `reboot` option [GH-11194]
9
+ - darwin/nfs: Put each NFS export on its own line [GH-11216]
10
+ - contrib/bash: Add more completion flags to up command [GH-11223]
11
+ - provider/virtualbox: Add VirtualBox provider support for version 6.1.x [GH-11250]
12
+ - box/outdated: Allow to force check for box updates and ignore cached check [GH-11231]
13
+ - guest/alpine: Update apk cache when installing rsync [GH-11220]
14
+ - provider/virtualbox: Improve error message when machine folder is inaccessible [GH-11239]
15
+ - provisioner/ansible_local: Add pip install method for arch guests [GH-11265]
16
+ - communicators/winssh: Use Windows shell for `vagrant ssh -c` [GH-11258]
17
+
18
+ BUG FIXES:
19
+
20
+ - command/snapshot/save: Fix regression that prevented snapshot of all guests in environment [GH-11152]
21
+ - core: Update UI to properly retain newlines when adding prefix [GH-11126]
22
+ - core: Check if box update is available locally [GH-11188]
23
+ - core: Ensure Vagrant::Errors are loaded in file_checksum util [GH-11183]
24
+ - cloud/publish: Improve argument handling for missing arguments to command [GH-11184]
25
+ - core: Get latest version for current provider during outdated check [GH-11192]
26
+ - linux/nfs: avoid adding extra newlines to /etc/exports [GH-11201]
27
+ - guest/darwin: Fix VMware synced folders on APFS [GH-11267]
28
+ - guest/redhat: Ensure `nfs-server` is restarted when installing nfs client [GH-11212]
29
+ - core: Do not validate checksums if options are empty string [GH-11211]
30
+ - provider/docker: Enhance docker build method to match against buildkit output [GH-11205]
31
+ - provisioner/ansible_local: Don't prompt for input when installing Ansible on Ubuntu and Debian [GH-11191]
32
+ - provisioner/ansible_local: Ensure all guest caps accept all passed in arguments [GH-11265]
33
+ - host/windows: Fix regression that prevented port collisions from being detected [GH-11244]
34
+ - core/provisioner: Set top level provisioner name if set in a provisioner config [GH-11295]
35
+
1
36
  ## 2.2.6 (October 14, 2019)
2
37
 
3
38
  FEATURES:
@@ -13,7 +48,7 @@ IMPROVEMENTS:
13
48
  - guest/alt: Improve handling for using network tools when setting hostname [GH-11000]
14
49
  - guest/suse: Add ipv6 network config templates for SUSE based distributions [GH-11013]
15
50
  - guest/windows: Retry on connection timeout errors for the reboot capability [GH-11093]
16
- - host/bsd: Use host resolve path capability to modify local paths if requird [GH-11108]
51
+ - host/bsd: Use host resolve path capability to modify local paths if required [GH-11108]
17
52
  - host/darwin: Add host resolve path capability to provide real paths for firmlinks [GH-11108]
18
53
  - provisioners/chef: Update pkg install flags for chef on FreeBSD guests [GH-11075]
19
54
  - provider/hyperv: Improve error message when VMMS is not running [GH-10978]
@@ -509,7 +544,7 @@ BUG FIXES:
509
544
  - core: Rescue more exceptions when checking if port is open [GH-8517]
510
545
  - guests/solaris11: Inherit from Solaris guest and keep solaris11 specific methods [GH-9034]
511
546
  - guests/windows: Split out cygwin path helper for msys2/cygwin paths and ensure cygpath exists [GH-8972]
512
- - guests/windows: Specify expected shell when executing on guest (fixes winssh communicator usage) [GH-9012]
547
+ - guests/windows: Specify expected shell when executing on guest (fixes einssh communicator usage) [GH-9012]
513
548
  - guests/windows: Include WinSSH Communicator when using insert_public_key [GH-9105]
514
549
  - hosts/windows: Check for vagrant.exe when validating versions within WSL [GH-9107, GH-8962]
515
550
  - providers/docker: Isolate windows check within executor to handle running through VM [GH-8921]
@@ -75,7 +75,19 @@ _vagrant() {
75
75
  then
76
76
  local vm_list=$(find "${vagrant_state_file}/machines" -mindepth 1 -maxdepth 1 -type d -exec basename {} \;)
77
77
  fi
78
- local up_commands="--no-provision"
78
+ local up_commands="\
79
+ --provision \
80
+ --no-provision \
81
+ --provision-with \
82
+ --destroy-on-error \
83
+ --no-destroy-on-error \
84
+ --parallel \
85
+ --no-parallel
86
+ --provider \
87
+ --install-provider \
88
+ --no-install-provider \
89
+ -h \
90
+ --help"
79
91
  COMPREPLY=($(compgen -W "${up_commands} ${vm_list}" -- ${cur}))
80
92
  return 0
81
93
  ;;
@@ -15,6 +15,7 @@ module Vagrant
15
15
  autoload :Confirm, "vagrant/action/builtin/confirm"
16
16
  autoload :ConfigValidate, "vagrant/action/builtin/config_validate"
17
17
  autoload :DestroyConfirm, "vagrant/action/builtin/destroy_confirm"
18
+ autoload :Disk, "vagrant/action/builtin/disk"
18
19
  autoload :EnvSet, "vagrant/action/builtin/env_set"
19
20
  autoload :GracefulHalt, "vagrant/action/builtin/graceful_halt"
20
21
  autoload :HandleBox, "vagrant/action/builtin/handle_box"
@@ -348,9 +348,15 @@ module Vagrant
348
348
  end
349
349
 
350
350
  if opts[:checksum] && opts[:checksum_type]
351
- env[:ui].detail(I18n.t("vagrant.actions.box.add.checksumming"))
352
- validate_checksum(
353
- opts[:checksum_type], opts[:checksum], box_url)
351
+ if opts[:checksum].to_s.strip.empty?
352
+ @logger.warn("Given checksum is empty, cannot validate checksum for box")
353
+ elsif opts[:checksum_type].to_s.strip.empty?
354
+ @logger.warn("Given checksum type is empty, cannot validate checksum for box")
355
+ else
356
+ env[:ui].detail(I18n.t("vagrant.actions.box.add.checksumming"))
357
+ validate_checksum(
358
+ opts[:checksum_type], opts[:checksum], box_url)
359
+ end
354
360
  end
355
361
 
356
362
  # Add the box!
@@ -40,7 +40,7 @@ module Vagrant
40
40
  # Have download options specified in the environment override
41
41
  # options specified for the machine.
42
42
  download_options = {
43
- automatic_check: true,
43
+ automatic_check: !env[:box_outdated_force],
44
44
  ca_cert: env[:ca_cert] || machine.config.vm.box_download_ca_cert,
45
45
  ca_path: env[:ca_path] || machine.config.vm.box_download_ca_path,
46
46
  client_cert: env[:client_cert] ||
@@ -70,15 +70,23 @@ module Vagrant
70
70
  message: e.message))
71
71
  end
72
72
  env[:box_outdated] = update != nil
73
- if update
73
+ local_update = check_outdated_local(env)
74
+ if update && (local_update.nil? || (local_update.version < update[1].version))
74
75
  env[:ui].warn(I18n.t(
75
76
  "vagrant.box_outdated_single",
76
77
  name: update[0].name,
77
78
  provider: box.provider,
78
79
  current: box.version,
79
80
  latest: update[1].version))
81
+ elsif local_update
82
+ env[:ui].warn(I18n.t(
83
+ "vagrant.box_outdated_local",
84
+ name: local_update.name,
85
+ old: box.version,
86
+ new: local_update.version))
87
+ env[:box_outdated] = true
80
88
  else
81
- check_outdated_local(env)
89
+ env[:box_outdated] = false
82
90
  end
83
91
 
84
92
  @app.call(env)
@@ -93,19 +101,8 @@ module Vagrant
93
101
  version ||= ""
94
102
  version += "> #{machine.box.version}"
95
103
 
96
- box = env[:box_collection].find(
104
+ env[:box_collection].find(
97
105
  machine.box.name, machine.box.provider, version)
98
- if box
99
- env[:ui].warn(I18n.t(
100
- "vagrant.box_outdated_local",
101
- name: box.name,
102
- old: machine.box.version,
103
- new: box.version))
104
- env[:box_outdated] = true
105
- return
106
- end
107
-
108
- env[:box_outdated] = false
109
106
  end
110
107
  end
111
108
  end
@@ -0,0 +1,39 @@
1
+ module Vagrant
2
+ module Action
3
+ module Builtin
4
+ class Disk
5
+ def initialize(app, env)
6
+ @app = app
7
+ @logger = Log4r::Logger.new("vagrant::action::builtin::disk")
8
+ end
9
+
10
+ def call(env)
11
+ machine = env[:machine]
12
+ defined_disks = get_disks(machine, env)
13
+
14
+ # Call into providers machine implementation for disk management
15
+ if !defined_disks.empty?
16
+ if machine.provider.capability?(:configure_disks)
17
+ machine.provider.capability(:configure_disks, defined_disks)
18
+ else
19
+ env[:ui].warn(I18n.t("vagrant.actions.disk.provider_unsupported",
20
+ provider: machine.provider_name))
21
+ end
22
+ end
23
+
24
+ # Continue On
25
+ @app.call(env)
26
+ end
27
+
28
+ def get_disks(machine, env)
29
+ return @_disks if @_disks
30
+
31
+ @_disks = []
32
+ @_disks = machine.config.vm.disks
33
+
34
+ @_disks
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -25,9 +25,27 @@ module Vagrant
25
25
  # Store in the type map so that --provision-with works properly
26
26
  @_provisioner_types[result] = provisioner.type
27
27
 
28
+ # Set top level provisioner name to provisioner configs name if top level name not set.
29
+ # This is mostly for handling the shell provisioner, if a user has set its name like:
30
+ #
31
+ # config.vm.provision "shell", name: "my_provisioner"
32
+ #
33
+ # Where `name` is a shell config option, not a top level provisioner class option
34
+ #
35
+ # Note: `name` is set to a symbol, since it is converted to one via #Config::VM.provision
36
+ provisioner_name = provisioner.name
37
+ if !provisioner_name
38
+ if provisioner.config.respond_to?(:name) &&
39
+ provisioner.config.name
40
+ provisioner_name = provisioner.config.name.to_sym
41
+ end
42
+ else
43
+ provisioner_name = provisioner_name.to_sym
44
+ end
45
+
28
46
  # Build up the options
29
47
  options = {
30
- name: provisioner.name,
48
+ name: provisioner_name,
31
49
  run: provisioner.run,
32
50
  before: provisioner.before,
33
51
  after: provisioner.after,
@@ -36,17 +36,35 @@ module Vagrant
36
36
 
37
37
  # Get the command and wrap it in a login shell
38
38
  command = ShellQuote.escape(env[:ssh_run_command], "'")
39
- command = "#{env[:machine].config.ssh.shell} -c '#{command}'"
39
+
40
+ if env[:machine].config.vm.communicator == :winssh
41
+ shell = env[:machine].config.winssh.shell
42
+ else
43
+ shell = env[:machine].config.ssh.shell
44
+ end
45
+
46
+ if shell == "cmd"
47
+ # Add an extra space to the command so cmd.exe quoting works
48
+ # properly
49
+ command = "#{shell} /C #{command} "
50
+ elsif shell == "powershell"
51
+ command = "$ProgressPreference = \"SilentlyContinue\"; #{command}"
52
+ command = Base64.strict_encode64(command.encode("UTF-16LE", "UTF-8"))
53
+ command = "#{shell} -encodedCommand #{command}"
54
+ else
55
+ command = "#{shell} -c '#{command}'"
56
+ end
40
57
 
41
58
  # Execute!
42
59
  opts = env[:ssh_opts] || {}
43
60
  opts[:extra_args] ||= []
44
61
 
45
62
  # Allow the user to specify a tty or non-tty manually, but if they
46
- # don't then we default to a TTY
63
+ # don't then we default to a TTY unless they are using WinSSH
47
64
  if !opts[:extra_args].include?("-t") &&
48
65
  !opts[:extra_args].include?("-T") &&
49
- env[:tty]
66
+ env[:tty] &&
67
+ env[:machine].config.vm.communicator != :winssh
50
68
  opts[:extra_args] << "-t"
51
69
  end
52
70
 
@@ -47,7 +47,16 @@ module Vagrant
47
47
  raise Errors::VagrantInterrupt if env[:interrupted]
48
48
  action = @actions.shift
49
49
  @logger.info("Calling IN action: #{action}")
50
+
51
+ if !action.is_a?(Proc) && env[:hook]
52
+ hook_name = action.class.name.split("::").last.
53
+ gsub(/([a-z])([A-Z])/, '\1_\2').gsub('-', '_').downcase
54
+ end
55
+
56
+ env[:hook].call("before_#{hook_name}".to_sym) if hook_name
50
57
  @stack.unshift(action).first.call(env)
58
+ env[:hook].call("after_#{hook_name}".to_sym) if hook_name
59
+
51
60
  raise Errors::VagrantInterrupt if env[:interrupted]
52
61
  @logger.info("Calling OUT action: #{action}")
53
62
  rescue SystemExit
@@ -68,11 +68,25 @@ module Vagrant
68
68
 
69
69
  # Returns all the versions supported by this metadata. These
70
70
  # versions are sorted so the last element of the list is the
71
- # latest version.
71
+ # latest version. Optionally filter versions by a matching
72
+ # provider.
72
73
  #
73
74
  # @return[Array<String>]
74
- def versions
75
- @version_map.keys.sort.map(&:to_s)
75
+ def versions(**opts)
76
+ provider = nil
77
+ provider = opts[:provider].to_sym if opts[:provider]
78
+
79
+ if provider
80
+ @version_map.select do |version, raw|
81
+ if raw["providers"]
82
+ raw["providers"].detect do |p|
83
+ p["name"].to_sym == provider
84
+ end
85
+ end
86
+ end.keys.sort.map(&:to_s)
87
+ else
88
+ @version_map.keys.sort.map(&:to_s)
89
+ end
76
90
  end
77
91
 
78
92
  # Represents a single version within the metadata.
@@ -436,6 +436,10 @@ module Vagrant
436
436
  error_key(:machine_action_locked)
437
437
  end
438
438
 
439
+ class MachineFolderNotAccessible < VagrantError
440
+ error_key(:machine_folder_not_accessible)
441
+ end
442
+
439
443
  class MachineGuestNotReady < VagrantError
440
444
  error_key(:machine_guest_not_ready)
441
445
  end
data/lib/vagrant/ui.rb CHANGED
@@ -329,10 +329,15 @@ module Vagrant
329
329
  target = opts[:target] if opts.key?(:target)
330
330
  target = "#{target}:" if target != ""
331
331
 
332
- # Get the lines. The first default is because if the message
333
- # is an empty string, then we want to still use the empty string.
334
332
  lines = [message]
335
- lines = message.split("\n") if message != ""
333
+ if message != ""
334
+ lines = [].tap do |l|
335
+ message.scan(/(.*?)(\n|$)/).each do |m|
336
+ l << m.first if m.first != "" || (m.first == "" && m.last == "\n")
337
+ end
338
+ end
339
+ lines << "" if message.end_with?("\n")
340
+ end
336
341
 
337
342
  # Otherwise, make sure to prefix every line properly
338
343
  lines.map do |line|
@@ -2,6 +2,9 @@
2
2
  # passed into FileChecksum. Note that this isn't strictly enforced at
3
3
  # the moment, and this class isn't directly used. It is merely here for
4
4
  # documentation of structure of the class.
5
+
6
+ require "vagrant/errors"
7
+
5
8
  class DigestClass
6
9
  def update(string); end
7
10
  def hexdigest; end
@@ -62,8 +65,9 @@ class FileChecksum
62
65
  def load_digest(type)
63
66
  digest = CHECKSUM_MAP[type.to_s.to_sym]
64
67
  if digest.nil?
65
- raise Errors::BoxChecksumInvalidType,
66
- type: type.to_s
68
+ raise Vagrant::Errors::BoxChecksumInvalidType,
69
+ type: type.to_s,
70
+ types: CHECKSUM_MAP.keys.join(', ')
67
71
  end
68
72
  digest
69
73
  end
@@ -30,8 +30,7 @@ module Vagrant
30
30
  return true
31
31
  end
32
32
  rescue Timeout::Error, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, \
33
- Errno::ENETUNREACH, Errno::EACCES, Errno::ENOTCONN, \
34
- Errno::EADDRNOTAVAIL
33
+ Errno::ENETUNREACH, Errno::EACCES, Errno::ENOTCONN
35
34
  # Any of the above exceptions signal that the port is closed.
36
35
  return false
37
36
  end
@@ -0,0 +1,61 @@
1
+ require "log4r"
2
+
3
+ module Vagrant
4
+ module Util
5
+ class Numeric
6
+
7
+ # Authors Note: This conversion has been borrowed from the ActiveSupport Numeric class
8
+ # Conversion helper constants
9
+ KILOBYTE = 1024
10
+ MEGABYTE = KILOBYTE * 1024
11
+ GIGABYTE = MEGABYTE * 1024
12
+ TERABYTE = GIGABYTE * 1024
13
+ PETABYTE = TERABYTE * 1024
14
+ EXABYTE = PETABYTE * 1024
15
+
16
+ BYTES_CONVERSION_MAP = {KB: KILOBYTE, MB: MEGABYTE, GB: GIGABYTE, TB: TERABYTE,
17
+ PB: PETABYTE, EB: EXABYTE}
18
+
19
+ # Regex borrowed from the vagrant-disksize config class
20
+ SHORTHAND_MATCH_REGEX = /^(?<number>[0-9]+)\s?(?<unit>KB|MB|GB|TB)?$/
21
+
22
+ class << self
23
+ LOGGER = Log4r::Logger.new("vagrant::util::numeric")
24
+
25
+ # A helper that converts a shortcut string to its bytes representation.
26
+ # The expected format of `str` is essentially: "<Number>XX"
27
+ # Where `XX` is shorthand for KB, MB, GB, TB, PB, or EB. For example, 50 megabytes:
28
+ #
29
+ # str = "50MB"
30
+ #
31
+ # @param [String] - str
32
+ # @return [Integer,nil] - bytes - returns nil if method fails to convert to bytes
33
+ def string_to_bytes(str)
34
+ bytes = nil
35
+
36
+ str = str.to_s.strip
37
+ matches = SHORTHAND_MATCH_REGEX.match(str)
38
+ if matches
39
+ number = matches[:number].to_i
40
+ unit = matches[:unit].to_sym
41
+
42
+ if BYTES_CONVERSION_MAP.key?(unit)
43
+ bytes = number * BYTES_CONVERSION_MAP[unit]
44
+ else
45
+ LOGGER.error("An invalid unit or format was given, string_to_bytes cannot convert #{str}")
46
+ end
47
+ end
48
+
49
+ bytes
50
+ end
51
+
52
+ # @private
53
+ # Reset the cached values for platform. This is not considered a public
54
+ # API and should only be used for testing.
55
+ def reset!
56
+ instance_variables.each(&method(:remove_instance_variable))
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end