rest-ftp-daemon 0.241 → 0.242.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +7 -7
- data/README.md +50 -37
- data/config.ru +6 -5
- data/lib/rest-ftp-daemon.rb +8 -0
- data/lib/rest-ftp-daemon/constants.rb +3 -2
- data/lib/rest-ftp-daemon/paginate.rb +2 -4
- data/lib/rest-ftp-daemon/views/dashboard_table.haml +8 -7
- data/lib/rest-ftp-daemon/worker_job.rb +12 -3
- data/rest-ftp-daemon.gemspec +3 -0
- data/rest-ftp-daemon.yml.sample +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5fe06b493b45467f188f2bb44abf1c8cc1afea28
|
4
|
+
data.tar.gz: dc2b03120828edc2131efba729df7faf1e042912
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 882dbf325e495f70f89e5a948b144b6646ab4d3c1e37422d8c783fda51c7b24653e419c3b29bb7b2e0b1bc31bb5349b1896fbf30f5eabbfe86c5d81f1739c276
|
7
|
+
data.tar.gz: a9e48d701b53d0d7f43880d2dc401ccdfc18a8048b8b1ab38b17d4b57b7055952c69b18e5c6dbac528e630a0e0fac5379daffa4e6edfb023ecda56336e58b41f
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rest-ftp-daemon (0.
|
4
|
+
rest-ftp-daemon (0.242.0)
|
5
5
|
double-bag-ftps
|
6
6
|
facter
|
7
7
|
get_process_mem
|
@@ -41,7 +41,7 @@ GEM
|
|
41
41
|
descendants_tracker (0.0.4)
|
42
42
|
thread_safe (~> 0.3, >= 0.3.1)
|
43
43
|
diff-lcs (1.2.5)
|
44
|
-
domain_name (0.5.
|
44
|
+
domain_name (0.5.25)
|
45
45
|
unf (>= 0.0.5, < 1.0.0)
|
46
46
|
double-bag-ftps (0.1.2)
|
47
47
|
equalizer (0.0.11)
|
@@ -66,7 +66,7 @@ GEM
|
|
66
66
|
haml (4.0.7)
|
67
67
|
tilt
|
68
68
|
hashie (3.4.2)
|
69
|
-
http (0.9.
|
69
|
+
http (0.9.8)
|
70
70
|
addressable (~> 2.3)
|
71
71
|
http-cookie (~> 1.0)
|
72
72
|
http-form_data (~> 1.0.1)
|
@@ -84,12 +84,12 @@ GEM
|
|
84
84
|
multi_xml (0.5.5)
|
85
85
|
net-sftp (2.1.2)
|
86
86
|
net-ssh (>= 2.6.5)
|
87
|
-
net-ssh (
|
88
|
-
newrelic_rpm (3.
|
89
|
-
parser (2.2.
|
87
|
+
net-ssh (3.0.1)
|
88
|
+
newrelic_rpm (3.14.0.305)
|
89
|
+
parser (2.2.3.0)
|
90
90
|
ast (>= 1.1, < 3.0)
|
91
91
|
powerpack (0.1.1)
|
92
|
-
pry (0.10.
|
92
|
+
pry (0.10.3)
|
93
93
|
coderay (~> 1.1.0)
|
94
94
|
method_source (~> 0.8.1)
|
95
95
|
slop (~> 3.4)
|
data/README.md
CHANGED
@@ -17,42 +17,45 @@ be notified of their completion, watch their status on a dedicated dashboard.
|
|
17
17
|
Features
|
18
18
|
------------------------------------------------------------------------------------
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
*
|
23
|
-
*
|
24
|
-
|
25
|
-
|
26
|
-
*
|
27
|
-
*
|
28
|
-
*
|
29
|
-
*
|
30
|
-
*
|
31
|
-
|
32
|
-
*
|
33
|
-
*
|
34
|
-
*
|
35
|
-
*
|
36
|
-
*
|
37
|
-
*
|
38
|
-
|
39
|
-
*
|
40
|
-
*
|
41
|
-
*
|
42
|
-
|
20
|
+
* System and process features
|
21
|
+
* environment-aware configuration in a YAML file
|
22
|
+
* daemon process is tagged with its name and environment in process lists
|
23
|
+
* global dashboard directly served within the daemon HTTP interface
|
24
|
+
|
25
|
+
|
26
|
+
* File management ans transferts
|
27
|
+
* allow authentication in FTP target in a standard URI-format
|
28
|
+
* static path pointers in configuration to abstract local mounts or remote FTPs (endpoint tokens)
|
29
|
+
* local source path and local/remote target path can use patterns to match multiple files (`/dir/file*.jpg`)
|
30
|
+
* several file transfer protocols supported: FTPs, FTPes, sFTP
|
31
|
+
|
32
|
+
* Job management
|
33
|
+
* highly parrallel job processing using dedicated worker threads with their own context
|
34
|
+
* jobs are taken into account as soon as they are submitted
|
35
|
+
* each job carry its own attributes: build subdirectories (mkdir), overwrite target file, priority weight
|
36
|
+
* dynamic evaluation of priorities, honoring any change on context until the job is picked
|
37
|
+
* automatically clean-up jobs after a configurable amount of time (failed, finished)
|
38
|
+
|
39
|
+
* Realtime status reporting
|
40
|
+
* realtime transfer status reporting, with progress and errors
|
41
|
+
* periodic update notifications sent along with transfer status and progress to an arbitrary URL (JSON resource POSTed)
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
Status
|
46
|
+
------------------------------------------------------------------------------------
|
47
|
+
|
48
|
+
Though it may need more robust tests, this gem has been used successfully in production for
|
49
|
+
a while without glitches at France Télévisions.
|
43
50
|
|
44
51
|
Expected features in a short-time range :
|
45
52
|
|
46
|
-
* Allow fallback file source when first file path is unavailable (failover)
|
47
53
|
* Provide swagger-style API documentation
|
48
54
|
* Authenticate API clients
|
49
55
|
* Allow more transfer protocols (sFTP, HTTP POST etc)
|
56
|
+
* Expose JSON status of workers on `GET /jobs/` for automated monitoring
|
50
57
|
|
51
|
-
Status
|
52
|
-
------------------------------------------------------------------------------------
|
53
58
|
|
54
|
-
Though lacking testing, this gem has been used successfully in production for
|
55
|
-
a while without glitches.
|
56
59
|
|
57
60
|
|
58
61
|
Installation
|
@@ -176,19 +179,21 @@ Default administrator credentials are `admin/admin`. Please change the password
|
|
176
179
|
Logging
|
177
180
|
------------------------------------------------------------------------------------
|
178
181
|
|
179
|
-
The application will
|
180
|
-
|
182
|
+
The application will log to paths specified in the configuration file, if any.
|
183
|
+
Separate logging paths can be provided for the Thin webserver, API related messages, and workers related messages.
|
184
|
+
Providing empty values as paths, will simply activate logging to `STDOUT`.
|
181
185
|
|
182
186
|
|
183
187
|
Job cleanup
|
184
188
|
------------------------------------------------------------------------------------
|
185
189
|
|
186
|
-
Job can be cleanup
|
190
|
+
Job queue can be set to automatically cleanup after a certain delay. Entries are removed from the queue when they have been idle (updated_at) for more than X seconds, and in any of the following statuses:
|
187
191
|
|
188
|
-
-
|
189
|
-
-
|
192
|
+
- failed (conchita.clean_failed)
|
193
|
+
- finished (conchita.clean_finished)
|
194
|
+
- queued, (conchita.clean_queued)
|
190
195
|
|
191
|
-
Cleanup is done on a regular basis, every
|
196
|
+
Cleanup is done on a regular basis, every (conchita.timer) seconds.
|
192
197
|
|
193
198
|
|
194
199
|
TODO for this document
|
@@ -200,7 +205,6 @@ TODO for this document
|
|
200
205
|
* Update Apiary documentation !
|
201
206
|
* Document /status
|
202
207
|
* Document /routes
|
203
|
-
* Document multiple-files upload
|
204
208
|
* Document mkdir and overwrite options
|
205
209
|
* Document counters
|
206
210
|
|
@@ -253,6 +257,12 @@ Known bugs
|
|
253
257
|
|
254
258
|
* As this project is based on SettingsLogic, which in turns uses Syck YAML parser, configuration merge from "defaults" section and environment-specific section is broken. A sub-tree defined for a specific environment, will overwrite the corresponding subtree from "defaults".
|
255
259
|
|
260
|
+
* If you get ```fatal error: 'openssl/ssl.h' file not found when installing ```eventmachine``` on OSX El Capitan, you can try with:
|
261
|
+
```
|
262
|
+
gem install eventmachine -v '1.0.8' -- --with-cppflags=-I/usr/local/opt/openssl/include
|
263
|
+
bundle install
|
264
|
+
```
|
265
|
+
|
256
266
|
|
257
267
|
Contributing
|
258
268
|
------------------------------------------------------------------------------------
|
@@ -293,5 +303,8 @@ About
|
|
293
303
|
|
294
304
|
Thanks to https://github.com/berkshelf/berkshelf-api for parts and ideas used in this project
|
295
305
|
|
296
|
-
|
297
|
-
http://bmconseil.com/
|
306
|
+
This project has been initiated and originally written by
|
307
|
+
Bruno MEDICI Consultant (http://bmconseil.com/)
|
308
|
+
|
309
|
+
|
310
|
+
|
data/config.ru
CHANGED
@@ -9,11 +9,6 @@ $queue = RestFtpDaemon::JobQueue.new
|
|
9
9
|
# Initialize workers and conchita subsystem
|
10
10
|
$pool = RestFtpDaemon::WorkerPool.new
|
11
11
|
|
12
|
-
# Rack reloader
|
13
|
-
unless Settings.namespace == "production"
|
14
|
-
use Rack::Reloader, 0
|
15
|
-
end
|
16
|
-
|
17
12
|
# Rack authent
|
18
13
|
unless Settings.adminpwd.nil?
|
19
14
|
use Rack::Auth::Basic, "Restricted Area" do |username, password|
|
@@ -27,6 +22,12 @@ GC::Profiler.enable if Settings.newrelic_enabled?
|
|
27
22
|
# Serve static assets
|
28
23
|
use Rack::Static, :urls => ["/css", "/js", "/images"], :root => "#{APP_LIBS}/static/"
|
29
24
|
|
25
|
+
# Rack reloader and mini-profiler
|
26
|
+
unless Settings.namespace == "production"
|
27
|
+
use Rack::Reloader, 0
|
28
|
+
# use Rack::MiniProfiler
|
29
|
+
end
|
30
|
+
|
30
31
|
# Launch the main daemon
|
31
32
|
run RestFtpDaemon::API::Root
|
32
33
|
#run Rack::Cascade.new [RestFtpDaemon::API::Root]
|
data/lib/rest-ftp-daemon.rb
CHANGED
@@ -10,6 +10,14 @@ require "singleton"
|
|
10
10
|
require "newrelic_rpm"
|
11
11
|
|
12
12
|
|
13
|
+
# Development libs /?pp=flamegraph
|
14
|
+
# unless Settings.namespace == "production"
|
15
|
+
# require 'rack-mini-profiler'
|
16
|
+
# # require 'stackprof'
|
17
|
+
# require 'flamegraph'
|
18
|
+
# end
|
19
|
+
|
20
|
+
|
13
21
|
# Project's libs
|
14
22
|
require_relative "rest-ftp-daemon/constants"
|
15
23
|
require_relative "rest-ftp-daemon/settings"
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Terrific constants
|
2
2
|
APP_NAME = "rest-ftp-daemon"
|
3
3
|
APP_NICK = "rftpd"
|
4
|
-
APP_VER = "0.
|
4
|
+
APP_VER = "0.242.0"
|
5
5
|
|
6
6
|
# Provide default config file information
|
7
7
|
APP_LIB = File.expand_path File.dirname(__FILE__)
|
@@ -91,7 +91,8 @@ DASHBOARD_WORKER_STYLES = {
|
|
91
91
|
DEFAULT_WORKER_TIMEOUT = 3600
|
92
92
|
DEFAULT_FTP_CHUNK = 1024
|
93
93
|
DEFAULT_PAGE_SIZE = 40
|
94
|
-
DEFAULT_WORKERS =
|
94
|
+
DEFAULT_WORKERS = 2
|
95
|
+
DEFAULT_RETRY_DELAY = 10
|
95
96
|
|
96
97
|
DEFAULT_SFTP_TIMEOUT = 30
|
97
98
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module RestFtpDaemon
|
2
2
|
class Paginate
|
3
3
|
|
4
|
+
attr_writer :only
|
5
|
+
|
4
6
|
def initialize data
|
5
7
|
# Defaults
|
6
8
|
@pages = 0
|
@@ -22,10 +24,6 @@ module RestFtpDaemon
|
|
22
24
|
@pages = 1 if @pages < 1
|
23
25
|
end
|
24
26
|
|
25
|
-
def only= raw_only
|
26
|
-
@only = raw_only
|
27
|
-
end
|
28
|
-
|
29
27
|
def page= raw_page
|
30
28
|
@page = [1, raw_page.to_i, @pages].sort[1]
|
31
29
|
end
|
@@ -13,14 +13,9 @@
|
|
13
13
|
|
14
14
|
%tr{class: trclass.to_s}
|
15
15
|
%td
|
16
|
-
|
17
|
-
|
18
16
|
%a{href: Helpers.dashboard_job_link(job)}
|
19
17
|
%b= job.id
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
19
|
%td= job.label
|
25
20
|
|
26
21
|
%td{title: job.get(:source_path)}
|
@@ -78,8 +73,14 @@
|
|
78
73
|
.label.label-default.flag.worker-label= job.priority
|
79
74
|
|
80
75
|
%td
|
81
|
-
-
|
82
|
-
.label.label-info.flag.worker-label=
|
76
|
+
- if job.runs.nil?
|
77
|
+
.label.label-info.flag.worker-label= "-"
|
78
|
+
- elsif job.runs == 1
|
79
|
+
.label.label-default.flag.worker-label= job.runs
|
80
|
+
- elsif job.runs == 2
|
81
|
+
.label.label-warning.flag.worker-label= job.runs
|
82
|
+
- elsif job.runs > 2
|
83
|
+
.label.label-danger.flag.worker-label= job.runs
|
83
84
|
|
84
85
|
-#%td
|
85
86
|
- unless job.priority.nil?
|
@@ -31,6 +31,7 @@ module RestFtpDaemon
|
|
31
31
|
on_errors = Settings.at(:retry, :on_errors)
|
32
32
|
max_age = Settings.at(:retry, :max_age)
|
33
33
|
max_runs = Settings.at(:retry, :max_runs)
|
34
|
+
delay = Settings.at(:retry, :delay)
|
34
35
|
|
35
36
|
if !job.error
|
36
37
|
#log_info "job succeeded"
|
@@ -39,13 +40,21 @@ module RestFtpDaemon
|
|
39
40
|
log_error "not retrying: error not eligible"
|
40
41
|
|
41
42
|
elsif max_age && (job.age >= max_age)
|
42
|
-
log_error "not retrying:
|
43
|
+
log_error "not retrying: max_age reached (#{max_age} s)"
|
43
44
|
|
44
45
|
elsif max_runs && (job.runs >= max_runs)
|
45
|
-
log_error "not retrying:
|
46
|
+
log_error "not retrying: max_runs reached (#{max_runs} tentatives)"
|
46
47
|
|
47
48
|
else
|
48
|
-
|
49
|
+
# Delay cannot be negative, and will be 1s minimum
|
50
|
+
retry_after = [delay || DEFAULT_RETRY_DELAY, 1].max
|
51
|
+
log_info "retrying job: waiting for #{retry_after} seconds"
|
52
|
+
|
53
|
+
# Wait !
|
54
|
+
sleep retry_after
|
55
|
+
log_info "retrying job: requeued after delay"
|
56
|
+
|
57
|
+
# Now, requeue this job
|
49
58
|
$queue.requeue job
|
50
59
|
end
|
51
60
|
|
data/rest-ftp-daemon.gemspec
CHANGED
@@ -32,6 +32,9 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.add_development_dependency "http", "~> 0.8"
|
33
33
|
spec.add_development_dependency "rubocop", "~> 0.32.0"
|
34
34
|
spec.add_development_dependency "pry"
|
35
|
+
# spec.add_development_dependency "rack-mini-profiler"
|
36
|
+
# spec.add_development_dependency "stackprof"
|
37
|
+
# spec.add_development_dependency "flamegraph"
|
35
38
|
|
36
39
|
spec.add_runtime_dependency "thin", "~> 1.6"
|
37
40
|
spec.add_runtime_dependency "grape"
|
data/rest-ftp-daemon.yml.sample
CHANGED
@@ -17,6 +17,7 @@ defaults: &defaults
|
|
17
17
|
# on_errors: ["net_temp_error", "conn_reset_by_peer", "conn_timed_out", "conn_refused", "sftp_auth_failed", "conn_host_is_down", "conn_unreachable", "conn_failed", "conn_openssl_error"]
|
18
18
|
# max_runs: 5
|
19
19
|
# max_age: 1800
|
20
|
+
# delay: 10
|
20
21
|
|
21
22
|
conchita:
|
22
23
|
# timer: 60
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest-ftp-daemon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.242.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bruno MEDICI
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|