vagrant-ssh-config-manager 0.8.3 → 1.0.0.alpha
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.
- checksums.yaml +4 -4
- data/.bundle/config +1 -1
- data/.gitignore +2 -1
- data/.rspec +2 -0
- data/.rubocop.yml +62 -0
- data/Gemfile +11 -9
- data/README.md +2 -2
- data/Rakefile +10 -8
- data/TESTING.md +82 -0
- data/lib/vagrant/ssh/config/manager.rb +5 -0
- data/lib/vagrant_ssh_config_manager/action/destroy.rb +82 -0
- data/lib/vagrant_ssh_config_manager/action/halt.rb +66 -0
- data/lib/vagrant_ssh_config_manager/action/provision.rb +81 -0
- data/lib/vagrant_ssh_config_manager/action/reload.rb +105 -0
- data/lib/vagrant_ssh_config_manager/action/up.rb +98 -0
- data/lib/{vagrant-ssh-config-manager → vagrant_ssh_config_manager}/config.rb +45 -49
- data/lib/{vagrant-ssh-config-manager → vagrant_ssh_config_manager}/file_locker.rb +35 -37
- data/lib/{vagrant-ssh-config-manager → vagrant_ssh_config_manager}/file_manager.rb +90 -80
- data/lib/{vagrant-ssh-config-manager → vagrant_ssh_config_manager}/include_manager.rb +54 -53
- data/lib/{vagrant-ssh-config-manager → vagrant_ssh_config_manager}/plugin.rb +15 -13
- data/lib/vagrant_ssh_config_manager/ssh_config_manager.rb +1152 -0
- data/lib/{vagrant-ssh-config-manager → vagrant_ssh_config_manager}/ssh_info_extractor.rb +129 -141
- data/lib/vagrant_ssh_config_manager/version.rb +7 -0
- data/lib/{vagrant-ssh-config-manager.rb → vagrant_ssh_config_manager.rb} +15 -12
- data/test-all.sh +11 -0
- data/test-integration.sh +4 -0
- data/test-unit.sh +4 -0
- data/vagrant-ssh-config-manager.gemspec +25 -21
- metadata +28 -18
- data/lib/vagrant-ssh-config-manager/action/destroy.rb +0 -84
- data/lib/vagrant-ssh-config-manager/action/halt.rb +0 -68
- data/lib/vagrant-ssh-config-manager/action/provision.rb +0 -82
- data/lib/vagrant-ssh-config-manager/action/reload.rb +0 -106
- data/lib/vagrant-ssh-config-manager/action/up.rb +0 -99
- data/lib/vagrant-ssh-config-manager/ssh_config_manager.rb +0 -2150
- data/lib/vagrant-ssh-config-manager/version.rb +0 -5
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module SshConfigManager
|
5
|
+
module Action
|
6
|
+
class Up
|
7
|
+
def initialize(app, env)
|
8
|
+
@app = app
|
9
|
+
@env = env
|
10
|
+
@logger = Log4r::Logger.new('vagrant::plugins::ssh_config_manager::action::up')
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
# Call the next middleware first
|
15
|
+
@app.call(env)
|
16
|
+
|
17
|
+
# Only proceed if the machine is running and SSH is ready
|
18
|
+
machine = env[:machine]
|
19
|
+
return unless machine
|
20
|
+
return unless machine.state.id == :running
|
21
|
+
|
22
|
+
# Check if plugin is enabled
|
23
|
+
config = machine.config.sshconfigmanager
|
24
|
+
return unless config&.enabled
|
25
|
+
|
26
|
+
@logger.info("SSH Config Manager: Creating SSH config file for machine: #{machine.name}")
|
27
|
+
|
28
|
+
# Handle SSH config file creation
|
29
|
+
handle_ssh_config_creation(machine, config)
|
30
|
+
rescue StandardError => e
|
31
|
+
@logger.error("SSH Config Manager: Error in Up action: #{e.message}")
|
32
|
+
@logger.debug("Backtrace: #{e.backtrace.join("\n")}")
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def handle_ssh_config_creation(machine, config)
|
38
|
+
@logger.info("Creating SSH config file for machine: #{machine.name}")
|
39
|
+
|
40
|
+
# Lazy load required classes with error handling
|
41
|
+
begin
|
42
|
+
require 'vagrant_ssh_config_manager/ssh_info_extractor'
|
43
|
+
require 'vagrant_ssh_config_manager/file_manager'
|
44
|
+
require 'vagrant_ssh_config_manager/include_manager'
|
45
|
+
rescue LoadError => e
|
46
|
+
@logger.error("Failed to load required classes: #{e.message}")
|
47
|
+
machine.ui.warn('SSH config manager: Failed to load required components, skipping SSH config creation')
|
48
|
+
return
|
49
|
+
end
|
50
|
+
|
51
|
+
# Extract SSH information
|
52
|
+
extractor = SshInfoExtractor.new(machine)
|
53
|
+
|
54
|
+
# Check if machine supports SSH
|
55
|
+
unless extractor.ssh_capable?
|
56
|
+
@logger.debug("Machine #{machine.name} does not support SSH, skipping")
|
57
|
+
return
|
58
|
+
end
|
59
|
+
|
60
|
+
# Create file manager and include manager
|
61
|
+
file_manager = FileManager.new(config)
|
62
|
+
include_manager = IncludeManager.new(config)
|
63
|
+
|
64
|
+
# Write SSH config file
|
65
|
+
@logger.info("Attempting to create SSH config file for #{machine.name}")
|
66
|
+
|
67
|
+
if file_manager.write_ssh_config_file(machine)
|
68
|
+
host_name = file_manager.send(:generate_host_name, machine)
|
69
|
+
machine.ui.info("SSH config file created for machine '#{machine.name}' as '#{host_name}'")
|
70
|
+
machine.ui.info("You can now connect with: ssh #{host_name}")
|
71
|
+
@logger.info("Successfully created SSH config file for #{machine.name}")
|
72
|
+
|
73
|
+
# Manage Include directive after file creation
|
74
|
+
include_manager.manage_include_directive
|
75
|
+
else
|
76
|
+
machine.ui.warn("Failed to create SSH config file for machine: #{machine.name}")
|
77
|
+
@logger.warn("Failed to create SSH config file for #{machine.name}")
|
78
|
+
end
|
79
|
+
rescue Errno::EACCES => e
|
80
|
+
@logger.error("Permission denied accessing SSH config for #{machine.name}: #{e.message}")
|
81
|
+
machine.ui.warn('SSH config manager: Permission denied. Check file permissions.')
|
82
|
+
rescue Errno::ENOSPC => e
|
83
|
+
@logger.error("No space left on device for #{machine.name}: #{e.message}")
|
84
|
+
machine.ui.warn('SSH config manager: No space left on device.')
|
85
|
+
rescue Errno::EIO => e
|
86
|
+
@logger.error("I/O error for #{machine.name}: #{e.message}")
|
87
|
+
machine.ui.warn('SSH config manager: I/O error accessing SSH config files.')
|
88
|
+
rescue StandardError => e
|
89
|
+
@logger.error("Error creating SSH config for #{machine.name}: #{e.message}")
|
90
|
+
@logger.debug("Backtrace: #{e.backtrace.join("\n")}")
|
91
|
+
|
92
|
+
# Don't fail the vagrant up process, just warn
|
93
|
+
machine.ui.warn("SSH config manager encountered an error: #{e.message}")
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -1,26 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'fileutils'
|
2
4
|
require 'vagrant'
|
3
5
|
|
4
6
|
module VagrantPlugins
|
5
7
|
module SshConfigManager
|
6
|
-
|
8
|
+
# Configuration for SSH Config Manager
|
9
|
+
class Config < Vagrant.plugin('2', :config)
|
7
10
|
# Plugin enabled/disabled flag
|
8
11
|
attr_accessor :enabled
|
9
12
|
|
10
13
|
# SSH config directory configuration
|
11
14
|
attr_accessor :ssh_config_dir
|
12
|
-
attr_accessor :manage_includes
|
13
|
-
|
14
|
-
attr_accessor :cleanup_empty_dir
|
15
|
+
attr_accessor :manage_includes, :auto_create_dir, :cleanup_empty_dir, :update_on_reload, :refresh_on_provision,
|
16
|
+
:keep_config_on_halt, :project_isolation
|
15
17
|
|
16
18
|
# Additional configuration options
|
17
19
|
attr_accessor :auto_remove_on_destroy
|
18
|
-
attr_accessor :update_on_reload
|
19
|
-
attr_accessor :refresh_on_provision
|
20
|
-
attr_accessor :keep_config_on_halt
|
21
|
-
attr_accessor :project_isolation
|
22
20
|
|
21
|
+
# Set initial state, call parent constructor
|
23
22
|
def initialize
|
23
|
+
super
|
24
24
|
@enabled = Vagrant::Plugin::V2::Config::UNSET_VALUE
|
25
25
|
@ssh_config_dir = Vagrant::Plugin::V2::Config::UNSET_VALUE
|
26
26
|
@manage_includes = Vagrant::Plugin::V2::Config::UNSET_VALUE
|
@@ -36,7 +36,9 @@ module VagrantPlugins
|
|
36
36
|
def finalize!
|
37
37
|
# Set default values for unset configuration options
|
38
38
|
@enabled = true if @enabled == Vagrant::Plugin::V2::Config::UNSET_VALUE
|
39
|
-
|
39
|
+
if @ssh_config_dir == Vagrant::Plugin::V2::Config::UNSET_VALUE
|
40
|
+
@ssh_config_dir = File.expand_path('~/.ssh/config.d/vagrant')
|
41
|
+
end
|
40
42
|
@manage_includes = false if @manage_includes == Vagrant::Plugin::V2::Config::UNSET_VALUE
|
41
43
|
@auto_create_dir = true if @auto_create_dir == Vagrant::Plugin::V2::Config::UNSET_VALUE
|
42
44
|
@cleanup_empty_dir = true if @cleanup_empty_dir == Vagrant::Plugin::V2::Config::UNSET_VALUE
|
@@ -48,48 +50,44 @@ module VagrantPlugins
|
|
48
50
|
|
49
51
|
# Expand and validate file paths
|
50
52
|
@ssh_config_dir = File.expand_path(@ssh_config_dir) if @ssh_config_dir.is_a?(String)
|
51
|
-
|
53
|
+
|
52
54
|
# Ensure SSH config directory exists if auto_create_dir is enabled
|
53
55
|
ensure_ssh_config_directory if @auto_create_dir && @ssh_config_dir
|
54
56
|
end
|
55
57
|
|
56
|
-
def validate(
|
58
|
+
def validate(_machine)
|
57
59
|
errors = _detected_errors
|
58
60
|
|
59
61
|
# Validate enabled flag
|
60
|
-
unless [true, false].include?(@enabled)
|
61
|
-
errors << "sshconfigmanager.enabled must be true or false"
|
62
|
-
end
|
62
|
+
errors << 'sshconfigmanager.enabled must be true or false' unless [true, false].include?(@enabled)
|
63
63
|
|
64
64
|
# Validate SSH config directory
|
65
65
|
if @ssh_config_dir
|
66
|
-
|
67
|
-
errors << "sshconfigmanager.ssh_config_dir must be a string path"
|
68
|
-
else
|
66
|
+
if @ssh_config_dir.is_a?(String)
|
69
67
|
# Validate directory path format
|
70
68
|
expanded_path = File.expand_path(@ssh_config_dir)
|
71
|
-
if expanded_path.include?(
|
69
|
+
if expanded_path.include?('..') || expanded_path.include?('//')
|
72
70
|
errors << "sshconfigmanager.ssh_config_dir contains invalid path components: #{@ssh_config_dir}"
|
73
71
|
end
|
74
72
|
|
75
73
|
# Check if the directory exists or can be created
|
76
|
-
|
77
|
-
if @auto_create_dir
|
78
|
-
begin
|
79
|
-
# Try to create the directory to validate the path
|
80
|
-
FileUtils.mkdir_p(@ssh_config_dir, mode: 0700)
|
81
|
-
rescue => e
|
82
|
-
errors << "sshconfigmanager.ssh_config_dir cannot be created: #{e.message}"
|
83
|
-
end
|
84
|
-
else
|
85
|
-
errors << "sshconfigmanager.ssh_config_dir does not exist and auto_create_dir is disabled: #{@ssh_config_dir}"
|
86
|
-
end
|
87
|
-
else
|
74
|
+
if File.directory?(@ssh_config_dir)
|
88
75
|
# Check directory permissions
|
89
76
|
unless File.readable?(@ssh_config_dir) && File.writable?(@ssh_config_dir)
|
90
77
|
errors << "sshconfigmanager.ssh_config_dir is not readable/writable: #{@ssh_config_dir}"
|
91
78
|
end
|
79
|
+
elsif @auto_create_dir
|
80
|
+
begin
|
81
|
+
# Try to create the directory to validate the path
|
82
|
+
FileUtils.mkdir_p(@ssh_config_dir, mode: 0o700)
|
83
|
+
rescue StandardError => e
|
84
|
+
errors << "sshconfigmanager.ssh_config_dir cannot be created: #{e.message}"
|
85
|
+
end
|
86
|
+
else
|
87
|
+
errors << "sshconfigmanager.ssh_config_dir does not exist and auto_create_dir is disabled: #{@ssh_config_dir}"
|
92
88
|
end
|
89
|
+
else
|
90
|
+
errors << 'sshconfigmanager.ssh_config_dir must be a string path'
|
93
91
|
end
|
94
92
|
end
|
95
93
|
|
@@ -106,13 +104,11 @@ module VagrantPlugins
|
|
106
104
|
}
|
107
105
|
|
108
106
|
boolean_options.each do |option_name, value|
|
109
|
-
unless [true, false].include?(value)
|
110
|
-
errors << "sshconfigmanager.#{option_name} must be true or false"
|
111
|
-
end
|
107
|
+
errors << "sshconfigmanager.#{option_name} must be true or false" unless [true, false].include?(value)
|
112
108
|
end
|
113
109
|
|
114
110
|
# Return validation results
|
115
|
-
{
|
111
|
+
{ 'SSH Config Manager' => errors }
|
116
112
|
end
|
117
113
|
|
118
114
|
# Get configuration summary for debugging
|
@@ -156,16 +152,16 @@ module VagrantPlugins
|
|
156
152
|
result = self.class.new
|
157
153
|
|
158
154
|
# Merge each attribute, preferring the other config's values if set
|
159
|
-
result.enabled = other.enabled
|
160
|
-
result.ssh_config_dir = other.ssh_config_dir
|
161
|
-
result.manage_includes = other.manage_includes
|
162
|
-
result.auto_create_dir = other.auto_create_dir
|
163
|
-
result.cleanup_empty_dir = other.cleanup_empty_dir
|
164
|
-
result.auto_remove_on_destroy = other.auto_remove_on_destroy
|
165
|
-
result.update_on_reload = other.update_on_reload
|
166
|
-
result.refresh_on_provision = other.refresh_on_provision
|
167
|
-
result.keep_config_on_halt = other.keep_config_on_halt
|
168
|
-
result.project_isolation = other.project_isolation
|
155
|
+
result.enabled = other.enabled == UNSET_VALUE ? @enabled : other.enabled
|
156
|
+
result.ssh_config_dir = other.ssh_config_dir == UNSET_VALUE ? @ssh_config_dir : other.ssh_config_dir
|
157
|
+
result.manage_includes = other.manage_includes == UNSET_VALUE ? @manage_includes : other.manage_includes
|
158
|
+
result.auto_create_dir = other.auto_create_dir == UNSET_VALUE ? @auto_create_dir : other.auto_create_dir
|
159
|
+
result.cleanup_empty_dir = other.cleanup_empty_dir == UNSET_VALUE ? @cleanup_empty_dir : other.cleanup_empty_dir
|
160
|
+
result.auto_remove_on_destroy = other.auto_remove_on_destroy == UNSET_VALUE ? @auto_remove_on_destroy : other.auto_remove_on_destroy
|
161
|
+
result.update_on_reload = other.update_on_reload == UNSET_VALUE ? @update_on_reload : other.update_on_reload
|
162
|
+
result.refresh_on_provision = other.refresh_on_provision == UNSET_VALUE ? @refresh_on_provision : other.refresh_on_provision
|
163
|
+
result.keep_config_on_halt = other.keep_config_on_halt == UNSET_VALUE ? @keep_config_on_halt : other.keep_config_on_halt
|
164
|
+
result.project_isolation = other.project_isolation == UNSET_VALUE ? @project_isolation : other.project_isolation
|
169
165
|
|
170
166
|
result
|
171
167
|
end
|
@@ -176,19 +172,19 @@ module VagrantPlugins
|
|
176
172
|
return true if File.directory?(@ssh_config_dir)
|
177
173
|
|
178
174
|
begin
|
179
|
-
FileUtils.mkdir_p(@ssh_config_dir, mode:
|
175
|
+
FileUtils.mkdir_p(@ssh_config_dir, mode: 0o700)
|
180
176
|
true
|
181
|
-
rescue
|
177
|
+
rescue StandardError
|
182
178
|
false
|
183
179
|
end
|
184
180
|
end
|
185
181
|
|
186
|
-
#
|
187
|
-
def
|
188
|
-
# Use separate file approach with FileManager
|
182
|
+
# Retrieve the SSH config manager for a given machine
|
183
|
+
def ssh_manager_instance(_machine)
|
189
184
|
require_relative 'file_manager'
|
190
185
|
FileManager.new(self)
|
191
186
|
end
|
187
|
+
alias get_ssh_manager_instance ssh_manager_instance
|
192
188
|
end
|
193
189
|
end
|
194
190
|
end
|
@@ -1,8 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'fcntl'
|
2
4
|
require 'timeout'
|
3
5
|
|
4
6
|
module VagrantPlugins
|
5
7
|
module SshConfigManager
|
8
|
+
# Handles file locking for SSH config files to prevent concurrent conflicts
|
6
9
|
class FileLocker
|
7
10
|
# Default timeout for acquiring locks (in seconds)
|
8
11
|
DEFAULT_TIMEOUT = 30
|
@@ -14,29 +17,25 @@ module VagrantPlugins
|
|
14
17
|
|
15
18
|
def initialize(file_path, logger = nil)
|
16
19
|
@file_path = file_path
|
17
|
-
@logger = logger || Log4r::Logger.new(
|
20
|
+
@logger = logger || Log4r::Logger.new('vagrant::plugins::ssh_config_manager::file_locker')
|
18
21
|
@lock_file = nil
|
19
22
|
@locked = false
|
20
23
|
end
|
21
24
|
|
22
25
|
# Acquire an exclusive lock on the file
|
23
|
-
def with_exclusive_lock(timeout: DEFAULT_TIMEOUT)
|
24
|
-
with_lock(LOCK_EXCLUSIVE, timeout: timeout)
|
25
|
-
yield
|
26
|
-
end
|
26
|
+
def with_exclusive_lock(timeout: DEFAULT_TIMEOUT, &block)
|
27
|
+
with_lock(LOCK_EXCLUSIVE, timeout: timeout, &block)
|
27
28
|
end
|
28
29
|
|
29
30
|
# Acquire a shared lock on the file
|
30
|
-
def with_shared_lock(timeout: DEFAULT_TIMEOUT)
|
31
|
-
with_lock(LOCK_SHARED, timeout: timeout)
|
32
|
-
yield
|
33
|
-
end
|
31
|
+
def with_shared_lock(timeout: DEFAULT_TIMEOUT, &block)
|
32
|
+
with_lock(LOCK_SHARED, timeout: timeout, &block)
|
34
33
|
end
|
35
34
|
|
36
35
|
# Check if file is currently locked by another process
|
37
36
|
def locked?
|
38
37
|
return false unless File.exist?(@file_path)
|
39
|
-
|
38
|
+
|
40
39
|
begin
|
41
40
|
File.open(@file_path, 'r') do |file|
|
42
41
|
# Try to acquire a non-blocking exclusive lock
|
@@ -45,7 +44,7 @@ module VagrantPlugins
|
|
45
44
|
end
|
46
45
|
rescue Errno::EAGAIN, Errno::EACCES
|
47
46
|
true # File is locked
|
48
|
-
rescue => e
|
47
|
+
rescue StandardError => e
|
49
48
|
@logger.debug("Error checking lock status: #{e.message}")
|
50
49
|
false
|
51
50
|
end
|
@@ -55,7 +54,7 @@ module VagrantPlugins
|
|
55
54
|
|
56
55
|
def with_lock(lock_type, timeout: DEFAULT_TIMEOUT)
|
57
56
|
acquire_lock(lock_type, timeout: timeout)
|
58
|
-
|
57
|
+
|
59
58
|
begin
|
60
59
|
yield
|
61
60
|
ensure
|
@@ -65,34 +64,33 @@ module VagrantPlugins
|
|
65
64
|
|
66
65
|
def acquire_lock(lock_type, timeout: DEFAULT_TIMEOUT)
|
67
66
|
ensure_directory_exists
|
68
|
-
|
67
|
+
|
69
68
|
@logger.debug("Acquiring #{lock_type_name(lock_type)} lock on #{@file_path}")
|
70
|
-
|
69
|
+
|
71
70
|
# Use timeout to prevent infinite waiting
|
72
71
|
Timeout.timeout(timeout) do
|
73
|
-
@lock_file = File.open(@file_path, File::RDWR | File::CREAT,
|
72
|
+
@lock_file = File.open(@file_path, File::RDWR | File::CREAT, 0o600)
|
74
73
|
@lock_file.flock(lock_type)
|
75
74
|
@locked = true
|
76
75
|
@logger.debug("Successfully acquired lock on #{@file_path}")
|
77
76
|
end
|
78
|
-
|
79
77
|
rescue Timeout::Error
|
80
78
|
cleanup_lock_file
|
81
|
-
raise LockTimeoutError
|
82
|
-
rescue => e
|
79
|
+
raise LockTimeoutError, "Timeout waiting for lock on #{@file_path} (waited #{timeout}s)"
|
80
|
+
rescue StandardError => e
|
83
81
|
cleanup_lock_file
|
84
82
|
@logger.error("Failed to acquire lock on #{@file_path}: #{e.message}")
|
85
|
-
raise LockAcquisitionError
|
83
|
+
raise LockAcquisitionError, "Could not acquire lock: #{e.message}"
|
86
84
|
end
|
87
85
|
|
88
86
|
def release_lock
|
89
87
|
return unless @locked && @lock_file
|
90
88
|
|
91
89
|
@logger.debug("Releasing lock on #{@file_path}")
|
92
|
-
|
90
|
+
|
93
91
|
begin
|
94
92
|
@lock_file.flock(File::LOCK_UN)
|
95
|
-
rescue => e
|
93
|
+
rescue StandardError => e
|
96
94
|
@logger.warn("Error releasing lock: #{e.message}")
|
97
95
|
ensure
|
98
96
|
cleanup_lock_file
|
@@ -100,34 +98,34 @@ module VagrantPlugins
|
|
100
98
|
end
|
101
99
|
|
102
100
|
def cleanup_lock_file
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
101
|
+
return unless @lock_file
|
102
|
+
|
103
|
+
begin
|
104
|
+
@lock_file.close unless @lock_file.closed?
|
105
|
+
rescue StandardError => e
|
106
|
+
@logger.debug("Error closing lock file: #{e.message}")
|
107
|
+
ensure
|
108
|
+
@lock_file = nil
|
109
|
+
@locked = false
|
112
110
|
end
|
113
111
|
end
|
114
112
|
|
115
113
|
def ensure_directory_exists
|
116
114
|
dir = File.dirname(@file_path)
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
115
|
+
return if File.directory?(dir)
|
116
|
+
|
117
|
+
FileUtils.mkdir_p(dir, mode: 0o700)
|
118
|
+
@logger.debug("Created directory: #{dir}")
|
121
119
|
end
|
122
120
|
|
123
121
|
def lock_type_name(lock_type)
|
124
122
|
case lock_type
|
125
123
|
when LOCK_SHARED
|
126
|
-
|
124
|
+
'shared'
|
127
125
|
when LOCK_EXCLUSIVE
|
128
|
-
|
126
|
+
'exclusive'
|
129
127
|
else
|
130
|
-
|
128
|
+
'unknown'
|
131
129
|
end
|
132
130
|
end
|
133
131
|
end
|