train 2.1.7 → 2.1.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/lib/train.rb +20 -20
  3. data/lib/train/errors.rb +1 -1
  4. data/lib/train/extras.rb +2 -2
  5. data/lib/train/extras/command_wrapper.rb +24 -24
  6. data/lib/train/extras/stat.rb +27 -27
  7. data/lib/train/file.rb +30 -30
  8. data/lib/train/file/local.rb +8 -8
  9. data/lib/train/file/local/unix.rb +5 -5
  10. data/lib/train/file/local/windows.rb +1 -1
  11. data/lib/train/file/remote.rb +8 -8
  12. data/lib/train/file/remote/aix.rb +1 -1
  13. data/lib/train/file/remote/linux.rb +2 -2
  14. data/lib/train/file/remote/qnx.rb +8 -8
  15. data/lib/train/file/remote/unix.rb +10 -14
  16. data/lib/train/file/remote/windows.rb +5 -5
  17. data/lib/train/globals.rb +1 -1
  18. data/lib/train/options.rb +8 -8
  19. data/lib/train/platforms.rb +8 -8
  20. data/lib/train/platforms/common.rb +1 -1
  21. data/lib/train/platforms/detect/helpers/os_common.rb +36 -32
  22. data/lib/train/platforms/detect/helpers/os_linux.rb +12 -12
  23. data/lib/train/platforms/detect/helpers/os_windows.rb +27 -29
  24. data/lib/train/platforms/detect/scanner.rb +4 -4
  25. data/lib/train/platforms/detect/specifications/api.rb +8 -8
  26. data/lib/train/platforms/detect/specifications/os.rb +252 -252
  27. data/lib/train/platforms/detect/uuid.rb +5 -7
  28. data/lib/train/platforms/platform.rb +9 -5
  29. data/lib/train/plugin_test_helper.rb +12 -12
  30. data/lib/train/plugins.rb +5 -5
  31. data/lib/train/plugins/base_connection.rb +13 -13
  32. data/lib/train/plugins/transport.rb +7 -7
  33. data/lib/train/transports/azure.rb +23 -23
  34. data/lib/train/transports/cisco_ios_connection.rb +20 -20
  35. data/lib/train/transports/clients/azure/graph_rbac.rb +2 -2
  36. data/lib/train/transports/clients/azure/vault.rb +4 -4
  37. data/lib/train/transports/docker.rb +4 -10
  38. data/lib/train/transports/gcp.rb +23 -23
  39. data/lib/train/transports/helpers/azure/file_credentials.rb +8 -8
  40. data/lib/train/transports/helpers/azure/file_parser.rb +1 -1
  41. data/lib/train/transports/helpers/azure/subscription_number_file_parser.rb +1 -1
  42. data/lib/train/transports/local.rb +22 -22
  43. data/lib/train/transports/mock.rb +33 -35
  44. data/lib/train/transports/ssh.rb +47 -47
  45. data/lib/train/transports/ssh_connection.rb +28 -28
  46. data/lib/train/transports/vmware.rb +32 -34
  47. data/lib/train/transports/winrm.rb +37 -37
  48. data/lib/train/transports/winrm_connection.rb +12 -12
  49. data/lib/train/version.rb +1 -1
  50. metadata +2 -2
@@ -12,7 +12,7 @@ module Train
12
12
  end
13
13
 
14
14
  def content
15
- @content ||= ::File.read(@path, encoding: 'UTF-8')
15
+ @content ||= ::File.read(@path, encoding: "UTF-8")
16
16
  rescue StandardError => _
17
17
  nil
18
18
  end
@@ -23,7 +23,7 @@ module Train
23
23
  @link_path ||= ::File.realpath(@path)
24
24
  rescue Errno::ELOOP => _
25
25
  # Leave it blank on symbolic loop, same as readlink
26
- @link_path = ''
26
+ @link_path = ""
27
27
  end
28
28
  end
29
29
 
@@ -42,13 +42,13 @@ module Train
42
42
 
43
43
  def type
44
44
  case ::File.ftype(@path)
45
- when 'blockSpecial'
45
+ when "blockSpecial"
46
46
  :block_device
47
- when 'characterSpecial'
47
+ when "characterSpecial"
48
48
  :character_device
