Module: Aspera::Cli::SyncActions
- Included in:
- Plugins::Config, Plugins::Node, Plugins::Server
- Defined in:
- lib/aspera/cli/sync_actions.rb
Overview
Helpers shared by plugins that expose Aspera Sync (async) operations. Provides DSL registration, argument-to-sync-info conversion, and action methods.
Constant Summary collapse
- STATE_STR =
Translate state id (int) to string
(['Nil'] + (1..18).map { |i| "P(#{i})" } + %w[Syncd Error Confl Pconf] + (23..24).map { |i| "P(#{i})" }).freeze
- PATH_AND_INFO_ARGS =
Positional arguments shared by sync transfer commands (push/pull/bidi) and sync admin commands.
[{name: :path, type: String}, {name: :sync_info, type: Hash, mandatory: false, default: {}}].freeze
- ADMIN_COMMANDS =
Names of the leaf commands registered under any
sync adminnode. %i[find status meta counters file_info overview query].freeze
Class Method Summary collapse
- .included(base) ⇒ Object
-
.register_sync_admin_commands(base, admin_path) ⇒ Object
DSL helper: register the 7
sync adminleaf commands under the given parent path.
Instance Method Summary collapse
- #action_sync_admin_counters(path:, sync_info: {}) ⇒ Object
- #action_sync_admin_file_info(path:, sync_info: {}) ⇒ Object
- #action_sync_admin_find(path:) ⇒ Object
- #action_sync_admin_meta(path:, sync_info: {}) ⇒ Object
- #action_sync_admin_overview(path:, sync_info: {}) ⇒ Object
- #action_sync_admin_query(path:, sync_info: {}) ⇒ Object
- #action_sync_admin_status(path:, sync_info: {}) ⇒ Object
-
#async_info_from_args(path:, sync_info: {}, direction: nil) ⇒ Hash
Convert path + sync_info to internal
sync_infoformat. -
#db_from_args(path:, sync_info: {}) ⇒ Object
Provide database object from path + sync_info for admin ops.
-
#run_sync_transfer(direction, path:, sync_info: {}, &block) ⇒ Object
Execute a sync transfer for a given direction.
Class Method Details
.included(base) ⇒ Object
25 26 27 |
# File 'lib/aspera/cli/sync_actions.rb', line 25 def included(base) base.option(:sql, description: 'SQL suffix appended to sqlite3 queries for admin subcommands (e.g. WHERE clause)') end |
.register_sync_admin_commands(base, admin_path) ⇒ Object
DSL helper: register the 7 sync admin leaf commands under the given parent path.
Called at class-load time from any plugin that includes SyncActions.
33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/aspera/cli/sync_actions.rb', line 33 def register_sync_admin_commands(base, admin_path) base.commands_under(admin_path) do base.command(:find, description: 'Find sync database files', arguments: [{name: :path, type: String}], action: :action_sync_admin_find) base.command(:status, description: 'Show sync session status', arguments: PATH_AND_INFO_ARGS, action: :action_sync_admin_status) base.command(:meta, description: 'Show sync session metadata', arguments: PATH_AND_INFO_ARGS, action: :action_sync_admin_meta) base.command(:counters, description: 'Show sync counters', arguments: PATH_AND_INFO_ARGS, action: :action_sync_admin_counters) base.command(:file_info, description: 'Show per-file sync state', arguments: PATH_AND_INFO_ARGS, action: :action_sync_admin_file_info) base.command(:overview, description: 'Show sync database overview', arguments: PATH_AND_INFO_ARGS, action: :action_sync_admin_overview) base.command(:query, description: 'Execute a raw SQL query', arguments: PATH_AND_INFO_ARGS, action: :action_sync_admin_query) end end |
Instance Method Details
#action_sync_admin_counters(path:, sync_info: {}) ⇒ Object
136 137 138 139 |
# File 'lib/aspera/cli/sync_actions.rb', line 136 def action_sync_admin_counters(path:, sync_info: {}, **) require 'aspera/sync/database' Result::SingleObject.new(db_from_args(path: path, sync_info: sync_info).counters(.get_option(:sql))) end |
#action_sync_admin_file_info(path:, sync_info: {}) ⇒ Object
141 142 143 144 145 146 147 148 |
# File 'lib/aspera/cli/sync_actions.rb', line 141 def action_sync_admin_file_info(path:, sync_info: {}, **) require 'aspera/sync/database' result = db_from_args(path: path, sync_info: sync_info).file_info(.get_option(:sql)) result.each do |r| r['sstate'] = SyncActions::STATE_STR[r['state']] if r['state'] end Result::ObjectList.new(result, fields: %w[sstate record_id f_meta_path message]) end |
#action_sync_admin_find(path:) ⇒ Object
126 127 128 129 |
# File 'lib/aspera/cli/sync_actions.rb', line 126 def action_sync_admin_find(path:, **) dbs = Sync::Operations.list_db_files(path) Result::ObjectList.new(dbs.keys.map { |n| {name: n, path: dbs[n]} }) end |
#action_sync_admin_meta(path:, sync_info: {}) ⇒ Object
131 132 133 134 |
# File 'lib/aspera/cli/sync_actions.rb', line 131 def (path:, sync_info: {}, **) require 'aspera/sync/database' Result::SingleObject.new(db_from_args(path: path, sync_info: sync_info).(.get_option(:sql))) end |
#action_sync_admin_overview(path:, sync_info: {}) ⇒ Object
150 151 152 153 |
# File 'lib/aspera/cli/sync_actions.rb', line 150 def action_sync_admin_overview(path:, sync_info: {}, **) require 'aspera/sync/database' Result::ObjectList.new(db_from_args(path: path, sync_info: sync_info).overview, fields: %w[table name type]) end |
#action_sync_admin_query(path:, sync_info: {}) ⇒ Object
155 156 157 158 |
# File 'lib/aspera/cli/sync_actions.rb', line 155 def action_sync_admin_query(path:, sync_info: {}, **) require 'aspera/sync/database' Result.auto(db_from_args(path: path, sync_info: sync_info).execute(.get_option(:sql, mandatory: true))) end |
#action_sync_admin_status(path:, sync_info: {}) ⇒ Object
122 123 124 |
# File 'lib/aspera/cli/sync_actions.rb', line 122 def action_sync_admin_status(path:, sync_info: {}, **) Result::SingleObject.new(Sync::Operations.admin_status(async_info_from_args(path: path, sync_info: sync_info))) end |
#async_info_from_args(path:, sync_info: {}, direction: nil) ⇒ Hash
Convert path + sync_info to internal sync_info format.
The resulting sync_info has args format only if it contains one of the sessions or instance keys.
It has the conf format (default) otherwise.
If the conf format is detected, then both local and remote keys are set.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 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 99 100 101 102 103 104 |
# File 'lib/aspera/cli/sync_actions.rb', line 54 def async_info_from_args(path:, sync_info: {}, direction: nil) # is the positional path a remote path ? path_is_remote = direction.eql?(:pull) if sync_info.key?('sessions') || sync_info.key?('instance') # `args` sync_info['sessions'] ||= [{}] Aspera.assert(sync_info['sessions'].length == 1, 'Only one session is supported') session = sync_info['sessions'].first dir_key = path_is_remote ? 'remote_dir' : 'local_dir' Aspera.assert(!session.key?(dir_key)) { "Parameter #{dir_key} shall not be in sync_info" } session[dir_key] = path if direction dir_key = path_is_remote ? 'local_dir' : 'remote_dir' Aspera.assert(!session.key?(dir_key)) { "Parameter #{dir_key} shall not be in sync_info" } session[dir_key] = transfer.destination_folder(path_is_remote ? Transfer::Spec::DIRECTION_RECEIVE : Transfer::Spec::DIRECTION_SEND) local_remote = %w[local remote].map { |i| session["#{i}_dir"] } end else # `conf` session = sync_info dir_key = path_is_remote ? 'remote' : 'local' session[dir_key] ||= {} Aspera.assert(!session[dir_key].key?('path')) { "Parameter #{dir_key}.path shall not be in sync_info" } session[dir_key]['path'] = path if direction dir_key = path_is_remote ? 'local' : 'remote' session[dir_key] ||= {} Aspera.assert(!session[dir_key].key?('path')) { "Parameter #{dir_key}.path shall not be in sync_info" } session[dir_key]['path'] = transfer.destination_folder(path_is_remote ? Transfer::Spec::DIRECTION_RECEIVE : Transfer::Spec::DIRECTION_SEND) local_remote = %w[local remote].map { |i| session[i]['path'] } end # `conf` is quiet by default session['quiet'] = false if !session.key?('quiet') && Environment.terminal? end if direction Aspera.assert(!session.key?('direction'), type: BadArgument) { 'direction shall not be in sync_info' } session['direction'] = direction.to_s # generate name if not provided by user if !session.key?('name') safe_char = Environment.instance.safe_filename_character # from async man page: # -N : can contain only ASCII alphanumeric, hyphen, and underscore characters session['name'] = Environment.instance.sanitized_filename( ([direction.to_s] + local_remote).map do |value| Pathname(value).each_filename.to_a.last(2).join(safe_char) end.join(safe_char).gsub(/[^A-Za-z0-9_-]/, safe_char) ) end end sync_info end |
#db_from_args(path:, sync_info: {}) ⇒ Object
Provide database object from path + sync_info for admin ops
109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/aspera/cli/sync_actions.rb', line 109 def db_from_args(path:, sync_info: {}) sync_info = async_info_from_args(path: path, sync_info: sync_info) session = sync_info.key?('sessions') ? sync_info['sessions'].first : sync_info # if name not provided, check in db folder if there is only one name if !session.key?('name') local_db_dir = Sync::Operations.local_db_folder(sync_info) dbs = Sync::Operations.list_db_files(local_db_dir) Aspera.assert(dbs.length == 1) { "#{dbs.length} session found in #{local_db_dir}, please provide a name" } session['name'] = dbs.keys.first end Sync::Database.new(Sync::Operations.session_db_file(sync_info)) end |
#run_sync_transfer(direction, path:, sync_info: {}, &block) ⇒ Object
Execute a sync transfer for a given direction.
165 166 167 168 |
# File 'lib/aspera/cli/sync_actions.rb', line 165 def run_sync_transfer(direction, path:, sync_info: {}, &block) Sync::Operations.start(async_info_from_args(path: path, sync_info: sync_info, direction: direction), transfer.user_transfer_spec, &block) Result::Success.new end |