Class: RestFtpDaemon::RemoteSFTP

Inherits:
Remote
  • Object
show all
Defined in:
lib/rest-ftp-daemon/remote_sftp.rb

Overview

Handles sFTP transfers for Remote class

Instance Attribute Summary collapse

Attributes inherited from Remote

#log_context, #logger

Instance Method Summary collapse

Constructor Details

#initialize(url, log_context, options = {}) ⇒ RemoteSFTP

Returns a new instance of RemoteSFTP.



8
9
10
11
12
13
14
15
16
17
# File 'lib/rest-ftp-daemon/remote_sftp.rb', line 8

def initialize url, log_context, options = {}
  # Call super
  super

  # Use debug ?
  @debug = (Settings.at :debug, :sftp) == true

  # Announce object
  log_info "RemoteSFTP.initialize"
end

Instance Attribute Details

#sftpObject (readonly)

Returns the value of attribute sftp.



6
7
8
# File 'lib/rest-ftp-daemon/remote_sftp.rb', line 6

def sftp
  @sftp
end

Instance Method Details

#chdir_or_create(directory, mkdir = false) ⇒ Object

Raises:

  • (JobTargetShouldBeDirectory)


70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/rest-ftp-daemon/remote_sftp.rb', line 70

def chdir_or_create directory, mkdir = false
  # Init, extract my parent name and my own name
  log_info "RemoteSFTP.chdir_or_create mkdir[#{mkdir}] dir[#{directory}]"
  parent, _current = Helpers.extract_parent(directory)

  # Access this directory
  begin
    # log_info "   chdir [/#{directory}]"
    @sftp.opendir! "./#{directory}"

  rescue Net::SFTP::StatusException => _e
    # If not allowed to create path, that's over, we're stuck
    return false unless mkdir

    # Recurse upward
    chdir_or_create parent, mkdir

    # Now I was able to chdir into my parent, create the current directory
    mkdir directory

    # Finally retry the chdir
    retry
  else
    return true
  end

  # We should never get here
  raise JobTargetShouldBeDirectory
end

#closeObject



154
155
156
157
158
159
# File 'lib/rest-ftp-daemon/remote_sftp.rb', line 154

def close
  # Close init
  super

  # @sftp.close
end

#connectObject



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/rest-ftp-daemon/remote_sftp.rb', line 19

def connect
  # Connect init
  super
  log_info "RemoteSFTP.connect [#{@url.user}]@[#{@url.host}]:[#{@url.port}]"

  # Debug level
  verbosity = @debug ? Logger::INFO : false

  # Connect remote server
  @sftp = Net::SFTP.start(@url.host.to_s, @url.user.to_s,
      password: @url.password.to_s,
      verbose: verbosity,
      port: @url.port,
      non_interactive: true,
      timeout: DEFAULT_SFTP_TIMEOUT
      )
end

#connected?Boolean

Returns:

  • (Boolean)


161
162
163
# File 'lib/rest-ftp-daemon/remote_sftp.rb', line 161

def connected?
  @sftp && !@sftp.closed?
end

#mkdir(directory) ⇒ Object



62
63
64
65
66
67
68
# File 'lib/rest-ftp-daemon/remote_sftp.rb', line 62

def mkdir directory
  log_info "RemoteSFTP.mkdir [#{directory}]"
  @sftp.mkdir! directory

  rescue
    raise JobTargetPermissionError
end

#present?(target) ⇒ Boolean

Returns:

  • (Boolean)


37
38
39
40
41
42
43
44
45
# File 'lib/rest-ftp-daemon/remote_sftp.rb', line 37

def present? target
  log_info "RemoteSFTP.present? [#{target.name}]"
  stat = @sftp.stat! target.full

rescue Net::SFTP::StatusException
  return false
else
  return stat.size
end

#push(source, target, tempname = nil, &callback) ⇒ Object

def dir_contents directory

# Access this directory
handle = @sftp.opendir! directory
@sftp.readdir! handle

end



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/rest-ftp-daemon/remote_sftp.rb', line 106

def push source, target, tempname = nil, &callback
  # Push init
  raise RestFtpDaemon::JobAssertionFailed, "push/1" if @sftp.nil?

  # Temp file if provided
  destination = target.clone
  destination.name = tempname if tempname

  # Do the transfer
  log_info "RemoteSFTP.push [#{destination.full}]"
  @sftp.upload! source.full, destination.full do |event, _uploader, *args|
    case event
    when :open then
      # args[0] : file metadata
    when :put then
      # args[0] : file metadata
      # args[1] : byte offset in remote file
      # args[2] : data being written (as string)
      # puts "writing #{args[2].length} bytes to #{args[0].remote} starting at #{args[1]}"

      # Update the worker activity marker
      # FIXME: worker_is_still_active

      # Update job status after this block transfer
      yield args[2].length, destination.name

    when :close then
      # args[0] : file metadata
    when :mkdir
      # args[0] : remote path name
    when :finish
    end

  end

  # flags = 0x0001 + 0x0002
  flags = 0x00000001

  # Rename if needed
  if tempname
    log_info "RemoteSFTP.push rename to\t[#{target.name}]"
    @sftp.rename! destination.full, target.full, flags
  end

  # progress:
  # Net::SFTP::StatusException
end

#remove!(target) ⇒ Object

def remove target

log_info "RemoteSFTP.remove [#{target.name}]"
@sftp.remove target.full

end



52
53
54
55
56
57
58
59
60
# File 'lib/rest-ftp-daemon/remote_sftp.rb', line 52

def remove! target
  log_info "RemoteSFTP.remove! [#{target.name}]"
  @sftp.remove target.full

rescue Net::SFTP::StatusException
  log_info "#{LOG_INDENT}[#{target.name}] file not found"
else
  log_info "#{LOG_INDENT}[#{target.name}] removed"
end