49
- when 'link'
49
+ when "link"
50
50
  :symlink
51
- when 'fifo'
51
+ when "fifo"
52
52
  :pipe
53
53
  else
54
54
  ::File.ftype(@path).to_sym
@@ -76,5 +76,5 @@ end
76
76
 
77
77
  # subclass requires are loaded after Train::File::Local is defined
78
78
  # to avoid superclass mismatch errors
79
- require 'train/file/local/unix'
80
- require 'train/file/local/windows'
79
+ require "train/file/local/unix"
80
+ require "train/file/local/windows"
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'shellwords'
4
- require 'train/extras/stat'
3
+ require "shellwords"
4
+ require "train/extras/stat"
5
5
 
6
6
  module Train
7
7
  class File
@@ -36,9 +36,9 @@ module Train
36
36
  gid: file_stat.gid,
37
37
  }
38
38
 
39
- lstat = @follow_symlink ? ' -L' : ''
39
+ lstat = @follow_symlink ? " -L" : ""
40
40
  res = @backend.run_command("stat#{lstat} #{@spath} 2>/dev/null --printf '%C'")
41
- if res.exit_status == 0 && !res.stdout.empty? && res.stdout != '?'
41
+ if res.exit_status == 0 && !res.stdout.empty? && res.stdout != "?"
42
42
  @stat[:selinux_label] = res.stdout.strip
43
43
  end
44
44
 
@@ -79,7 +79,7 @@ module Train
79
79
  end
80
80
 
