train 0.13.1 → 0.14.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.
- checksums.yaml +4 -4
 - data/CHANGELOG.md +15 -2
 - data/lib/train/extras/file_common.rb +18 -8
 - data/lib/train/extras/os_common.rb +4 -1
 - data/lib/train/extras/os_detect_esx.rb +6 -4
 - data/lib/train/extras/stat.rb +7 -7
 - data/lib/train/plugins/base_connection.rb +17 -0
 - data/lib/train/transports/docker.rb +0 -1
 - data/lib/train/transports/local.rb +0 -1
 - data/lib/train/transports/mock.rb +19 -5
 - data/lib/train/transports/ssh_connection.rb +1 -2
 - data/lib/train/transports/winrm_connection.rb +1 -2
 - data/lib/train/version.rb +1 -1
 - data/test/integration/test-one.yaml +4 -0
 - data/test/integration/test-two.yaml +4 -0
 - data/test/integration/tests/path_file_test.rb +6 -0
 - data/test/integration/tests/run_command_test.rb +7 -0
 - data/test/unit/extras/os_common_test.rb +1 -0
 - data/test/unit/extras/stat_test.rb +41 -0
 - data/test/unit/transports/mock_test.rb +9 -2
 - metadata +7 -3
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: bef369edee3db008a24f018851fb38b4b8ee2690
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 4a029b67d3631b3975ad928c1b7c7832ac7da2cf
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 81d4f61c914a1b3cbdfc11037c90be5652d3a7a8264d8ba351c65e614036a71bb507339ea6bfec310098b65a261b831d0ca97e517bd86dde5d286fae4cc9d466
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: c8d5bddc212d56e7d7f604df95008339b676c8dcf59a7dc59c7422d997d23781adce45276db983184a7c4b659282b98bd1d3b6f50b7434444fca12dfb7d8e7c0
         
     | 
    
        data/CHANGELOG.md
    CHANGED
    
    | 
         @@ -1,7 +1,20 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # Change Log
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
            ## [0. 
     | 
