openc3 5.0.7 → 5.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 19c4ca95f60633de6f38b56a72891bda7cdcdf0b902a16d52f6527966c213bab
4
- data.tar.gz: 7ed07cc0014bd9ca27c57ff307cc879e385617339a6cb9b6c1fa891ab971a018
3
+ metadata.gz: 3a1e753382bf9c7d98b63dad72fed1aa08e3a234ce140327d0bbf07ed2a913dd
4
+ data.tar.gz: 4b61da453f0fc1c75b7ec5df06516970b1a0d3325425e15f550322a505e90883
5
5
  SHA512:
6
- metadata.gz: bc5c9ff0457266a17d4bef4f89c40fc99b851d4fe87d1d40783db3bdd84bf2581244e0055bfd6c5db706a60f35f4073d3eb0f9c0659a88a736bdc185051535bc
7
- data.tar.gz: fdc7c1552371c0555f0d67e30d8f31b9e966986224ecec2ab0c5705e60f8f2d4708782fb26776d359514c696ea6632f380526f7ba7a6dc34d382d32eab3f536b
6
+ metadata.gz: 3cfaad4b9103a68a6608d48513f1e1161df68325bfb0684d9dac6aebcc47af0e4c2a3225692dff08b7d28aa96ce33a3b7812928e0191620bffb08686fbe511d6
7
+ data.tar.gz: a385b3d5ac4524c8919adf9cc1050793c1ce5e30fb62c679a711b79f7523d3908301de23cfd97d426ec0c58ce1815d16047807802afb8530cbb1faf91392a444
data/bin/openc3cli CHANGED
@@ -530,6 +530,9 @@ if not ARGV[0].nil? # argument(s) given
530
530
  if plugin["name"] =~ /tool-base/ and plugin["name"] !~ /enterprise/
531
531
  unload_plugin(plugin_name, scope: scope_name)
532
532
  end
533
+ if plugin["name"] =~ /tool-admin/ and plugin["name"] !~ /enterprise/
534
+ unload_plugin(plugin_name, scope: scope_name)
535
+ end
533
536
  end
534
537
  end
535
538
 
@@ -545,6 +548,10 @@ if not ARGV[0].nil? # argument(s) given
545
548
  end
546
549
  end
547
550
 
551
+ when 'destroyscope'
552
+ scope = OpenC3::ScopeModel.get_model(name: ARGV[1])
553
+ scope.destroy
554
+
548
555
  else # Unknown task
549
556
  print_usage()
550
557
  abort("Unknown task: #{ARGV[0]}")
@@ -78,7 +78,7 @@ ARRAY_PARAMETER:
78
78
  - name: Name
79
79
  required: true
80
80
  description: Name of the parameter. Must be unique within the command.
81
- values: \'
81
+ values: .*
82
82
  - name: Bit Offset
83
83
  required: true
84
84
  description: Bit offset into the command packet of the Most Significant Bit of this parameter.
@@ -95,7 +95,7 @@ APPEND_ARRAY_PARAMETER:
95
95
  - name: Name
96
96
  required: true
97
97
  description: Name of the parameter. Must be unique within the command.
98
- values: '\D\S*'
98
+ values: .*
99
99
  <%= MetaConfigParser.load('_array_params.yaml').to_meta_config_yaml(4) %>
100
100
  SELECT_PARAMETER:
101
101
  modifiers:
@@ -61,3 +61,11 @@ TOOL:
61
61
  required: true
62
62
  description: Whether or not the tool is shown. TRUE or FALSE
63
63
  values: ["true", "false"]
64
+ POSITION:
65
+ summary: Position of the tool in the nav bar
66
+ description: Position of the tool as an integer starting at 1. Tools without a position are appended to the end as they are installed.
67
+ parameters:
68
+ - name: Position
69
+ required: true
70
+ description: Numerical position
71
+ values: \d+
@@ -909,6 +909,37 @@ LINEGRAPH:
909
909
  # required: false
910
910
  # description: The type of the value to display. Default is CONVERTED.
911
911
  # values: <%= %w(RAW CONVERTED FORMATTED WITH_UNITS) %>
912
+ SPARKLINE:
913
+ summary: Displays a sparkline graph (no cursor, scale or legend) of a telemetry item
914
+ parameters:
915
+ - name: Target name
916
+ required: true
917
+ description: The target name
918
+ values: .+
919
+ - name: Packet name
920
+ required: true
921
+ description: The packet name
922
+ values: .+
923
+ - name: Item name
924
+ required: true
925
+ description: The item name
926
+ values: .+
927
+ LABELSPARKLINE:
928
+ summary: Displays a LABEL widget to show the telemetry
929
+ item name followed by a SPARKLINE widget to graph the item
930
+ parameters:
931
+ - name: Target name
932
+ required: true
933
+ description: The target name
934
+ values: .+
935
+ - name: Packet name
936
+ required: true
937
+ description: The packet name
938
+ values: .+
939
+ - name: Item name
940
+ required: true
941
+ description: The item name
942
+ values: .+
912
943
  PROGRESSBAR:
