Skip to content

Commit

Permalink
add ability to run without async for easier debugging
Browse files Browse the repository at this point in the history
  • Loading branch information
wr0ngway committed Jun 3, 2022
1 parent 9791457 commit cfe52f3
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 13 deletions.
6 changes: 3 additions & 3 deletions helm/kubetruth/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ spec:
- --polling-interval
- "{{ .Values.appSettings.pollingInterval }}"
{{- end }}
{{- if .Values.appSettings.noMetadata }}
- --no-metadata
{{- end }}
{{- if .Values.appSettings.debug }}
- --debug
{{- end }}
{{- if not .Values.appSettings.async }}
- --no-async
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
Expand Down
1 change: 1 addition & 0 deletions helm/kubetruth/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ appSettings:
apiUrl:
pollingInterval:
debug: false
async: true

# If secret.create == false, secret generation is left to the user
# outside of the chart, and a name should be specified
Expand Down
6 changes: 5 additions & 1 deletion lib/kubetruth/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class CLI < CLIBase
:flag, "Perform a dry run",
default: false

option ["-a", "--[no-]async"],
:flag, "Run using async I/O (or not)",
default: true

# TODO: option to map template to configmap?

def execute
Expand All @@ -47,7 +51,7 @@ def execute
Kubetruth::CtApi.configure(api_key: api_key, api_url: api_url)
Kubetruth::KubeApi.configure(namespace: kube_namespace, token: kube_token, api_url: kube_url)

etl = ETL.new(dry_run: dry_run?)
etl = ETL.new(dry_run: dry_run?, async: async?)

Signal.trap("HUP") do
puts "Handling HUP signal - waking up ETL poller" # logger cant be called from trap
Expand Down
46 changes: 39 additions & 7 deletions lib/kubetruth/etl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ module Kubetruth
class ETL
include GemLogger::LoggerSupport

def initialize(dry_run: false)
def initialize(dry_run: false, async: true)
@dry_run = dry_run
@async = async
@wrote_crds = false
end

Expand Down Expand Up @@ -85,14 +86,47 @@ def with_polling(interval, &block)
end
end

def async_task_tree(task)
msg = ""

if task.parent
# The root task seems to always be nil, so exclude it from name
unless task.parent.parent.nil? && task.parent.annotation.blank?
msg << async_task_tree(task.parent) << " -> "
end
end

msg << (task.annotation ? task.annotation : "unnamed")
msg
end

def wait
# no-op so we have something to return from sync tasks that can be waited on
end

def async(*args, **kwargs)
Async(*args, **kwargs) do |task|
if @async
Async(*args, **kwargs) do |task|
task_name = async_task_tree(task)
begin
logger.info "Starting async task: #{task_name}"
yield task
logger.info "Completed async task: #{task_name}"
rescue => e
logger.log_exception(e, "Failure in async task: #{task_name}")
task.stop
end
end
else
task_name = kwargs[:annotation] || "unnamed"
begin
yield task
logger.info "Starting sync task: #{task_name}"
yield
logger.info "Completed sync task: #{task_name}"
rescue => e
logger.log_exception(e, "Failure in async task: #{task.annotation}")
task.stop
logger.log_exception(e, "Failure in sync task: #{task_name}")
end
self # return self to get a wait method
end
end

Expand Down Expand Up @@ -224,8 +258,6 @@ def apply
if parsed_yml.present?
async(annotation: "Apply Template: #{template_id}") do
kube_apply(parsed_yml)
kube_apply(parsed_yml)
kube_apply(parsed_yml)
end
else
logger.debug {"Skipping empty stream template"}
Expand Down
3 changes: 2 additions & 1 deletion spec/kubetruth/cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ module Kubetruth
--kube-token kt
--kube-url ku
--dry-run
--no-async
--polling-interval 27
]

Expand All @@ -41,7 +42,7 @@ module Kubetruth
})

etl = double(ETL)
expect(ETL).to receive(:new).with(dry_run: true).and_return(etl)
expect(ETL).to receive(:new).with(dry_run: true, async: false).and_return(etl)
expect(etl).to receive(:apply)
expect(etl).to receive(:with_polling).with(27).and_yield
cli.run(args)
Expand Down
38 changes: 37 additions & 1 deletion spec/kubetruth/etl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -724,9 +724,45 @@ class ForceExit < Exception; end
end

it "yields task" do
n = nil
etl.async(annotation: "mytask") do |task|
expect(task.annotation).to eq("mytask")
n = task.annotation
end
expect(n).to eq("mytask")
end

it "can switch to sync mode" do
etl = described_class.new(async: false)
etl.async(annotation: "mytask") do |task|
nil
end
expect(Logging.contents).to match(/Starting sync task: mytask.*Completed sync task: mytask/m)

task = etl.async(annotation: "badtask") do
raise "task fail"
end
expect(Logging.contents).to match(/Failure in sync task: badtask/)

t = etl.async(annotation: "mytask") do |task|
nil
end
t.wait # make sure wait is allowed (no-op) in sync mode
end

it "formats task name" do
n1, n2, n3 = nil, nil, nil
etl.async(annotation: "parenttask") do |t1|
n1 = etl.async_task_tree(t1)
etl.async do |t2|
n2 = etl.async_task_tree(t2)
etl.async(annotation: "childtask") do |t3|
n3 = etl.async_task_tree(t3)
end
end
end
expect(n1).to eq("parenttask")
expect(n2).to eq("parenttask -> unnamed")
expect(n3).to eq("parenttask -> unnamed -> childtask")
end

end
Expand Down

0 comments on commit cfe52f3

Please sign in to comment.