| 
       4 
     | 
    
         
            -
            [Full Changelog](https://github.com/chef/train/compare/v0. 
     | 
| 
      
 3 
     | 
    
         
            +
            ## [0.14.0](https://github.com/chef/train/tree/0.14.0) (2016-06-27)
         
     | 
| 
      
 4 
     | 
    
         
            +
            [Full Changelog](https://github.com/chef/train/compare/v0.13.1...0.14.0)
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            **Implemented enhancements:**
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            - json in and out for base connection [\#118](https://github.com/chef/train/pull/118) ([arlimus](https://github.com/arlimus))
         
     | 
| 
      
 9 
     | 
    
         
            +
            - ESX support [\#116](https://github.com/chef/train/pull/116) ([Anirudh-Gupta](https://github.com/Anirudh-Gupta))
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            **Fixed bugs:**
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            - sporadic appveyor failure on `winrm delete ...` [\#105](https://github.com/chef/train/issues/105)
         
     | 
| 
      
 14 
     | 
    
         
            +
            - bugfix: run frozen string commands via ssh [\#117](https://github.com/chef/train/pull/117) ([arlimus](https://github.com/arlimus))
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            ## [v0.13.1](https://github.com/chef/train/tree/v0.13.1) (2016-06-16)
         
     | 
| 
      
 17 
     | 
    
         
            +
            [Full Changelog](https://github.com/chef/train/compare/v0.12.1...v0.13.1)
         
     | 
| 
       5 
18 
     | 
    
         | 
| 
       6 
19 
     | 
    
         
             
            **Implemented enhancements:**
         
     | 
| 
       7 
20 
     | 
    
         | 
| 
         @@ -9,10 +9,12 @@ module Train::Extras 
     | 
|
| 
       9 
9 
     | 
    
         
             
              class FileCommon # rubocop:disable Metrics/ClassLength
         
     | 
| 
       10 
10 
     | 
    
         
             
                # interface methods: these fields should be implemented by every
         
     | 
| 
       11 
11 
     | 
    
         
             
                # backend File
         
     | 
| 
       12 
     | 
    
         
            -
                %w{
         
     | 
| 
      
 12 
     | 
    
         
            +
                DATA_FIELDS = %w{
         
     | 
| 
       13 
13 
     | 
    
         
             
                  exist? mode owner group uid gid content mtime size selinux_label path
         
     | 
| 
       14 
14 
     | 
    
         
             
                  product_version file_version
         
     | 
| 
       15 
     | 
    
         
            -
                }. 
     | 
| 
      
 15 
     | 
    
         
            +
                }.freeze
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                DATA_FIELDS.each do |m|
         
     | 
| 
       16 
18 
     | 
    
         
             
                  define_method m.to_sym do
         
     | 
| 
       17 
19 
     | 
    
         
             
                    fail NotImplementedError, "File must implement the #{m}() method."
         
     | 
| 
       18 
20 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -24,6 +26,14 @@ module Train::Extras 
     | 
|
| 
       24 
26 
     | 
    
         
             
                  @follow_symlink = follow_symlink
         
     | 
| 
       25 
27 
     | 
    
         
             
                end
         
     | 
| 
       26 
28 
     | 
    
         | 
| 
      
 29 
     | 
    
         
            +
                def to_json
         
     | 
| 
      
 30 
     | 
    
         
            +
                  res = Hash[DATA_FIELDS.map { |x| [x, method(x).call] }]
         
     | 
| 
      
 31 
     | 
    
         
            +
                  # additional fields provided as input
         
     | 
| 
      
 32 
     | 
    
         
            +
                  res['type'] = type
         
     | 
| 
      
 33 
     | 
    
         
            +
                  res['follow_symlink'] = @follow_symlink
         
     | 
| 
      
 34 
     | 
    
         
            +
                  res
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
       27 
37 
     | 
    
         
             
                def type
         
     | 
| 
       28 
38 
     | 
    
         
             
                  :unknown
         
     | 
| 
       29 
39 
     | 
    
         
             
                end
         
     | 
| 
         @@ -50,27 +60,27 @@ module Train::Extras 
     | 
|
| 
       50 
60 
     | 
    
         
             
                # Additional methods for convenience
         
     | 
| 
       51 
61 
     | 
    
         | 
| 
       52 
62 
     | 
    
         
             
                def file?
         
     | 
| 
       53 
     | 
    
         
            -
                  type ==  
     | 
| 
      
 63 
     | 
    
         
            +
                  type.to_s == 'file'
         
     | 
| 
       54 
64 
     | 
    
         
             
                end
         
     | 
| 
       55 
65 
     | 
    
         | 
| 
       56 
66 
     | 
    
         
             
                def block_device?
         
     | 
| 
       57 
     | 
    
         
            -
                  type ==  
     | 
| 
      
 67 
     | 
    
         
            +
                  type.to_s == 'block_device'
         
     | 
| 
       58 
68 
     | 
    
         
             
                end
         
     | 
| 
       59 
69 
     | 
    
         | 
| 
       60 
70 
     | 
    
         
             
                def character_device?
         
     | 
| 
       61 
     | 
    
         
            -
                  type ==  
     | 
| 
      
 71 
     | 
    
         
            +
                  type.to_s == 'character_device'
         
     | 
| 
       62 
72 
     | 
    
         
             
                end
         
     | 
| 
       63 
73 
     | 
    
         | 
| 
       64 
74 
     | 
    
         
             
                def socket?
         
     | 
| 
       65 
     | 
    
         
            -
                  type ==  
     | 
| 
      
 75 
     | 
    
         
            +
                  type.to_s == 'socket'
         
     | 
| 
       66 
76 
     | 
    
         
             
                end
         
     | 
| 
       67 
77 
     | 
    
         | 
| 
       68 
78 
     | 
    
         
             
                def directory?
         
     | 
| 
       69 
     | 
    
         
            -
                  type ==  
     | 
| 
      
 79 
     | 
    
         
            +
                  type.to_s == 'directory'
         
     | 
| 
       70 
80 
     | 
    
         
             
                end
         
     | 
| 
       71 
81 
     | 
    
         | 
| 
       72 
82 
     | 
    
         
             
                def symlink?
         
     | 
| 
       73 
     | 
    
         
            -
                  source.type ==  
     | 
| 
      
 83 
     | 
    
         
            +
                  source.type.to_s == 'symlink'
         
     | 
| 
       74 
84 
     | 
    
         
             
                end
         
     | 
| 
       75 
85 
     | 
    
         | 
| 
       76 
86 
     | 
    
         
             
                def source_path
         
     | 
| 
         @@ -12,6 +12,7 @@ require 'train/extras/os_detect_darwin' 
     | 
|
| 
       12 
12 
     | 
    
         
             
            require 'train/extras/os_detect_linux'
         
     | 
| 
       13 
13 
     | 
    
         
             
            require 'train/extras/os_detect_unix'
         
     | 
| 
       14 
14 
     | 
    
         
             
            require 'train/extras/os_detect_windows'
         
     | 
| 
      
 15 
     | 
    
         
            +
            require 'train/extras/os_detect_esx'
         
     | 
| 
       15 
16 
     | 
    
         | 
| 
       16 
17 
     | 
    
         
             
            module Train::Extras
         
     | 
| 
       17 
18 
     | 
    
         
             
              class OSCommon
         
     | 
| 
         @@ -19,6 +20,7 @@ module Train::Extras 
     | 
|
| 
       19 
20 
     | 
    
         
             
                include Train::Extras::DetectLinux
         
     | 
| 
       20 
21 
     | 
    
         
             
                include Train::Extras::DetectUnix
         
     | 
| 
       21 
22 
     | 
    
         
             
                include Train::Extras::DetectWindows
         
     | 
| 
      
 23 
     | 
    
         
            +
                include Train::Extras::DetectEsx
         
     | 
| 
       22 
24 
     | 
    
         | 
| 
       23 
25 
     | 
    
         
             
                def initialize(backend, platform = nil)
         
     | 
| 
       24 
26 
     | 
    
         
             
                  @backend = backend
         
     | 
| 
         @@ -107,7 +109,7 @@ module Train::Extras 
     | 
|
| 
       107 
109 
     | 
    
         
             
                  detect_family_type
         
     | 
| 
       108 
110 
     | 
    
         
             
                end
         
     | 
| 
       109 
111 
     | 
    
         | 
| 
       110 
     | 
    
         
            -
                def detect_family_type
         
     | 
| 
      
 112 
     | 
    
         
            +
                def detect_family_type # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
         
     | 
| 
       111 
113 
     | 
    
         
             
                  pf = @platform[:family]
         
     | 
| 
       112 
114 
     | 
    
         | 
| 
       113 
115 
     | 
    
         
             
                  return detect_windows if pf == 'windows'
         
     | 
| 
         @@ -120,6 +122,7 @@ module Train::Extras 
     | 
|
| 
       120 
122 
     | 
    
         | 
| 
       121 
123 
     | 
    
         
             
                  # unix based systems combine the above
         
     | 
| 
       122 
124 
     | 
    
         
             
                  return true if pf == 'unix' and detect_darwin
         
     | 
| 
      
 125 
     | 
    
         
            +
                  return true if pf == 'unix' and detect_esx
         
     | 
| 
       123 
126 
     | 
    
         
             
                  return true if pf == 'unix' and detect_via_uname
         
     | 
| 
       124 
127 
     | 
    
         | 
| 
       125 
128 
     | 
    
         
             
                  # if we arrive here, we most likey have a regular linux
         
     | 
| 
         @@ -11,10 +11,12 @@ 
     | 
|
| 
       11 
11 
     | 
    
         
             
            module Train::Extras
         
     | 
| 
       12 
12 
     | 
    
         
             
              module DetectEsx
         
     | 
| 
       13 
13 
     | 
    
         
             
                def detect_esx
         
     | 
| 
       14 
     | 
    
         
            -
                   
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
      
 14 
     | 
    
         
            +
                  if uname_s.downcase.chomp == 'vmkernel'
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @platform[:family] = 'esx'
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @platform[:name] = uname_s.lines[0].chomp
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @platform[:release] = uname_r.lines[0].chomp
         
     | 
| 
      
 18 
     | 
    
         
            +
                    true
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
       18 
20 
     | 
    
         
             
                end
         
     | 
| 
       19 
21 
     | 
    
         
             
              end
         
     | 
| 
       20 
22 
     | 
    
         
             
            end
         
     | 
    
        data/lib/train/extras/stat.rb
    CHANGED
    
    | 
         @@ -1,7 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # encoding: utf-8
         
     | 
| 
       2 
2 
     | 
    
         
             
            # author: Dominik Richter
         
     | 
| 
       3 
3 
     | 
    
         
             
            # author: Christoph Hartmann
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
4 
     | 
    
         
             
            module Train::Extras
         
     | 
| 
       6 
5 
     | 
    
         
             
              class Stat
         
     | 
| 
       7 
6 
     | 
    
         
             
                TYPES = {
         
     | 
| 
         @@ -20,13 +19,13 @@ module Train::Extras 
     | 
|
| 
       20 
19 
     | 
    
         
             
                end
         
     | 
| 
       21 
20 
     | 
    
         | 
| 
       22 
21 
     | 
    
         
             
                def self.stat(shell_escaped_path, backend, follow_symlink)
         
     | 
| 
       23 
     | 
    
         
            -
                  # use perl scripts for aix  
     | 
| 
      
 22 
     | 
    
         
            +
                  # use perl scripts for aix, solaris 10 and hpux
         
     | 
| 
       24 
23 
     | 
    
         
             
                  if backend.os.aix? || (backend.os.solaris? && backend.os[:release].to_i < 11) || backend.os.hpux?
         
     | 
| 
       25 
24 
     | 
    
         
             
                    return aix_stat(shell_escaped_path, backend, follow_symlink)
         
     | 
| 
       26 
25 
     | 
    
         
             
                  end
         
     | 
| 
       27 
26 
     | 
    
         
             
                  return bsd_stat(shell_escaped_path, backend, follow_symlink) if backend.os.bsd?
         
     | 
| 
       28 
     | 
    
         
            -
                  # linux and  
     | 
| 
       29 
     | 
    
         
            -
                  return linux_stat(shell_escaped_path, backend, follow_symlink) if backend.os.unix?
         
     | 
| 
      
 27 
     | 
    
         
            +
                  # linux,solaris 11 and esx will use standard linux stats
         
     | 
| 
      
 28 
     | 
    
         
            +
                  return linux_stat(shell_escaped_path, backend, follow_symlink) if backend.os.unix? || backend.os.esx?
         
     | 
| 
       30 
29 
     | 
    
         
             
                  # all other cases we don't handle
         
     | 
| 
       31 
30 
     | 
    
         
             
                  # TODO: print an error if we get here, as it shouldn't be invoked
         
     | 
| 
       32 
31 
     | 
    
         
             
                  # on non-unix
         
     | 
| 
         @@ -35,7 +34,8 @@ module Train::Extras 
     | 
|
| 
       35 
34 
     | 
    
         | 
| 
       36 
35 
     | 
    
         
             
                def self.linux_stat(shell_escaped_path, backend, follow_symlink)
         
     | 
| 
       37 
36 
     | 
    
         
             
                  lstat = follow_symlink ? ' -L' : ''
         
     | 
| 
       38 
     | 
    
         
            -
                   
     | 
| 
      
 37 
     | 
    
         
            +
                  format = backend.os.esx? ? '-c' : '--printf'
         
     | 
| 
      
 38 
     | 
    
         
            +
                  res = backend.run_command("stat#{lstat} #{shell_escaped_path} 2>/dev/null #{format} '%s\n%f\n%U\n%u\n%G\n%g\n%X\n%Y\n%C'")
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
40 
     | 
    
         
             
                  # ignore the exit_code: it is != 0 if selinux labels are not supported
         
     | 
| 
       41 
41 
     | 
    
         
             
                  # on the system.
         
     | 
| 
         @@ -45,8 +45,8 @@ module Train::Extras 
     | 
|
| 
       45 
45 
     | 
    
         | 
| 
       46 
46 
     | 
    
         
             
                  tmask = fields[1].to_i(16)
         
     | 
| 
       47 
47 
     | 
    
         
             
                  selinux = fields[8]
         
     | 
| 
       48 
     | 
    
         
            -
                  selinux  
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
      
 48 
     | 
    
         
            +
                  ## selinux security context string not available on esxi
         
     | 
| 
      
 49 
     | 
    
         
            +
                  selinux = nil if selinux == '?' or selinux == '(null)' or selinux == 'C'
         
     | 
| 
       50 
50 
     | 
    
         
             
                  {
         
     | 
| 
       51 
51 
     | 
    
         
             
                    type:  find_type(tmask),
         
     | 
| 
       52 
52 
     | 
    
         
             
                    mode:  tmask & 07777,
         
     | 
| 
         @@ -18,6 +18,9 @@ class Train::Plugins::Transport 
     | 
|
| 
       18 
18 
     | 
    
         
             
              class BaseConnection
         
     | 
| 
       19 
19 
     | 
    
         
             
                include Train::Extras
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
      
 21 
     | 
    
         
            +
                # Provide access to the files cache.
         
     | 
| 
      
 22 
     | 
    
         
            +
                attr_reader :files
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
       21 
24 
     | 
    
         
             
                # Create a new Connection instance.
         
     | 
| 
       22 
25 
     | 
    
         
             
                #
         
     | 
| 
       23 
26 
     | 
    
         
             
                # @param options [Hash] connection options
         
     | 
| 
         @@ -25,6 +28,7 @@ class Train::Plugins::Transport 
     | 
|
| 
       25 
28 
     | 
    
         
             
                def initialize(options = nil)
         
     | 
| 
       26 
29 
     | 
    
         
             
                  @options = options || {}
         
     | 
| 
       27 
30 
     | 
    
         
             
                  @logger = @options.delete(:logger) || Logger.new(STDOUT)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  @files = {}
         
     | 
| 
       28 
32 
     | 
    
         
             
                end
         
     | 
| 
       29 
33 
     | 
    
         | 
| 
       30 
34 
     | 
    
         
             
                # Closes the session connection, if it is still active.
         
     | 
| 
         @@ -32,6 +36,19 @@ class Train::Plugins::Transport 
     | 
|
| 
       32 
36 
     | 
    
         
             
                  # this method may be left unimplemented if that is applicable
         
     | 
| 
       33 
37 
     | 
    
         
             
                end
         
     | 
| 
       34 
38 
     | 
    
         | 
| 
      
 39 
     | 
    
         
            +
                def to_json
         
     | 
| 
      
 40 
     | 
    
         
            +
                  {
         
     | 
| 
      
 41 
     | 
    
         
            +
                    'files' => Hash[@files.map { |x, y| [x, y.to_json] }],
         
     | 
| 
      
 42 
     | 
    
         
            +
                  }
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                def load_json(j)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  require 'train/transports/mock'
         
     | 
| 
      
 47 
     | 
    
         
            +
                  j['files'].each do |path, jf|
         
     | 
| 
      
 48 
     | 
    
         
            +
                    @files[path] = Train::Transports::Mock::Connection::File.from_json(jf)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
       35 
52 
     | 
    
         
             
                # Execute a command using this connection.
         
     | 
| 
       36 
53 
     | 
    
         
             
                #
         
     | 
| 
       37 
54 
     | 
    
         
             
                # @param command [String] command string to execute
         
     | 
| 
         @@ -65,7 +65,6 @@ class Train::Transports::Mock 
     | 
|
| 
       65 
65 
     | 
    
         | 
| 
       66 
66 
     | 
    
         
             
                def initialize(conf = nil)
         
     | 
| 
       67 
67 
     | 
    
         
             
                  @conf = conf || {}
         
     | 
| 
       68 
     | 
    
         
            -
                  @files = {}
         
     | 
| 
       69 
68 
     | 
    
         
             
                  @os = OS.new(self, family: 'unknown')
         
     | 
| 
       70 
69 
     | 
    
         
             
                  @commands = {}
         
     | 
| 
       71 
70 
     | 
    
         
             
                end
         
     | 
| 
         @@ -130,12 +129,27 @@ end 
     | 
|
| 
       130 
129 
     | 
    
         | 
| 
       131 
130 
     | 
    
         
             
            class Train::Transports::Mock::Connection
         
     | 
| 
       132 
131 
     | 
    
         
             
              class File < FileCommon
         
     | 
| 
       133 
     | 
    
         
            -
                 
     | 
| 
       134 
     | 
    
         
            -
                   
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
      
 132 
     | 
    
         
            +
                def self.from_json(json)
         
     | 
| 
      
 133 
     | 
    
         
            +
                  res = new(json['backend'],
         
     | 
| 
      
 134 
     | 
    
         
            +
                            json['path'],
         
     | 
| 
      
 135 
     | 
    
         
            +
                            json['follow_symlink'])
         
     | 
| 
      
 136 
     | 
    
         
            +
                  res.type = json['type']
         
     | 
| 
      
 137 
     | 
    
         
            +
                  Train::Extras::FileCommon::DATA_FIELDS.each do |f|
         
     | 
| 
      
 138 
     | 
    
         
            +
                    m = (f.tr('?', '') + '=').to_sym
         
     | 
| 
      
 139 
     | 
    
         
            +
                    res.method(m).call(json[f])
         
     | 
| 
      
 140 
     | 
    
         
            +
                  end
         
     | 
| 
      
 141 
     | 
    
         
            +
                  res
         
     | 
| 
      
 142 
     | 
    
         
            +
                end
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
                Train::Extras::FileCommon::DATA_FIELDS.each do |m|
         
     | 
| 
       137 
145 
     | 
    
         
             
                  attr_accessor m.tr('?', '').to_sym
         
     | 
| 
      
 146 
     | 
    
         
            +
                  next unless m.include?('?')
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                  define_method m.to_sym do
         
     | 
| 
      
 149 
     | 
    
         
            +
                    method(m.tr('?', '').to_sym).call
         
     | 
| 
      
 150 
     | 
    
         
            +
                  end
         
     | 
| 
       138 
151 
     | 
    
         
             
                end
         
     | 
| 
      
 152 
     | 
    
         
            +
                attr_accessor :type
         
     | 
| 
       139 
153 
     | 
    
         | 
| 
       140 
154 
     | 
    
         
             
                def initialize(backend, path, follow_symlink = true)
         
     | 
| 
       141 
155 
     | 
    
         
             
                  super(backend, path, follow_symlink)
         
     | 
| 
         @@ -38,7 +38,6 @@ class Train::Transports::SSH 
     | 
|
| 
       38 
38 
     | 
    
         
             
                  @connection_retries     = @options.delete(:connection_retries)
         
     | 
| 
       39 
39 
     | 
    
         
             
                  @connection_retry_sleep = @options.delete(:connection_retry_sleep)
         
     | 
| 
       40 
40 
     | 
    
         
             
                  @max_wait_until_ready   = @options.delete(:max_wait_until_ready)
         
     | 
| 
       41 
     | 
    
         
            -
                  @files                  = {}
         
     | 
| 
       42 
41 
     | 
    
         
             
                  @session                = nil
         
     | 
| 
       43 
42 
     | 
    
         
             
                  @transport_options      = @options.delete(:transport_options)
         
     | 
| 
       44 
43 
     | 
    
         
             
                  @cmd_wrapper            = nil
         
     | 
| 
         @@ -73,7 +72,7 @@ class Train::Transports::SSH 
     | 
|
| 
       73 
72 
     | 
    
         
             
                def run_command(cmd)
         
     | 
| 
       74 
73 
     | 
    
         
             
                  stdout = stderr = ''
         
     | 
| 
       75 
74 
     | 
    
         
             
                  exit_status = nil
         
     | 
| 
       76 
     | 
    
         
            -
                  cmd.force_encoding('binary') if cmd.respond_to?(:force_encoding)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  cmd.dup.force_encoding('binary') if cmd.respond_to?(:force_encoding)
         
     | 
| 
       77 
76 
     | 
    
         
             
                  logger.debug("[SSH] #{self} (#{cmd})")
         
     | 
| 
       78 
77 
     | 
    
         | 
| 
       79 
78 
     | 
    
         
             
                  session.open_channel do |channel|
         
     | 
| 
         @@ -27,7 +27,7 @@ class Train::Transports::WinRM 
     | 
|
| 
       27 
27 
     | 
    
         
             
              # host such as executing commands, transferring files, etc.
         
     | 
| 
       28 
28 
     | 
    
         
             
              #
         
     | 
| 
       29 
29 
     | 
    
         
             
              # @author Fletcher Nichol <fnichol@nichol.ca>
         
     | 
| 
       30 
     | 
    
         
            -
              class Connection < BaseConnection 
     | 
| 
      
 30 
     | 
    
         
            +
              class Connection < BaseConnection
         
     | 
| 
       31 
31 
     | 
    
         
             
                def initialize(options)
         
     | 
| 
       32 
32 
     | 
    
         
             
                  super(options)
         
     | 
| 
       33 
33 
     | 
    
         
             
                  @endpoint               = @options.delete(:endpoint)
         
     | 
| 
         @@ -36,7 +36,6 @@ class Train::Transports::WinRM 
     | 
|
| 
       36 
36 
     | 
    
         
             
                  @connection_retries     = @options.delete(:connection_retries)
         
     | 
| 
       37 
37 
     | 
    
         
             
                  @connection_retry_sleep = @options.delete(:connection_retry_sleep)
         
     | 
| 
       38 
38 
     | 
    
         
             
                  @max_wait_until_ready   = @options.delete(:max_wait_until_ready)
         
     | 
| 
       39 
     | 
    
         
            -
                  @files                  = {}
         
     | 
| 
       40 
39 
     | 
    
         
             
                end
         
     | 
| 
       41 
40 
     | 
    
         | 
| 
       42 
41 
     | 
    
         
             
                # (see Base::Connection#close)
         
     | 
    
        data/lib/train/version.rb
    CHANGED
    
    
| 
         @@ -10,6 +10,13 @@ describe 'run_command' do 
     | 
|
| 
       10 
10 
     | 
    
         
             
                res.exit_status.must_equal(0)
         
     | 
| 
       11 
11 
     | 
    
         
             
              end
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
      
 13 
     | 
    
         
            +
              it 'can run frozen commands' do
         
     | 
| 
      
 14 
     | 
    
         
            +
                res = backend.run_command('echo hello world'.freeze)
         
     | 
| 
      
 15 
     | 
    
         
            +
                res.stdout.must_equal("hello world\n")
         
     | 
| 
      
 16 
     | 
    
         
            +
                res.stderr.must_equal('')
         
     | 
| 
      
 17 
     | 
    
         
            +
                res.exit_status.must_equal(0)
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
       13 
20 
     | 
    
         
             
              it 'can echo commands to stderr' do
         
     | 
| 
       14 
21 
     | 
    
         
             
                # TODO: Specinfra often fails on this test.
         
     | 
| 
       15 
22 
     | 
    
         
             
                # Fix and re-enable it.
         
     | 
| 
         @@ -270,6 +270,7 @@ describe 'os common plugin' do 
     | 
|
| 
       270 
270 
     | 
    
         
             
                let(:os) { mock_platform('esx') }
         
     | 
| 
       271 
271 
     | 
    
         
             
                it { os.solaris?.must_equal(false) }
         
     | 
| 
       272 
272 
     | 
    
         
             
                it { os.linux?.must_equal(false) }
         
     | 
| 
      
 273 
     | 
    
         
            +
                it {os[:family].must_equal('esx')}
         
     | 
| 
       273 
274 
     | 
    
         
             
                it { os.unix?.must_equal(false) }
         
     | 
| 
       274 
275 
     | 
    
         
             
                it { os.esx?.must_equal(true) }
         
     | 
| 
       275 
276 
     | 
    
         
             
              end
         
     | 
| 
         @@ -46,15 +46,56 @@ describe 'stat' do 
     | 
|
| 
       46 
46 
     | 
    
         | 
| 
       47 
47 
     | 
    
         
             
                it 'ignores wrong stat results' do
         
     | 
| 
       48 
48 
     | 
    
         
             
                  res = Minitest::Mock.new
         
     | 
| 
      
 49 
     | 
    
         
            +
                  os = Minitest::Mock.new
         
     | 
| 
       49 
50 
     | 
    
         
             
                  res.expect :stdout, ''
         
     | 
| 
      
 51 
     | 
    
         
            +
                  os.expect :esx?, false
         
     | 
| 
      
 52 
     | 
    
         
            +
                  backend.expect :os, os
         
     | 
| 
       50 
53 
     | 
    
         
             
                  backend.expect :run_command, res, [String]
         
     | 
| 
       51 
54 
     | 
    
         
             
                  cls.linux_stat('/path', backend, false).must_equal({})
         
     | 
| 
       52 
55 
     | 
    
         
             
                end
         
     | 
| 
       53 
56 
     | 
    
         | 
| 
       54 
57 
     | 
    
         
             
                it 'reads correct stat results' do
         
     | 
| 
       55 
58 
     | 
    
         
             
                  res = Minitest::Mock.new
         
     | 
| 
      
 59 
     | 
    
         
            +
                  os = Minitest::Mock.new
         
     | 
| 
       56 
60 
     | 
    
         
             
                  # 43ff is 41777; linux_stat strips the 4
         
     | 
| 
       57 
61 
     | 
    
         
             
                  res.expect :stdout, "360\n43ff\nroot\n0\nrootz\n1\n1444520846\n1444522445\n?"
         
     | 
| 
      
 62 
     | 
    
         
            +
                  os.expect :esx?, false
         
     | 
| 
      
 63 
     | 
    
         
            +
                  backend.expect :os, os
         
     | 
| 
      
 64 
     | 
    
         
            +
                  backend.expect :run_command, res, [String]
         
     | 
| 
      
 65 
     | 
    
         
            +
                  cls.linux_stat('/path', backend, false).must_equal({
         
     | 
| 
      
 66 
     | 
    
         
            +
                    type: :directory,
         
     | 
| 
      
 67 
     | 
    
         
            +
                    mode: 01777,
         
     | 
| 
      
 68 
     | 
    
         
            +
                    owner: 'root',
         
     | 
| 
      
 69 
     | 
    
         
            +
                    uid: 0,
         
     | 
| 
      
 70 
     | 
    
         
            +
                    group: 'rootz',
         
     | 
| 
      
 71 
     | 
    
         
            +
                    gid: 1,
         
     | 
| 
      
 72 
     | 
    
         
            +
                    mtime: 1444522445,
         
     | 
| 
      
 73 
     | 
    
         
            +
                    size: 360,
         
     | 
| 
      
 74 
     | 
    
         
            +
                    selinux_label: nil,
         
     | 
| 
      
 75 
     | 
    
         
            +
                  })
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
              describe 'esx stat' do
         
     | 
| 
      
 80 
     | 
    
         
            +
                let(:backend) { Minitest::Mock.new }
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                it 'ignores wrong stat results' do
         
     | 
| 
      
 83 
     | 
    
         
            +
                  res = Minitest::Mock.new
         
     | 
| 
      
 84 
     | 
    
         
            +
                  os = Minitest::Mock.new
         
     | 
| 
      
 85 
     | 
    
         
            +
                  res.expect :stdout, ''
         
     | 
| 
      
 86 
     | 
    
         
            +
                  os.expect :esx?, true
         
     | 
| 
      
 87 
     | 
    
         
            +
                  backend.expect :os, os
         
     | 
| 
      
 88 
     | 
    
         
            +
                  backend.expect :run_command, res, [String]
         
     | 
| 
      
 89 
     | 
    
         
            +
                  cls.linux_stat('/path', backend, false).must_equal({})
         
     | 
| 
      
 90 
     | 
    
         
            +
                end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                it 'reads correct stat results' do
         
     | 
| 
      
 93 
     | 
    
         
            +
                  res = Minitest::Mock.new
         
     | 
| 
      
 94 
     | 
    
         
            +
                  os = Minitest::Mock.new
         
     | 
| 
      
 95 
     | 
    
         
            +
                  # 43ff is 41777; linux_stat strips the 4
         
     | 
| 
      
 96 
     | 
    
         
            +
                  res.expect :stdout, "360\n43ff\nroot\n0\nrootz\n1\n1444520846\n1444522445\nC"
         
     | 
| 
      
 97 
     | 
    
         
            +
                  os.expect :esx?, true
         
     | 
| 
      
 98 
     | 
    
         
            +
                  backend.expect :os, os
         
     | 
| 
       58 
99 
     | 
    
         
             
                  backend.expect :run_command, res, [String]
         
     | 
| 
       59 
100 
     | 
    
         
             
                  cls.linux_stat('/path', backend, false).must_equal({
         
     | 
| 
       60 
101 
     | 
    
         
             
                    type: :directory,
         
     | 
| 
         @@ -84,8 +84,15 @@ describe 'mock transport' do 
     | 
|
| 
       84 
84 
     | 
    
         
             
              end
         
     | 
| 
       85 
85 
     | 
    
         | 
| 
       86 
86 
     | 
    
         
             
              describe 'when accessing a mocked file' do
         
     | 
| 
       87 
     | 
    
         
            -
                 
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
      
 87 
     | 
    
         
            +
                JSON = Train.create('local').connection.file(__FILE__).to_json
         
     | 
| 
      
 88 
     | 
    
         
            +
                RES = Train::Transports::Mock::Connection::File.from_json(JSON)
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                # tests if all fields between the local json and resulting mock file
         
     | 
| 
      
 91 
     | 
    
         
            +
                # are equal
         
     | 
| 
      
 92 
     | 
    
         
            +
                %w{ content mode owner group }.each do |f|
         
     | 
| 
      
 93 
     | 
    
         
            +
                  it "can be initialized from json (field #{f})" do
         
     | 
| 
      
 94 
     | 
    
         
            +
                    RES.method(f).call.must_equal JSON[f]
         
     | 
| 
      
 95 
     | 
    
         
            +
                  end
         
     | 
| 
       89 
96 
     | 
    
         
             
                end
         
     | 
| 
       90 
97 
     | 
    
         
             
              end
         
     | 
| 
       91 
98 
     | 
    
         
             
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: train
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.14.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Dominik Richter
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2016-06- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2016-06-27 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: json
         
     | 
| 
         @@ -188,8 +188,10 @@ files: 
     | 
|
| 
       188 
188 
     | 
    
         
             
            - test/integration/sudo/passwd.rb
         
     | 
| 
       189 
189 
     | 
    
         
             
            - test/integration/sudo/reqtty.rb
         
     | 
| 
       190 
190 
     | 
    
         
             
            - test/integration/sudo/run_as.rb
         
     | 
| 
      
 191 
     | 
    
         
            +
            - test/integration/test-one.yaml
         
     | 
| 
       191 
192 
     | 
    
         
             
            - test/integration/test-travis-1.yaml
         
     | 
| 
       192 
193 
     | 
    
         
             
            - test/integration/test-travis-2.yaml
         
     | 
| 
      
 194 
     | 
    
         
            +
            - test/integration/test-two.yaml
         
     | 
| 
       193 
195 
     | 
    
         
             
            - test/integration/test_local.rb
         
     | 
| 
       194 
196 
     | 
    
         
             
            - test/integration/test_ssh.rb
         
     | 
| 
       195 
197 
     | 
    
         
             
            - test/integration/tests/path_block_device_test.rb
         
     | 
| 
         @@ -241,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       241 
243 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       242 
244 
     | 
    
         
             
            requirements: []
         
     | 
| 
       243 
245 
     | 
    
         
             
            rubyforge_project: 
         
     | 
| 
       244 
     | 
    
         
            -
            rubygems_version: 2. 
     | 
| 
      
 246 
     | 
    
         
            +
            rubygems_version: 2.5.1
         
     | 
| 
       245 
247 
     | 
    
         
             
            signing_key: 
         
     | 
| 
       246 
248 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       247 
249 
     | 
    
         
             
            summary: Transport interface to talk to different backends.
         
     | 
| 
         @@ -262,8 +264,10 @@ test_files: 
     | 
|
| 
       262 
264 
     | 
    
         
             
            - test/integration/sudo/passwd.rb
         
     | 
| 
       263 
265 
     | 
    
         
             
            - test/integration/sudo/reqtty.rb
         
     | 
| 
       264 
266 
     | 
    
         
             
            - test/integration/sudo/run_as.rb
         
     | 
| 
      
 267 
     | 
    
         
            +
            - test/integration/test-one.yaml
         
     | 
| 
       265 
268 
     | 
    
         
             
            - test/integration/test-travis-1.yaml
         
     | 
| 
       266 
269 
     | 
    
         
             
            - test/integration/test-travis-2.yaml
         
     | 
| 
      
 270 
     | 
    
         
            +
            - test/integration/test-two.yaml
         
     | 
| 
       267 
271 
     | 
    
         
             
            - test/integration/test_local.rb
         
     | 
| 
       268 
272 
     | 
    
         
             
            - test/integration/test_ssh.rb
         
     | 
| 
       269 
273 
     | 
    
         
             
            - test/integration/tests/path_block_device_test.rb
         
     |