913
944
  summary: Displays a progress bar that is useful for displaying percentages
914
945
  parmeters:
@@ -40,12 +40,12 @@ module OpenC3
40
40
 
41
41
  # Delete the current value table for a target
42
42
  def self.del(target_name:, packet_name:, scope:)
43
- EphemeralStore.hdel("#{scope}__tlm__#{target_name}", packet_name)
43
+ Store.hdel("#{scope}__tlm__#{target_name}", packet_name)
44
44
  end
45
45
 
46
46
  # Set the current value table for a target, packet
47
47
  def self.set(hash, target_name:, packet_name:, scope:)
48
- EphemeralStore.hset("#{scope}__tlm__#{target_name}", packet_name, JSON.generate(hash.as_json(:allow_nan => true)))
48
+ Store.hset("#{scope}__tlm__#{target_name}", packet_name, JSON.generate(hash.as_json(:allow_nan => true)))
49
49
  end
50
50
 
51
51
  # Set an item in the current value table
@@ -62,9 +62,9 @@ module OpenC3
62
62
  else
63
63
  raise "Unknown type '#{type}' for #{target_name} #{packet_name} #{item_name}"
64
64
  end
65
- hash = JSON.parse(EphemeralStore.hget("#{scope}__tlm__#{target_name}", packet_name), :allow_nan => true, :create_additions => true)
65
+ hash = JSON.parse(Store.hget("#{scope}__tlm__#{target_name}", packet_name), :allow_nan => true, :create_additions => true)
66
66
  hash[field] = value
67
- EphemeralStore.hset("#{scope}__tlm__#{target_name}", packet_name, JSON.generate(hash.as_json(:allow_nan => true)))
67
+ Store.hset("#{scope}__tlm__#{target_name}", packet_name, JSON.generate(hash.as_json(:allow_nan => true)))
68
68
  end
69
69
 
70
70
  # Get an item from the current value table
@@ -86,7 +86,7 @@ module OpenC3
86
86
  else
87
87
  raise "Unknown type '#{type}' for #{target_name} #{packet_name} #{item_name}"
88
88
  end
89
- hash = JSON.parse(EphemeralStore.hget("#{scope}__tlm__#{target_name}", packet_name), :allow_nan => true, :create_additions => true)
89
+ hash = JSON.parse(Store.hget("#{scope}__tlm__#{target_name}", packet_name), :allow_nan => true, :create_additions => true)
90
90
  hash.values_at(*types).each do |result|
91
91
  return result if result
92
92
  end
@@ -106,7 +106,7 @@ module OpenC3
106
106
 
107
107
  lookups.each do |target_packet_key, target_name, packet_name, packet_values|
108
108
  unless packet_lookup[target_packet_key]
109
- packet = EphemeralStore.hget("#{scope}__tlm__#{target_name}", packet_name)
109
+ packet = Store.hget("#{scope}__tlm__#{target_name}", packet_name)
110
110
  raise "Packet '#{target_name} #{packet_name}' does not exist" unless packet
111
111
  packet_lookup[target_packet_key] = JSON.parse(packet, :allow_nan => true, :create_additions => true)
112
112
  end
@@ -267,11 +267,13 @@ module OpenC3
267
267
 
268
268
  # Undeploy all models associated with this plugin
269
269
  def undeploy
270
+ microservice_count = 0
270
271
  MicroserviceModel.find_all_by_plugin(plugin: @name, scope: @scope).each do |name, model_instance|
271
272
  model_instance.destroy
273
+ microservice_count += 1
272
274
  end
273
275
  # Wait for the operator to wake up and remove the microservice processes
274
- sleep 12 # Cycle time 5s times 2 plus 2s wait for soft stop and then hard stop
276
+ sleep 12 if microservice_count > 0 # Cycle time 5s times 2 plus 2s wait for soft stop and then hard stop
275
277
  # Remove all the other models now that the processes have stopped
276
278
  # Save TargetModel for last as it has the most to cleanup
277
279
  [InterfaceModel, RouterModel, ToolModel, WidgetModel, TargetModel].each do |model|
@@ -40,10 +40,47 @@ module OpenC3
40
40
  super(PRIMARY_KEY)
41
41
  end