81
81
  UNIX_MODE_OWNERS = {
82
- all: 00777,
82
+ all: 00777,
83
83
  owner: 00700,
84
84
  group: 00070,
85
85
  other: 00007,
@@ -9,7 +9,7 @@ module Train
9
9
  def sanitize_filename(path)
10
10
  return if path.nil?
11
11
  # we do not filter :, backslash and forward slash, since they are part of the path
12
- @spath = path.gsub(/[<>"|?*]/, '')
12
+ @spath = path.gsub(/[<>"|?*]/, "")
13
13
  end
14
14
 
15
15
  def product_version
@@ -3,9 +3,9 @@
3
3
  module Train
4
4
  class File
5
5
  class Remote < Train::File
6
- def basename(suffix = nil, sep = '/')
7
- fail 'Not yet supported: Suffix in file.basename' unless suffix.nil?
8
- @basename ||= detect_filename(path, sep || '/')
6
+ def basename(suffix = nil, sep = "/")
7
+ raise "Not yet supported: Suffix in file.basename" unless suffix.nil?
8
+ @basename ||= detect_filename(path, sep || "/")
9
9
  end
10
10
 
11
11
  def stat
@@ -29,8 +29,8 @@ end
29
29
 
30
30
  # subclass requires are loaded after Train::File::Remote is defined
31
31
  # to avoid superclass mismatch errors
32
- require 'train/file/remote/aix'
33
- require 'train/file/remote/linux'
34
- require 'train/file/remote/qnx'
35
- require 'train/file/remote/unix'
36
- require 'train/file/remote/windows'
32
+ require "train/file/remote/aix"
33
+ require "train/file/remote/linux"
34
+ require "train/file/remote/qnx"
35
+ require "train/file/remote/unix"
36
+ require "train/file/remote/windows"
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'train/file/remote/unix'
3
+ require "train/file/remote/unix"
4
4
 
5
5
  module Train
6
6
  class File
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'train/file/remote/unix'
3
+ require "train/file/remote/unix"
4
4
 
5
5
  module Train
6
6
  class File
@@ -10,7 +10,7 @@ module Train
10
10
  return @content if defined?(@content)
11
11
  @content = @backend.run_command("cat #{@spath} || echo -n").stdout
12
12
  return @content unless @content.empty?
13
- @content = nil if directory? or size.nil? or size > 0
13
+ @content = nil if directory? || size.nil? || (size > 0)
14
14
  @content
15
15
  end
16
16
  end
@@ -3,28 +3,28 @@
3
3
  # author: Christoph Hartmann
4
4
  # author: Dominik Richter
5
5
 
6
- require 'train/file/remote/unix'
6
+ require "train/file/remote/unix"
7
7
 
8
8
  module Train
9
9
  class File
10
10
  class Remote
11
11
  class Qnx < Train::File::Remote::Unix
12
12
  def content
13
- cat = 'cat'
14
- cat = '/proc/boot/cat' if @backend.os[:release].to_i >= 7
13
+ cat = "cat"
14
+ cat = "/proc/boot/cat" if @backend.os[:release].to_i >= 7
15
15
  @content ||= case
16
16
  when !exist?
17
17
  nil
18
18
  else
19
- @backend.run_command("#{cat} #{@spath}").stdout || ''
19
+ @backend.run_command("#{cat} #{@spath}").stdout || ""
20
20
  end
21
21
  end
22
22
 
23
23
  def type
24
- if @backend.run_command("file #{@spath}").stdout.include?('directory')
25
- return :directory
24
+ if @backend.run_command("file #{@spath}").stdout.include?("directory")
25
+ :directory
26
26
  else
27
- return :file
27
+ :file
28
28
  end
29
29
  end
30
30
 
@@ -32,7 +32,7 @@ module Train
32
32
  mode owner group uid gid mtime size selinux_label link_path mounted stat
33
33
  }.each do |field|
34
34
  define_method field.to_sym do
35
- fail NotImplementedError, "QNX does not implement the #{field}() method yet."
35
+ raise NotImplementedError, "QNX does not implement the #{field}() method yet."
36
36
  end
37
37
  end
38
38
  end
@@ -1,13 +1,9 @@
1
- # encoding: utf-8
2
-
3
- require 'shellwords'
1
+ require "shellwords"
4
2
 
5
3
  module Train
6
4
  class File
7
5
  class Remote
8
6
  class Unix < Train::File::Remote
9
- attr_reader :path
10
-
11
7
  def sanitize_filename(path)
12
8
  @spath = Shellwords.escape(path) || @path
13
9
  end
@@ -16,19 +12,19 @@ module Train
16
12
  @content ||=
17
13
  if !exist? || directory?
18
14
  nil
19
- elsif size.nil? || size.zero?
20
- ''
15
+ elsif size.nil? || size == 0
16
+ ""
21
17
  else
22
- @backend.run_command("cat #{@spath}").stdout || ''
18
+ @backend.run_command("cat #{@spath}").stdout || ""
23
19
  end
24
20
  end
25
21
 
26
22
  def exist?
27
- @exist ||= (
28
- f = @follow_symlink ? '' : " || test -L #{@spath}"
29
- @backend.run_command("test -e #{@spath}"+f)
23
+ @exist ||= begin
24
+ f = @follow_symlink ? "" : " || test -L #{@spath}"
25
+ @backend.run_command("test -e #{@spath}" + f)
30
26
  .exit_status == 0
31
- )
27
+ end
32
28
  end
33
29
 
34
30
  def mounted
@@ -88,14 +84,14 @@ module Train
88
84
  full_path = @backend.run_command("readlink -n #{@spath} -f").stdout
89
85
  # Needed for some OSes like OSX that returns relative path
90
86
  # when the link and target are in the same directory
91
- if !full_path.start_with?('/') && full_path != ''
87
+ if !full_path.start_with?("/") && full_path != ""
92
88
  full_path = ::File.expand_path("../#{full_path}", @spath)
93
89
  end
94
90
  full_path
95
91
  end
96
92
 
97
93
  UNIX_MODE_OWNERS = {
98
- all: 00777,
94
+ all: 00777,
99
95
  owner: 00700,
100
96
  group: 00070,
101
97
  other: 00007,
@@ -10,7 +10,7 @@ module Train
10
10
  def sanitize_filename(path)
11
11
  return if path.nil?
12
12
  # we do not filter :, backslash and forward slash, since they are part of the path
13
- @spath = path.gsub(/[<>"|?*]/, '')
13
+ @spath = path.gsub(/[<>"|?*]/, "")
14
14
  end
15
15
 
16
16
  def basename(suffix = nil, sep = '\\')
@@ -28,7 +28,7 @@ module Train
28
28
  def exist?
29
29
  return @exist if defined?(@exist)
30
30
  @exist = @backend.run_command(
31
- "(Test-Path -Path \"#{@spath}\").ToString()").stdout.chomp == 'True'
31
+ "(Test-Path -Path \"#{@spath}\").ToString()").stdout.chomp == "True"
32
32
  end
33
33
 
34
34
  def owner
@@ -39,11 +39,11 @@ module Train
39
39
  end
40
40
 
41
41
  def type
42
- if attributes.include?('Archive') && !attributes.include?('Directory')
42
+ if attributes.include?("Archive") && !attributes.include?("Directory")
43
43
  return :file
44
- elsif attributes.include?('ReparsePoint')
44
+ elsif attributes.include?("ReparsePoint")
45
45
  return :symlink
46
- elsif attributes.include?('Directory')
46
+ elsif attributes.include?("Directory")
47
47
  return :directory
48
48
  end
49
49
  :unknown
data/lib/train/globals.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Train
2
2
  def self.src_root
3
- File.expand_path(File.join(__FILE__, '..', '..', '..'))
3
+ File.expand_path(File.join(__FILE__, "..", "..", ".."))
4
4
  end
5
5
  end
data/lib/train/options.rb CHANGED
@@ -14,15 +14,15 @@ module Train
14
14
  def option(name, conf = nil, &block)
15
15
  d = conf || {}
16
16
  unless d.is_a? Hash
17
- fail Train::ClientError,
17
+ raise Train::ClientError,
18
18
  "The transport plugin #{self} declared an option #{name} "\
19
19
  "and didn't provide a valid configuration hash."
20
20
  end
21
21
 
22
- if !conf.nil? and !conf[:default].nil? and block_given?
23
- fail Train::ClientError,
22
+ if !conf.nil? && !conf[:default].nil? && block_given?
23
+ raise Train::ClientError,
24
24
  "The transport plugin #{self} declared an option #{name} "\
25
- 'with both a default value and block. Only use one of these.'
25
+ "with both a default value and block. Only use one of these."
26
26
  end
27
27
 
28
28
  d[:default] = block if block_given?
@@ -37,7 +37,7 @@ module Train
37
37
 
38
38
  def include_options(other)
39
39
  unless other.respond_to?(:default_options)
40
- fail "Trying to include options from module #{other.inspect}, "\
40
+ raise "Trying to include options from module #{other.inspect}, "\
41
41
  "which doesn't seem to support options."
42
42
  end
43
43
  default_options.merge!(other.default_options)
@@ -55,7 +55,7 @@ module Train
55
55
  def merge_options(base, opts)
56
56
  res = base.merge(opts || {})
57
57
  default_options.each do |field, hm|
58
- next unless res[field].nil? and hm.key?(:default)
58
+ next unless res[field].nil? && hm.key?(:default)
59
59
  default = hm[:default]
60
60
  if default.is_a? Proc
61
61
  res[field] = default.call(res)
@@ -68,8 +68,8 @@ module Train
68
68
 
69
69
  def validate_options(opts)
70
70
  default_options.each do |field, hm|
71
- if opts[field].nil? and hm[:required]
72
- fail Train::ClientError,
71
+ if opts[field].nil? && hm[:required]
72
+ raise Train::ClientError,
73
73
  "You must provide a value for #{field.to_s.inspect}."
74
74
  end
75
75
  end
@@ -1,13 +1,13 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'train/platforms/common'
4
- require 'train/platforms/detect'
5
- require 'train/platforms/detect/scanner'
6
- require 'train/platforms/detect/specifications/os'
7
- require 'train/platforms/detect/specifications/api'
8
- require 'train/platforms/detect/uuid'
9
- require 'train/platforms/family'
10
- require 'train/platforms/platform'
3
+ require "train/platforms/common"
4
+ require "train/platforms/detect"
5
+ require "train/platforms/detect/scanner"
6
+ require "train/platforms/detect/specifications/os"
7
+ require "train/platforms/detect/specifications/api"
8
+ require "train/platforms/detect/uuid"
9
+ require "train/platforms/family"
10
+ require "train/platforms/platform"
11
11
 
12
12
  module Train::Platforms
13
13
  class << self
@@ -6,7 +6,7 @@ module Train::Platforms
6
6
  # if it does not exist and add a child relationship.
7
7
  def in_family(family)
8
8
  if self.class == Train::Platforms::Family && @name == family
9
- fail "Unable to add family #{@name} to itself: '#{@name}.in_family(#{family})'"
9
+ raise "Unable to add family #{@name} to itself: '#{@name}.in_family(#{family})'"
10
10
  end
11
11
 
12
12
  # add family to the family list
@@ -1,8 +1,6 @@
1
- # encoding: utf-8
2
-
3
- require 'train/platforms/detect/helpers/os_linux'
4
- require 'train/platforms/detect/helpers/os_windows'
5
- require 'rbconfig'
1
+ require "train/platforms/detect/helpers/os_linux"
2
+ require "train/platforms/detect/helpers/os_windows"
3
+ require "rbconfig"
6
4
 
7
5
  module Train::Platforms::Detect::Helpers
8
6
  module OSCommon
@@ -10,11 +8,11 @@ module Train::Platforms::Detect::Helpers
10
8
  include Train::Platforms::Detect::Helpers::Windows
11
9
 
12
10
  def ruby_host_os(regex)
13
- ::RbConfig::CONFIG['host_os'] =~ regex
11
+ ::RbConfig::CONFIG["host_os"] =~ regex
14
12
  end
15
13
 
16
14
  def winrm?
17
- @backend.class.to_s == 'Train::Transports::WinRM::Connection'
15
+ @backend.class.to_s == "Train::Transports::WinRM::Connection"
18
16
  end
19
17
 
20
18
  def unix_file_contents(path)
@@ -23,42 +21,48 @@ module Train::Platforms::Detect::Helpers
23
21
 
24
22
  res = @backend.run_command("test -f #{path} && cat #{path}")
25
23
  # ignore files that can't be read
26
- @files[path] = res.exit_status.zero? ? res.stdout : nil
24
+ @files[path] = res.exit_status == 0 ? res.stdout : nil
27
25
  @files[path]
28
26
  end
29
27
 
30
28
  def unix_file_exist?(path)
31
- @backend.run_command("test -f #{path}").exit_status.zero?
29
+ @backend.run_command("test -f #{path}").exit_status == 0
32
30
  end
33
31
 
34
32
  def command_output(cmd)
35
33
  res = @backend.run_command(cmd).stdout
34
+ # When you try to execute command using ssh connction as root user and you have provided ssh user identity file
35
+ # it gives standard output to login as authorised user other than root. To show this standard ouput as an error
36
+ # to user we are matching the string of stdout and raising the error here so that user gets exact information.
37
+ if @backend.class.to_s == "Train::Transports::SSH::Connection" && res =~ /Please login as the user/
38
+ raise Train::UserError, "SSH failed: #{res}"
39
+ end
36
40
  res.strip! unless res.nil?
37
41
  res
38
42
  end
39
43
 
40
44
  def unix_uname_s
41
45
  return @uname[:s] if @uname.key?(:s)
42
- @uname[:s] = command_output('uname -s')
46
+ @uname[:s] = command_output("uname -s")
43
47
  end
44
48
 
45
49
  def unix_uname_r
46
50
  return @uname[:r] if @uname.key?(:r)
47
- @uname[:r] = command_output('uname -r')
51
+ @uname[:r] = command_output("uname -r")
48
52
  end
49
53
 
50
54
  def unix_uname_m
51
55
  return @uname[:m] if @uname.key?(:m)
52
- @uname[:m] = command_output('uname -m')
56
+ @uname[:m] = command_output("uname -m")
53
57
  end
54
58
 
55
59
  def brocade_version
56
60
  return @cache[:brocade] if @cache.key?(:brocade)
57
- res = command_output('version')
61
+ res = command_output("version")
58
62
 
59
63
  m = res.match(/^Fabric OS:\s+v(\S+)$/)
60
64
  unless m.nil?
61
- return @cache[:brocade] = { version: m[1], type: 'fos' }
65
+ return @cache[:brocade] = { version: m[1], type: "fos" }
62
66
  end
63
67
 
64
68
  @cache[:brocade] = nil
@@ -66,53 +70,53 @@ module Train::Platforms::Detect::Helpers
66
70
 
67
71
  def cisco_show_version
68
72
  return @cache[:cisco] if @cache.key?(:cisco)
69
- res = command_output('show version')
73
+ res = command_output("show version")
70
74
 
71
75
  m = res.match(/Cisco IOS Software, [^,]+? \(([^,]+?)\), Version (\d+\.\d+)/)
72
76
  unless m.nil?
73
- return @cache[:cisco] = { version: m[2], model: m[1], type: 'ios' }
77
+ return @cache[:cisco] = { version: m[2], model: m[1], type: "ios" }
74
78
  end
75
79
 
76
80
  m = res.match(/Cisco IOS Software, IOS-XE Software, [^,]+? \(([^,]+?)\), Version (\d+\.\d+\.\d+[A-Z]*)/)
77
81
  unless m.nil?
78
- return @cache[:cisco] = { version: m[2], model: m[1], type: 'ios-xe' }
82
+ return @cache[:cisco] = { version: m[2], model: m[1], type: "ios-xe" }
79
83
  end
80
84
 
81
85
  m = res.match(/Cisco Nexus Operating System \(NX-OS\) Software/)
82
86
  unless m.nil?
83
87
  v = res[/^\s*system:\s+version (\d+\.\d+)/, 1]
84
- return @cache[:cisco] = { version: v, type: 'nexus' }
88
+ return @cache[:cisco] = { version: v, type: "nexus" }
85
89
  end
86
90
 
87
91
  @cache[:cisco] = nil
88
92
  end
89
93
 
90
94
  def unix_uuid
91
- uuid = unix_uuid_from_chef
92
- uuid = unix_uuid_from_machine_file if uuid.nil?
93
- uuid = uuid_from_command if uuid.nil?
94
- raise Train::TransportError, 'Cannot find a UUID for your node.' if uuid.nil?
95
- uuid
95
+ (unix_uuid_from_chef ||
96
+ unix_uuid_from_machine_file ||
97
+ uuid_from_command ||
98
+ raise(Train::TransportError, "Cannot find a UUID for your node."))
96
99
  end
97
100
 
98
101
  def unix_uuid_from_chef
99
- file = @backend.file('/var/chef/cache/data_collector_metadata.json')
100
- if file.exist? && !file.size.zero?
102
+ file = @backend.file("/var/chef/cache/data_collector_metadata.json")
103
+ if file.exist? && file.size != 0
101
104
  json = ::JSON.parse(file.content)
102
- return json['node_uuid'] if json['node_uuid']
105
+ return json["node_uuid"] if json["node_uuid"]
103
106
  end
104
107
  end
105
108
 
106
109
  def unix_uuid_from_machine_file
107
- %W(
110
+ # require 'pry';binding.pry
111
+ %W{
108
112
  /etc/chef/chef_guid
109
113
  #{ENV['HOME']}/.chef/chef_guid
110
114
  /etc/machine-id
111
115
  /var/lib/dbus/machine-id
112
116
  /var/db/dbus/machine-id
113
- ).each do |path|
117
+ }.each do |path|
114
118
  file = @backend.file(path)
115
- next unless file.exist? && !file.size.zero?
119
+ next unless file.exist? && file.size != 0
116
120
  return file.content.chomp if path =~ /guid/
117
121
  return uuid_from_string(file.content.chomp)
118
122
  end
@@ -125,7 +129,7 @@ module Train::Platforms::Detect::Helpers
125
129
  def uuid_from_command
126
130
  return unless @platform[:uuid_command]
127
131
  result = @backend.run_command(@platform[:uuid_command])
128
- uuid_from_string(result.stdout.chomp) if result.exit_status.zero? && !result.stdout.empty?
132
+ uuid_from_string(result.stdout.chomp) if result.exit_status == 0 && !result.stdout.empty?
129
133
  end
130
134
 
131
135
  # This hashes the passed string into SHA1.
@@ -134,11 +138,11 @@ module Train::Platforms::Detect::Helpers
134
138
  def uuid_from_string(string)
135
139
  hash = Digest::SHA1.new
136
140
  hash.update(string)
137
- ary = hash.digest.unpack('NnnnnN')
141
+ ary = hash.digest.unpack("NnnnnN")
138
142
  ary[2] = (ary[2] & 0x0FFF) | (5 << 12)
139
143
  ary[3] = (ary[3] & 0x3FFF) | 0x8000
140
144
  # rubocop:disable Style/FormatString
141
- '%08x-%04x-%04x-%04x-%04x%08x' % ary
145
+ "%08x-%04x-%04x-%04x-%04x%08x" % ary
142
146
  end
143
147
  end
144
148
  end