This repository has been archived by the owner on Apr 17, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 472
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixed blocking issues with security scanning
Unless you provided enough Puma workers, there was a problem with HTTP requests getting blocked. This is a similar issue as pointed out in #1353 with registry events. The solution has been to move security scanning in the background, in a different process. This is similar to #1353, but more polished (and if this proves to really work we might move #1353 to this background runner as well). Now the Tag model has two more columns: `vulnerabilities` and `scanned`. The former contains the cached result of the latest security check. The latter is an integer that can have three different values: 0 (scanning not performed), 1 (working on it) and 2 (scanning done). This has also been exposed on the API, so the client side can be updated. Signed-off-by: Miquel Sabaté Solà <[email protected]>
- Loading branch information
Showing
20 changed files
with
699 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
require "portus/db" | ||
|
||
# | ||
# First of all, wait until the database is up and running. This is useful in | ||
# containerized scenarios. | ||
# | ||
|
||
count = 0 | ||
TIMEOUT = 90 | ||
|
||
while ::Portus::DB.ping != :ready | ||
if count >= TIMEOUT | ||
puts "Timeout reached, exiting with error. Check the logs..." | ||
exit 1 | ||
end | ||
|
||
puts "Waiting for DB to be ready" | ||
sleep 5 | ||
count += 5 | ||
end | ||
|
||
# | ||
# The DB is up, now let's define the different background jobs as classes. | ||
# | ||
|
||
require "portus/background/security_scanning" | ||
|
||
they = [::Portus::Background::SecurityScanning.new] | ||
values = they.map { |v| "'#{v}'" }.join(", ") | ||
Rails.logger.info "Running: #{values}" | ||
|
||
# | ||
# Finally, we will loop infinitely like this: | ||
# 1. Each background job will execute its task. | ||
# 2. Then we will sleep until there's more work to be done. | ||
# | ||
|
||
SLEEP_VALUE = 10 | ||
|
||
# Loop forever executing the given tasks. It will go to sleep for spans of | ||
# `SLEEP_VALUE` seconds, if there's nothing else to be done. | ||
loop do | ||
they.each { |t| t.execute! if t.work? } | ||
sleep SLEEP_VALUE until they.any?(&:work?) | ||
end | ||
|
||
exit 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
class AddScannedAndVulnsToTag < ActiveRecord::Migration | ||
def change | ||
add_column :tags, :scanned, :integer, default: 0 | ||
add_column :tags, :vulnerabilities, :text | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
require "portus/security" | ||
|
||
module Portus | ||
module Background | ||
# SecurityScanning represents a task for checking vulnerabilities of tags that | ||
# have not been scanned yet. | ||
class SecurityScanning | ||
def work? | ||
::Portus::Security.enabled? && Tag.exists?(scanned: Tag.statuses[:scan_none]) | ||
end | ||
|
||
def execute! | ||
Tag.where(scanned: Tag.statuses[:scan_none]).find_each do |tag| | ||
# Mark as work in progress. This is important in case there is a push in | ||
# progress. | ||
tag.update_columns(scanned: Tag.statuses[:scan_working]) | ||
|
||
# Fetch vulnerabilities. | ||
sec = ::Portus::Security.new(tag.repository.full_name, tag.name) | ||
vulns = sec.vulnerabilities | ||
|
||
# Now it's time to update the columns and mark the scanning as done. That | ||
# being said, it may have happened that during the scanning process a push | ||
# or a delete action has been performed against this tag. For this reason, | ||
# in a transaction we will reload it and check if any of these conditions | ||
# changed. If not, then we will proceed with the change. | ||
ActiveRecord::Base.transaction do | ||
# If the tag no longer exists, then we need to raise a Rollback | ||
# exception to leave early and cleanly from the transaction. | ||
begin | ||
tag = tag.reload | ||
rescue ActiveRecord::RecordNotFound | ||
raise ActiveRecord::Rollback | ||
end | ||
|
||
if tag&.scanned != Tag.statuses[:scan_none] | ||
tag.update_columns(vulnerabilities: vulns, scanned: Tag.statuses[:scan_done]) | ||
end | ||
end | ||
end | ||
end | ||
|
||
def to_s | ||
"Security scanning" | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.