42
42
 
43
+ def self.from_json(json, scope: nil)
44
+ json = JSON.parse(json, :allow_nan => true, :create_additions => true) if String === json
45
+ raise "json data is nil" if json.nil?
46
+
47
+ json.transform_keys!(&:to_sym)
48
+ self.new(**json, scope: scope)
49
+ end
50
+
51
+ def self.get_model(name:, scope: nil)
52
+ json = get(name: name)
53
+ if json
54
+ return from_json(json)
55
+ else
56
+ return nil
57
+ end
58
+ end
59
+
43
60
  def initialize(name:, updated_at: nil, scope: nil)
44
61
  super(PRIMARY_KEY, name: name, scope: name, updated_at: updated_at)
45
62
  end
46
63
 
64
+ def create(update: false, force: false)
65
+ # Ensure there are no "." in the scope name - prevents gems accidently becoming scope names
66
+ raise "Invalid scope name: #{@name}" if @name !~ /^[a-zA-Z0-9_-]+$/
67
+ @name = @name.upcase
68
+ super(update: update, force: force)
69
+ end
70
+
71
+ def destroy
72
+ if @name != 'DEFAULT'
73
+ # Remove all the plugins for this scope
74
+ plugins = PluginModel.get_all_models(scope: @name)
75
+ plugins.each do |plugin_name, plugin|
76
+ plugin.destroy
77
+ end
78
+ super()
79
+ else
80
+ raise "DEFAULT scope cannot be destroyed"
81
+ end
82
+ end
83
+
47
84
  def as_json(*a)
48
85
  { 'name' => @name,
49
86
  'updated_at' => @updated_at }
@@ -51,9 +88,12 @@ module OpenC3
51
88
 
52
89
  def deploy(gem_path, variables)
53
90
  seed_database()
54
-
55
91
  ConfigTopic.initialize_stream(@scope)
56
92
 
93
+ # Create UNKNOWN target for display of unknown data
94
+ model = TargetModel.new(name: "UNKNOWN", scope: @scope)
95
+ model.create
96
+
57
97
  # OpenC3 Log Microservice
58
98
  microservice_name = "#{@scope}__OPENC3__LOG"
