Skip to content

Commit ddd337e

Browse files
authored
Merge pull request #477 from tidewise/machine-name-arg
feat: rename yml file before transferring (on top of #467)
2 parents dfe9a3e + cceb093 commit ddd337e

File tree

6 files changed

+132
-58
lines changed

6 files changed

+132
-58
lines changed

lib/syskit/cli/log_runtime_archive.rb

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ class LogRuntimeArchive
3030
# to the ftp server @see process_root_folder_transfer
3131
# @param [Logger] logger the log structure
3232
def initialize(
33-
root_dir, target_dir: nil,
34-
logger: LogRuntimeArchive.null_logger
33+
root_dir,
34+
target_dir: nil, logger: LogRuntimeArchive.null_logger
3535
)
3636
@last_archive_index = {}
3737
@logger = logger
@@ -44,12 +44,13 @@ def initialize(
4444
#
4545
# @param [Params] server_params the FTP server parameters
4646
# @return [Array<TransferDatasetResult>]
47-
def process_root_folder_transfer(server_params)
47+
def process_root_folder_transfer(server_params, info_name: "info")
4848
candidates = self.class.find_all_dataset_folders(@root_dir)
4949
candidates.map do |child|
5050
process_dataset_transfer(
5151
child, server_params, @root_dir,
52-
full: !Roby::Application.log_dir_locked?(child.basename)
52+
full: !Roby::Application.log_dir_locked?(child.basename),
53+
info_name: info_name
5354
)
5455
end
5556
end
@@ -147,9 +148,10 @@ def process_dataset(child, full:, max_archive_size: DEFAULT_MAX_ARCHIVE_SIZE)
147148
end
148149
end
149150

150-
def process_dataset_transfer(child, server, root, full:)
151+
def process_dataset_transfer(child, server, root, full:, info_name: "info")
151152
self.class.transfer_dataset(
152-
child, server, root, full: full, logger: @logger
153+
child, server, root,
154+
full: full, logger: @logger, info_name: info_name
153155
)
154156
end
155157

@@ -166,36 +168,74 @@ def failures
166168
end
167169

168170
# Transfer the given dataset
169-
def self.transfer_dataset(
171+
def self.transfer_dataset( # rubocop:disable Metrics/ParameterLists
170172
dataset_path, server, root,
171-
full:, logger: null_logger
173+
full:, info_name: "info", logger: null_logger
172174
)
173175
logger.info(
174176
"Transfering dataset #{dataset_path} in " \
175177
"#{full ? 'full' : 'partial'} mode"
176178
)
179+
complete, paths_to_transfer =
180+
transfer_compute_paths(dataset_path, full, info_name)
181+
182+
transfer_results = paths_to_transfer.map do |source_path, target_name|
183+
result =
184+
transfer_file(source_path, server, root, target_name: target_name)
185+
source_path.unlink if result.success?
186+
187+
result
188+
end
189+
190+
result = TransferDatasetResult.new(
191+
complete: complete, transfer_results: transfer_results
192+
)
193+
log_transfer_results(dataset_path, result, logger: logger)
194+
end
195+
196+
# @api private
197+
#
198+
# Compute paths to the files that should be transferred in a given dataset dir
199+
#
200+
# @param [Pathname] dataset_path the path to the dataset dir
201+
# @param [Boolean] full if the transfer should be in full mode (all files
202+
# are transferred) or partial mode (only already rotated pocolog files
203+
# are transferred)
204+
# @param [String] info_name name that should be given to the `info.yml`
205+
# file on the target machine
206+
# @return [(Boolean,Array<Pathname>)] the boolean indicates whether this pass
207+
# is complete or not. The caller should call transfer_dataset until
208+
# the flag is true. The array is the list of paths to be transferred
209+
# in this pass
210+
def self.transfer_compute_paths(dataset_path, full, info_name)
177211
candidates =
178212
each_file_from_path(dataset_path)
179213
.reject { |p| p.extname == ".partial" }
180214

181-
complete, candidates =
215+
complete, paths_to_transfer =
182216
if full
183217
archive_filter_candidates_full(candidates)
184218
else
185219
archive_filter_candidates_partial(candidates)
186220
end
187221

188-
transfer_results = candidates.map do |child_path|
189-
result = transfer_file(child_path, server, root)
190-
child_path.unlink if result.success?
222+
paths_to_transfer =
223+
transfer_compute_remote_names(paths_to_transfer, info_name)
191224

192-
result
193-
end
225+
[complete, paths_to_transfer]
226+
end
194227

195-
result = TransferDatasetResult.new(
196-
complete: complete, transfer_results: transfer_results
197-
)
198-
log_transfer_results(dataset_path, result, logger: logger)
228+
# Renames the info.yml file
229+
def self.transfer_compute_remote_names(paths, info_name)
230+
paths.map do |p|
231+
basename = p.basename.to_s
232+
233+
if basename == "info.yml"
234+
[p, "#{info_name}.yml"]
235+
else
236+
[p, basename]
237+
end
238+
end
199239
end
200240

201241
# Logs the transfer dataset results
@@ -232,10 +272,11 @@ def self.log_transfer_results(dataset_path, result, logger: null_logger)
232272
# Transfer a file to the central log server via FTP
233273
#
234274
# @return [LogUploadState:Result]
235-
def self.transfer_file(file, server, root)
275+
def self.transfer_file(file, server, root, target_name: File.basename(file))
236276
ftp = RobyApp::LogTransferServer::FTPUpload.new(
237277
server.host, server.port, server.certificate, server.user,
238278
server.password, file,
279+
target_name: target_name,
239280
max_upload_rate: server.max_upload_rate || Float::INFINITY,
240281
implicit_ftps: server.implicit_ftps
241282
)

lib/syskit/cli/log_runtime_archive_main.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ def archive(root_dir, target_dir)
7676
type: :boolean, default: false,
7777
desc: "use implicit connection method for ftps " \
7878
"(disable for 2.5 clients on 2.7 servers)"
79+
option :info_name,
80+
type: :string, default: "info",
81+
desc: "basename (without extension) under which the info.yml " \
82+
"metadata file should be uploaded. Use for instance the " \
83+
"machine name"
7984
def watch_transfer( # rubocop:disable Metrics/ParameterLists
8085
source_dir, host, port, certificate_path, user, password
8186
)
@@ -100,6 +105,11 @@ def watch_transfer( # rubocop:disable Metrics/ParameterLists
100105
type: :boolean, default: false,
101106
desc: "use implicit connection method for ftps " \
102107
"(disable for 2.5 clients on 2.7 servers)"
108+
option :info_name,
109+
type: :string, default: "info",
110+
desc: "basename (without extension) under which the info.yml " \
111+
"metadata file should be uploaded. Use for instance the " \
112+
"machine name"
103113
def transfer( # rubocop:disable Metrics/ParameterLists
104114
source_dir, host, port, certificate_path, user, password
105115
)
@@ -112,7 +122,9 @@ def transfer( # rubocop:disable Metrics/ParameterLists
112122
implicit_ftps: options[:implicit_ftps],
113123
max_upload_rate: rate_mbps_to_bps(options[:max_upload_rate_mbps])
114124
)
115-
archiver.process_root_folder_transfer(server_params)
125+
archiver.process_root_folder_transfer(
126+
server_params, info_name: options[:info_name]
127+
)
116128
end
117129

118130
desc "transfer_server TARGET_DIR HOST PORT CERTFILE_PATH USER PASSWORD",

lib/syskit/roby_app/log_transfer_server/ftp_upload.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ class FTPUpload
1010
def initialize( # rubocop:disable Metrics/ParameterLists
1111
host, port, certificate, user, password, file,
1212
max_upload_rate: Float::INFINITY,
13-
implicit_ftps: false
13+
implicit_ftps: false,
14+
target_name: File.basename(file)
1415
)
1516

1617
@host = host
@@ -19,6 +20,7 @@ def initialize( # rubocop:disable Metrics/ParameterLists
1920
@user = user
2021
@password = password
2122
@file = file
23+
@target_name = target_name
2224

2325
@max_upload_rate = Float(max_upload_rate)
2426
if @max_upload_rate <= 0
@@ -89,17 +91,16 @@ def transfer(ftp, root)
8991
last = Time.now
9092
chdir_to_file_directory(ftp, root) if root
9193

92-
target_name = File.basename(@file)
9394
File.open(@file) do |file_io|
94-
ftp.storbinary("STOR #{target_name}.partial",
95+
ftp.storbinary("STOR #{@target_name}.partial",
9596
file_io, Net::FTP::DEFAULT_BLOCKSIZE) do |buf|
9697
now = Time.now
9798
rate_limit(buf.size, now, last)
9899
last = Time.now
99100
end
100101
end
101102

102-
ftp.rename("#{target_name}.partial", target_name)
103+
ftp.rename("#{@target_name}.partial", @target_name)
103104
end
104105

105106
# @api private

test/cli/test_log_runtime_archive.rb

Lines changed: 50 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -666,44 +666,63 @@ def create_server(params)
666666
end
667667

668668
describe ".transfer_dataset" do
669-
before do
670-
@dataset = make_valid_folder("PATH")
671-
make_random_file "test.0.log", root: @dataset
672-
end
669+
describe "transfer of normal files" do
670+
before do
671+
@dataset = make_valid_folder("PATH")
672+
make_random_file "test.0.log", root: @dataset
673+
end
673674

674-
it "transfers a dataset through FTP" do
675-
results = LogRuntimeArchive.transfer_dataset(
676-
@dataset, @params, @root, full: true
677-
)
675+
it "transfers a dataset through FTP" do
676+
results = LogRuntimeArchive.transfer_dataset(
677+
@dataset, @params, @root, full: true
678+
)
678679

679-
assert results.success?
680-
# Datasets that have pocolog files are not complete
681-
refute results.complete
682-
assert(File.exist?(@target_dir / "PATH" / "test.0.log"))
683-
end
680+
assert results.success?
681+
# Datasets that have pocolog files are not complete
682+
refute results.complete
683+
assert(File.exist?(@target_dir / "PATH" / "test.0.log"))
684+
end
684685

685-
it "removes the source file if the transfer was successful" do
686-
results = LogRuntimeArchive.transfer_dataset(
687-
@dataset, @params, @root, full: true
688-
)
686+
it "removes the source file if the transfer was successful" do
687+
results = LogRuntimeArchive.transfer_dataset(
688+
@dataset, @params, @root, full: true
689+
)
690+
691+
assert results.success?
692+
refute((@dataset / "test.0.log").exist?)
693+
end
689694

690-
assert results.success?
691-
refute((@dataset / "test.0.log").exist?)
695+
it "does not remove the source file if the transfer failed" do
696+
result = RobyApp::LogTransferServer::LogUploadState::Result
697+
.new("/PATH", false, "message")
698+
flexmock(LogRuntimeArchive)
699+
.should_receive(:transfer_file)
700+
.and_return(result)
701+
results = LogRuntimeArchive.transfer_dataset(
702+
@dataset, @params, @root, full: true
703+
)
704+
705+
refute results.success?
706+
assert((@dataset / "test.0.log").exist?)
707+
end
692708
end
693709

694-
it "does not remove the source file if the transfer failed" do
695-
result = RobyApp::LogTransferServer::LogUploadState::Result.new(
696-
"/PATH", false, "message"
697-
)
698-
flexmock(LogRuntimeArchive)
699-
.should_receive(:transfer_file)
700-
.and_return(result)
701-
results = LogRuntimeArchive.transfer_dataset(
702-
@dataset, @params, @root, full: true
703-
)
710+
describe "transfer of the info.yml file" do
711+
before do
712+
@dataset = make_valid_folder("PATH")
713+
@info_yml_content = make_random_file "info.yml",
714+
root: @dataset
715+
end
704716

705-
refute results.success?
706-
assert((@dataset / "test.0.log").exist?)
717+
it "renames info.yml during on the remote machine" do
718+
results = LogRuntimeArchive.transfer_dataset(
719+
@dataset, @params, @root, full: true, info_name: "test"
720+
)
721+
assert results.success?
722+
723+
expected_path = @target_dir / "PATH" / "test.yml"
724+
assert_equal @info_yml_content, expected_path.read
725+
end
707726
end
708727
end
709728

test/cli/test_log_runtime_archive_main.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ def call_archive(root_path, archive_path, low_limit, freed_limit)
186186
flexmock(LogRuntimeArchive)
187187
.new_instances
188188
.should_receive(:process_root_folder_transfer)
189-
.with(ftp_params)
189+
.with(ftp_params, info_name: "something")
190190
.and_raise(quit)
191191

192192
assert_raises(quit) do
@@ -197,7 +197,8 @@ def call_archive(root_path, archive_path, low_limit, freed_limit)
197197
"user", "password",
198198
"--period", 0.5,
199199
"--max_upload_rate_mbps", 10,
200-
"--implicit-ftps"]
200+
"--implicit-ftps",
201+
"--info-name", "something"]
201202
)
202203
end
203204
end

test/process_managers/test_remote.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ def wait_for_upload_completion(poll_period: 0.01, timeout: 1)
528528
end
529529

530530
state = client.log_upload_state
531-
return state if state.pending_count == 0
531+
return state if state.each_result.first
532532

533533
sleep poll_period
534534
end

0 commit comments

Comments
 (0)