59
99
  microservice = MicroserviceModel.new(
@@ -203,6 +203,9 @@ module OpenC3
203
203
  when 'SHOWN'
204
204
  parser.verify_num_parameters(1, 1, "SHOWN <true/false>")
205
205
  @shown = ConfigParser.handle_true_false(parameters[0])
206
+ when 'POSITION'
207
+ parser.verify_num_parameters(1, 1, "POSITION <value>")
208
+ @position = parameters[0].to_i
206
209
  else
207
210
  raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Tool: #{keyword} #{parameters.join(" ")}")
208
211
  end
@@ -90,7 +90,7 @@ module OpenC3
90
90
  @new_microservices.each do |microservice_name, microservice_config|
91
91
  cmd_array, work_dir, env, scope, container = convert_microservice_to_process_definition(microservice_name, microservice_config)
92
92
  if cmd_array
93
- process = OperatorProcess.new(cmd_array, work_dir: work_dir, env: env, scope: scope, container: container)
93
+ process = OperatorProcess.new(cmd_array, work_dir: work_dir, env: env, scope: scope, container: container, config: microservice_config)
94
94
  @new_processes[microservice_name] = process
95
95
  @processes[microservice_name] = process
96
96
  end
@@ -108,7 +108,7 @@ module OpenC3
108
108
  @changed_processes[microservice_name] = process
109
109
  else # TODO: How is this even possible?
110
110
  Logger.error("Changed microservice #{microservice_name} does not exist. Creating new...", scope: scope)
111
- process = OperatorProcess.new(cmd_array, work_dir: work_dir, env: env, scope: scope, container: container)
111
+ process = OperatorProcess.new(cmd_array, work_dir: work_dir, env: env, scope: scope, container: container, config: microservice_config)
112
112
  @new_processes[microservice_name] = process
113
113
  @processes[microservice_name] = process
114
114
  end
@@ -35,7 +35,8 @@ module OpenC3
35
35
  # Perform any setup steps necessary
36
36
  end
37
37
 
38
- def initialize(process_definition, work_dir: '/openc3/lib/openc3/microservices', temp_dir: nil, env: {}, scope:, container: nil) # container is not used, it's just here for Enterprise
38
+ # container is not used, it's just here for Enterprise
39
+ def initialize(process_definition, work_dir: '/openc3/lib/openc3/microservices', temp_dir: nil, env: {}, scope:, container: nil, config: nil)
39
40
  @process = nil
40
41
  @process_definition = process_definition
41
42
  @work_dir = work_dir
@@ -43,12 +44,26 @@ module OpenC3
43
44
  @new_temp_dir = temp_dir
44
45
  @env = env
45
46
  @scope = scope
47
+ # @config only used in start to help print a better Logger message
48
+ @config = config
46
49
  end
47
50
 
48
51
  def start
49
52
  @temp_dir = @new_temp_dir
50
53
  @new_temp_dir = nil
51
- Logger.info("Starting: #{@process_definition.join(' ')}", scope: @scope)
54
+
55
+ # In ProcessManager processes, the process_definition is the actual thing run
56
+ # e.g. OpenC3::ProcessManager.instance.spawn(["ruby", "/openc3/bin/openc3cli", "load", ...])
57
+ # However, if the MicroserviceOperator is spawning the proceses it sets
58
+ # process_definition = ["ruby", "plugin_microservice.rb"]
59
+ # which then calls exec(*@config["cmd"]) to actually run
60
+ # So check if the @config['cmd'] is defined to give the user more info in the log
61
+ cmd = @process_definition.join(' ')
62
+ if @config && @config['cmd']
63
+ cmd = @config['cmd'].join(' ')
64
+ end
65
+ Logger.info("Starting: #{cmd}", scope: @scope)
66
+
52
67
  @process = ChildProcess.build(*@process_definition)
53
68
  # This lets the ChildProcess use the parent IO ... but it breaks unit tests
54
69
  # @process.io.inherit!
@@ -22,6 +22,22 @@ require 'openc3/models/reducer_model'
22
22
 
23
23
  module OpenC3
24
24
  class S3Utilities
25
+ def self.put_object_and_check(params = {})
26
+ rubys3_client = Aws::S3::Client.new
27
+ rubys3_client.put_object(params)
28
+ # polls in a loop, sleeping between attempts
29
+ rubys3_client.wait_until(:object_exists,
30
+ {
31
+ bucket: params[:bucket],
32
+ key: params[:key]
33
+ },
34
+ {
35
+ max_attempts: 30,
36
+ delay: 0.1, # seconds
37
+ }
38
+ )
39
+ end
40
+
25
41
  def self.list_files_before_time(bucket, prefix, time)
26
42
  rubys3_client = Aws::S3::Client.new
27
43
  oldest_list = []
@@ -1,14 +1,14 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- OPENC3_VERSION = '5.0.7'
3
+ OPENC3_VERSION = '5.0.8'
4
4
  module OpenC3
5
5
  module Version
6
6
  MAJOR = '5'
7
7
  MINOR = '0'
8
- PATCH = '7'
8
+ PATCH = '8'
9
9
  OTHER = ''
10
- BUILD = 'be957bd6e3c30c2e535b9ee8dfbeffe75c720874'
10
+ BUILD = '8dc96d0ce9d272e063d9d806f848803b7d5c61ed'
11
11
  end
12
- VERSION = '5.0.7'
13
- GEM_VERSION = '5.0.7'
12
+ VERSION = '5.0.8'
13
+ GEM_VERSION = '5.0.8'
14
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openc3
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.7
4
+ version: 5.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Melton
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-08-05 00:00:00.000000000 Z
12
+ date: 2022-08-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: '6.3'
34
+ version: '6.4'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: '6.3'
41
+ version: '6.4'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: rake
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -185,14 +185,14 @@ dependencies:
185
185
  requirements:
186
186
  - - "~>"
187
187
  - !ruby/object:Gem::Version
188
- version: '3.0'
188
+ version: '4.0'
189
189
  type: :runtime
190
190
  prerelease: false
191
191
  version_requirements: !ruby/object:Gem::Requirement
192
192
  requirements:
193
193
  - - "~>"
194
194
  - !ruby/object:Gem::Version
195
- version: '3.0'
195
+ version: '4.0'
196
196
  - !ruby/object:Gem::Dependency
197
197
  name: matrix
198
198
  requirement: !ruby/object:Gem::Requirement
@@ -311,14 +311,14 @@ dependencies:
311
311
  requirements:
312
312
  - - "~>"
313
313
  - !ruby/object:Gem::Version
314
- version: '3.1'
314
+ version: '4.0'
315
315
  type: :development
316
316
  prerelease: false
317
317
  version_requirements: !ruby/object:Gem::Requirement
318
318
  requirements:
319
319
  - - "~>"
320
320
  - !ruby/object:Gem::Version
321
- version: '3.1'
321
+ version: '4.0'
322
322
  - !ruby/object:Gem::Dependency
323
323
  name: diff-lcs
324
324
  requirement: !ruby/object:Gem::Requirement