mirror of
https://github.com/quay/quay.git
synced 2025-04-18 10:44:06 +03:00
chore: allows Quay to run for account recoveries (PROJQUAY-970) (#793)
Adds ACCOUNT_RECOVERY_MODE to allow Quay to run with some core features disabled. When this is set, the instance should only be used in order by existing users who hasn't linked their account to an external login service, after database authentication has been disabled.
This commit is contained in:
parent
95ec9478fc
commit
a839a78eb5
@ -34,17 +34,20 @@ DEFAULT_CONTROLLER_PORT = 8686
|
||||
|
||||
|
||||
def run_build_manager():
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
if not features.BUILD_SUPPORT:
|
||||
logger.debug("Building is disabled. Please enable the feature flag")
|
||||
while True:
|
||||
time.sleep(1000)
|
||||
return
|
||||
|
||||
if app.config.get("REGISTRY_STATE", "normal") == "readonly":
|
||||
logger.debug("Building is disabled while in read-only mode.")
|
||||
while True:
|
||||
time.sleep(1000)
|
||||
return
|
||||
|
||||
build_manager_config = app.config.get("BUILD_MANAGER")
|
||||
if build_manager_config is None:
|
||||
|
@ -773,3 +773,6 @@ class DefaultConfig(ImmutableConfig):
|
||||
|
||||
# Create organization on push if it does not exist
|
||||
CREATE_NAMESPACE_ON_PUSH = False
|
||||
|
||||
# Account recovery mode
|
||||
ACCOUNT_RECOVERY_MODE = False
|
||||
|
@ -158,6 +158,7 @@ def render_page_template(name, route_data=None, **kwargs):
|
||||
version_number=version_number,
|
||||
current_year=datetime.datetime.now().year,
|
||||
kubernetes_namespace=IS_KUBERNETES and QE_NAMESPACE,
|
||||
account_recovery_mode=app.config.get("ACCOUNT_RECOVERY_MODE", False),
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
|
@ -171,6 +171,21 @@ def route_show_if(value):
|
||||
return decorator
|
||||
|
||||
|
||||
def disallow_for_account_recovery_mode(func):
|
||||
"""
|
||||
Disable route if ACCOUNT_RECOVERY_MODE is set.
|
||||
"""
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
abort(405, "Quay running for account recoveries only.")
|
||||
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def require_xhr_from_browser(func):
|
||||
"""
|
||||
Requires that API GET calls made from browsers are made via XHR, in order to prevent reflected
|
||||
|
@ -21,6 +21,7 @@ from digest import digest_tools
|
||||
from endpoints.decorators import (
|
||||
anon_protect,
|
||||
anon_allowed,
|
||||
disallow_for_account_recovery_mode,
|
||||
parse_repository_name,
|
||||
check_region_blacklisted,
|
||||
check_readonly,
|
||||
@ -51,6 +52,7 @@ BLOB_CONTENT_TYPE = "application/octet-stream"
|
||||
|
||||
|
||||
@v2_bp.route(BLOB_DIGEST_ROUTE, methods=["HEAD"])
|
||||
@disallow_for_account_recovery_mode
|
||||
@parse_repository_name()
|
||||
@process_registry_jwt_auth(scopes=["pull"])
|
||||
@require_repo_read
|
||||
@ -78,6 +80,7 @@ def check_blob_exists(namespace_name, repo_name, digest):
|
||||
|
||||
|
||||
@v2_bp.route(BLOB_DIGEST_ROUTE, methods=["GET"])
|
||||
@disallow_for_account_recovery_mode
|
||||
@parse_repository_name()
|
||||
@process_registry_jwt_auth(scopes=["pull"])
|
||||
@require_repo_read
|
||||
@ -217,6 +220,7 @@ def _try_to_mount_blob(repository_ref, mount_blob_digest):
|
||||
|
||||
|
||||
@v2_bp.route("/<repopath:repository>/blobs/uploads/", methods=["POST"])
|
||||
@disallow_for_account_recovery_mode
|
||||
@parse_repository_name()
|
||||
@process_registry_jwt_auth(scopes=["pull", "push"])
|
||||
@require_repo_write
|
||||
@ -278,6 +282,7 @@ def start_blob_upload(namespace_name, repo_name):
|
||||
|
||||
|
||||
@v2_bp.route("/<repopath:repository>/blobs/uploads/<upload_uuid>", methods=["GET"])
|
||||
@disallow_for_account_recovery_mode
|
||||
@parse_repository_name()
|
||||
@process_registry_jwt_auth(scopes=["pull"])
|
||||
@require_repo_write
|
||||
@ -305,6 +310,7 @@ def fetch_existing_upload(namespace_name, repo_name, upload_uuid):
|
||||
|
||||
|
||||
@v2_bp.route("/<repopath:repository>/blobs/uploads/<upload_uuid>", methods=["PATCH"])
|
||||
@disallow_for_account_recovery_mode
|
||||
@parse_repository_name()
|
||||
@process_registry_jwt_auth(scopes=["pull", "push"])
|
||||
@require_repo_write
|
||||
@ -336,6 +342,7 @@ def upload_chunk(namespace_name, repo_name, upload_uuid):
|
||||
|
||||
|
||||
@v2_bp.route("/<repopath:repository>/blobs/uploads/<upload_uuid>", methods=["PUT"])
|
||||
@disallow_for_account_recovery_mode
|
||||
@parse_repository_name()
|
||||
@process_registry_jwt_auth(scopes=["pull", "push"])
|
||||
@require_repo_write
|
||||
@ -376,6 +383,7 @@ def monolithic_upload_or_last_chunk(namespace_name, repo_name, upload_uuid):
|
||||
|
||||
|
||||
@v2_bp.route("/<repopath:repository>/blobs/uploads/<upload_uuid>", methods=["DELETE"])
|
||||
@disallow_for_account_recovery_mode
|
||||
@parse_repository_name()
|
||||
@process_registry_jwt_auth(scopes=["pull", "push"])
|
||||
@require_repo_write
|
||||
@ -397,6 +405,7 @@ def cancel_upload(namespace_name, repo_name, upload_uuid):
|
||||
|
||||
|
||||
@v2_bp.route("/<repopath:repository>/blobs/<digest>", methods=["DELETE"])
|
||||
@disallow_for_account_recovery_mode
|
||||
@parse_repository_name()
|
||||
@process_registry_jwt_auth(scopes=["pull", "push"])
|
||||
@require_repo_write
|
||||
|
@ -9,7 +9,7 @@ from auth.auth_context import get_authenticated_user, get_authenticated_context
|
||||
from auth.registry_jwt_auth import process_registry_jwt_auth
|
||||
from data import model
|
||||
from data.cache import cache_key
|
||||
from endpoints.decorators import anon_protect
|
||||
from endpoints.decorators import anon_protect, disallow_for_account_recovery_mode, route_show_if
|
||||
from endpoints.v2 import v2_bp, paginate
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@ class Repository(namedtuple("Repository", ["id", "namespace_name", "name"])):
|
||||
|
||||
|
||||
@v2_bp.route("/_catalog", methods=["GET"])
|
||||
@disallow_for_account_recovery_mode
|
||||
@process_registry_jwt_auth()
|
||||
@anon_protect
|
||||
@paginate()
|
||||
|
@ -13,7 +13,12 @@ from data.database import db_disallow_replica_use
|
||||
from data.registry_model import registry_model
|
||||
from data.model.oci.manifest import CreateManifestException
|
||||
from data.model.oci.tag import RetargetTagException
|
||||
from endpoints.decorators import anon_protect, parse_repository_name, check_readonly
|
||||
from endpoints.decorators import (
|
||||
anon_protect,
|
||||
disallow_for_account_recovery_mode,
|
||||
parse_repository_name,
|
||||
check_readonly,
|
||||
)
|
||||
from endpoints.metrics import image_pulls, image_pushes
|
||||
from endpoints.v2 import v2_bp, require_repo_read, require_repo_write
|
||||
from endpoints.v2.errors import (
|
||||
@ -43,6 +48,7 @@ MANIFEST_TAGNAME_ROUTE = BASE_MANIFEST_ROUTE.format(VALID_TAG_PATTERN)
|
||||
|
||||
|
||||
@v2_bp.route(MANIFEST_TAGNAME_ROUTE, methods=["GET"])
|
||||
@disallow_for_account_recovery_mode
|
||||
@parse_repository_name()
|
||||
@process_registry_jwt_auth(scopes=["pull"])
|
||||
@require_repo_read
|
||||
@ -101,6 +107,7 @@ def fetch_manifest_by_tagname(namespace_name, repo_name, manifest_ref):
|
||||
|
||||
|
||||
@v2_bp.route(MANIFEST_DIGEST_ROUTE, methods=["GET"])
|
||||
@disallow_for_account_recovery_mode
|
||||
@parse_repository_name()
|
||||
@process_registry_jwt_auth(scopes=["pull"])
|
||||
@require_repo_read
|
||||
@ -213,6 +220,7 @@ def _doesnt_accept_schema_v1():
|
||||
|
||||
|
||||
@v2_bp.route(MANIFEST_TAGNAME_ROUTE, methods=["PUT"])
|
||||
@disallow_for_account_recovery_mode
|
||||
@parse_repository_name()
|
||||
@_reject_manifest2_schema2
|
||||
@process_registry_jwt_auth(scopes=["pull", "push"])
|
||||
@ -225,6 +233,7 @@ def write_manifest_by_tagname(namespace_name, repo_name, manifest_ref):
|
||||
|
||||
|
||||
@v2_bp.route(MANIFEST_DIGEST_ROUTE, methods=["PUT"])
|
||||
@disallow_for_account_recovery_mode
|
||||
@parse_repository_name()
|
||||
@_reject_manifest2_schema2
|
||||
@process_registry_jwt_auth(scopes=["pull", "push"])
|
||||
@ -285,6 +294,7 @@ def _parse_manifest():
|
||||
|
||||
|
||||
@v2_bp.route(MANIFEST_DIGEST_ROUTE, methods=["DELETE"])
|
||||
@disallow_for_account_recovery_mode
|
||||
@parse_repository_name()
|
||||
@process_registry_jwt_auth(scopes=["pull", "push"])
|
||||
@require_repo_write
|
||||
|
@ -1,14 +1,20 @@
|
||||
from flask import jsonify
|
||||
|
||||
from app import model_cache
|
||||
from app import app, model_cache
|
||||
from auth.registry_jwt_auth import process_registry_jwt_auth
|
||||
from data.registry_model import registry_model
|
||||
from endpoints.decorators import anon_protect, parse_repository_name
|
||||
from endpoints.decorators import (
|
||||
anon_protect,
|
||||
disallow_for_account_recovery_mode,
|
||||
parse_repository_name,
|
||||
route_show_if,
|
||||
)
|
||||
from endpoints.v2 import v2_bp, require_repo_read, paginate
|
||||
from endpoints.v2.errors import NameUnknown
|
||||
|
||||
|
||||
@v2_bp.route("/<repopath:repository>/tags/list", methods=["GET"])
|
||||
@disallow_for_account_recovery_mode
|
||||
@parse_repository_name()
|
||||
@process_registry_jwt_auth(scopes=["pull"])
|
||||
@require_repo_read
|
||||
|
@ -1,5 +1,5 @@
|
||||
from app import app as application
|
||||
from endpoints.secscan import secscan
|
||||
|
||||
|
||||
if not application.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
application.register_blueprint(secscan, url_prefix="/secscan")
|
||||
|
@ -1,10 +1,17 @@
|
||||
<div class="announcement inline quay-message-bar-element" ng-show="messages.length || inReadOnlyMode">
|
||||
<div class="announcement inline quay-message-bar-element" ng-show="messages.length || inReadOnlyMode || inAccountRecoveryMode">
|
||||
<div class="quay-service-status-description info" ng-if="inReadOnlyMode">
|
||||
<div style="display: inline-block">
|
||||
<span class="registry-name"></span> is currently in read-only mode. Pulls and other read-only operations
|
||||
will succeed but all other operations are currently suspended.
|
||||
</div>
|
||||
</div>
|
||||
<div class="quay-service-status-description warning" ng-if="inAccountRecoveryMode">
|
||||
<div style="display: inline-block">
|
||||
<span class="registry-name"></span> is currently in account recovery mode. This instance should only be
|
||||
used to link accounts to an external login service. e.g RedHat. Registry operations such as pushes/pulls
|
||||
will not work.
|
||||
</div>
|
||||
</div>
|
||||
<div ng-repeat="token in NotificationService.expiringAppTokens">
|
||||
<div class="quay-service-status-description warning">
|
||||
Your external application token <strong style="display: inline-block; padding: 4px;">{{ token.title }}</strong>
|
||||
|
@ -16,6 +16,7 @@ angular.module('quay').directive('quayMessageBar', function () {
|
||||
|
||||
StateService.updateStateIn($scope, function(state) {
|
||||
$scope.inReadOnlyMode = state.inReadOnlyMode;
|
||||
$scope.inAccountRecoveryMode = state.inAccountRecoveryMode;
|
||||
});
|
||||
|
||||
ApiService.getGlobalMessages().then(function (data) {
|
||||
|
@ -33,6 +33,10 @@ export function provideRun($rootScope: QuayRunScope,
|
||||
stateService.setInReadOnlyMode();
|
||||
}
|
||||
|
||||
if ((<any>window).__account_recovery_mode) {
|
||||
stateService.setInAccountRecoveryMode();
|
||||
}
|
||||
|
||||
// Handle session security.
|
||||
restangular.setDefaultHeaders({
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
|
@ -6,7 +6,8 @@ angular.module('quay')
|
||||
var stateService = {};
|
||||
|
||||
var currentState = {
|
||||
'inReadOnlyMode': false
|
||||
'inReadOnlyMode': false,
|
||||
'inAccountRecoveryMode': false
|
||||
};
|
||||
|
||||
stateService.inReadOnlyMode = function() {
|
||||
@ -17,6 +18,15 @@ angular.module('quay')
|
||||
currentState.inReadOnlyMode = true;
|
||||
};
|
||||
|
||||
|
||||
stateService.inAccountRecoveryMode = function() {
|
||||
return currentState.inAccountRecoveryMode;
|
||||
};
|
||||
|
||||
stateService.setInAccountRecoveryMode = function() {
|
||||
currentState.inAccountRecoveryMode = true;
|
||||
};
|
||||
|
||||
stateService.updateStateIn = function(scope, opt_callback) {
|
||||
scope.$watch(function () { return stateService.currentState(); }, function (currentState) {
|
||||
$timeout(function(){
|
||||
|
@ -47,6 +47,7 @@
|
||||
window.__token = '{{ csrf_token() }}';
|
||||
window.__kubernetes_namespace = {{ kubernetes_namespace|tojson|safe }};
|
||||
window.__registry_state = '{{ registry_state }}';
|
||||
window.__account_recovery_mode = '{{ account_recovery_mode }}';
|
||||
|
||||
{% if error_code %}
|
||||
window.__error_code = {{ error_code }};
|
||||
|
@ -99,6 +99,7 @@ INTERNAL_ONLY_PROPERTIES = {
|
||||
"LOGS_MODEL_CONFIG",
|
||||
"APP_REGISTRY_RESULTS_LIMIT",
|
||||
"V3_UPGRADE_MODE", # Deprecated old flag
|
||||
"ACCOUNT_RECOVERY_MODE",
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import logging
|
||||
import logging.config
|
||||
import time
|
||||
|
||||
from datetime import timedelta, datetime
|
||||
|
||||
@ -85,6 +86,11 @@ def create_gunicorn_worker():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
logging.config.fileConfig(logfile_path(debug=False), disable_existing_loggers=False)
|
||||
GlobalLock.configure(app.config)
|
||||
worker = BlobUploadCleanupWorker()
|
||||
|
@ -1,4 +1,5 @@
|
||||
import logging
|
||||
import time
|
||||
|
||||
from gzip import GzipFile
|
||||
from tempfile import SpooledTemporaryFile
|
||||
@ -79,5 +80,10 @@ def create_gunicorn_worker():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
worker = ArchiveBuildLogsWorker()
|
||||
worker.start()
|
||||
|
@ -59,6 +59,11 @@ def create_gunicorn_worker():
|
||||
if __name__ == "__main__":
|
||||
logging.config.fileConfig(logfile_path(debug=False), disable_existing_loggers=False)
|
||||
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
engines = set(
|
||||
[config[0] for config in list(app.config.get("DISTRIBUTED_STORAGE_CONFIG", {}).values())]
|
||||
)
|
||||
|
@ -56,6 +56,11 @@ def create_gunicorn_worker():
|
||||
if __name__ == "__main__":
|
||||
logging.config.fileConfig(logfile_path(debug=False), disable_existing_loggers=False)
|
||||
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
if not features.APP_SPECIFIC_TOKENS:
|
||||
logger.debug("App specific tokens disabled; skipping")
|
||||
while True:
|
||||
|
@ -86,6 +86,11 @@ def create_gunicorn_worker():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
if not features.GARBAGE_COLLECTION:
|
||||
logger.debug("Garbage collection is disabled; skipping")
|
||||
while True:
|
||||
|
@ -82,6 +82,11 @@ def create_gunicorn_worker():
|
||||
def main():
|
||||
logging.config.fileConfig(logfile_path(debug=False), disable_existing_loggers=False)
|
||||
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
if not app.config.get("PROMETHEUS_PUSHGATEWAY_URL"):
|
||||
logger.debug("Prometheus not enabled; skipping global stats reporting")
|
||||
while True:
|
||||
|
@ -148,6 +148,11 @@ def create_gunicorn_worker():
|
||||
def main():
|
||||
logging.config.fileConfig(logfile_path(debug=False), disable_existing_loggers=False)
|
||||
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
if not features.ACTION_LOG_ROTATION or None in [SAVE_PATH, SAVE_LOCATION]:
|
||||
logger.debug("Action log rotation worker not enabled; skipping")
|
||||
while True:
|
||||
|
@ -1,4 +1,5 @@
|
||||
import logging
|
||||
import time
|
||||
|
||||
from peewee import fn
|
||||
|
||||
@ -103,6 +104,11 @@ def create_gunicorn_worker():
|
||||
def main():
|
||||
logging.config.fileConfig(logfile_path(debug=False), disable_existing_loggers=False)
|
||||
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
if not features.MANIFEST_SIZE_BACKFILL:
|
||||
logger.debug("Manifest backfill worker not enabled; skipping")
|
||||
while True:
|
||||
|
@ -64,6 +64,11 @@ def create_gunicorn_worker():
|
||||
if __name__ == "__main__":
|
||||
logging.config.fileConfig(logfile_path(debug=False), disable_existing_loggers=False)
|
||||
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
if not features.NAMESPACE_GARBAGE_COLLECTION:
|
||||
logger.debug("Namespace garbage collection is disabled; skipping")
|
||||
while True:
|
||||
|
@ -1,4 +1,5 @@
|
||||
import logging
|
||||
import time
|
||||
|
||||
from app import app, notification_queue
|
||||
from notifications.notificationmethod import NotificationMethod, InvalidNotificationMethodException
|
||||
@ -55,6 +56,11 @@ def create_gunicorn_worker():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
worker = NotificationWorker(
|
||||
notification_queue, poll_period_seconds=10, reservation_seconds=30, retry_after_seconds=30
|
||||
)
|
||||
|
@ -1,4 +1,5 @@
|
||||
import logging
|
||||
import time
|
||||
|
||||
from datetime import timedelta, datetime
|
||||
|
||||
@ -51,5 +52,10 @@ def create_gunicorn_worker():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
worker = QueueCleanupWorker()
|
||||
worker.start()
|
||||
|
@ -68,6 +68,11 @@ if __name__ == "__main__":
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
if not features.REPO_MIRROR:
|
||||
logger.debug("Repository mirror disabled; skipping RepoMirrorWorker")
|
||||
while True:
|
||||
|
@ -121,6 +121,11 @@ def create_gunicorn_worker():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
if not features.REPOSITORY_ACTION_COUNTER:
|
||||
logger.info("Repository action count is disabled; skipping")
|
||||
while True:
|
||||
|
@ -70,6 +70,11 @@ def create_gunicorn_worker():
|
||||
if __name__ == "__main__":
|
||||
logging.config.fileConfig(logfile_path(debug=False), disable_existing_loggers=False)
|
||||
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
if not features.REPOSITORY_GARBAGE_COLLECTION:
|
||||
logger.info("Repository garbage collection is disabled; skipping")
|
||||
while True:
|
||||
|
@ -152,6 +152,11 @@ def create_gunicorn_worker():
|
||||
if __name__ == "__main__":
|
||||
logging.config.fileConfig(logfile_path(debug=False), disable_existing_loggers=False)
|
||||
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
if not features.SECURITY_SCANNER:
|
||||
logger.debug("Security scanner disabled; sleeping")
|
||||
while True:
|
||||
|
@ -57,6 +57,11 @@ if __name__ == "__main__":
|
||||
|
||||
app.register_blueprint(v2_bp, url_prefix="/v2")
|
||||
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
if not features.SECURITY_SCANNER:
|
||||
logger.debug("Security scanner disabled; skipping SecurityWorker")
|
||||
while True:
|
||||
|
@ -202,6 +202,11 @@ if __name__ == "__main__":
|
||||
|
||||
has_local_storage = False
|
||||
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
if features.STORAGE_REPLICATION:
|
||||
for storage_type, _ in list(app.config.get("DISTRIBUTED_STORAGE_CONFIG", {}).values()):
|
||||
if storage_type == "LocalStorage":
|
||||
|
@ -47,6 +47,11 @@ def create_gunicorn_worker():
|
||||
def main():
|
||||
logging.config.fileConfig(logfile_path(debug=False), disable_existing_loggers=False)
|
||||
|
||||
if app.config.get("ACCOUNT_RECOVERY_MODE", False):
|
||||
logger.debug("Quay running in account recovery mode")
|
||||
while True:
|
||||
time.sleep(100000)
|
||||
|
||||
if not features.TEAM_SYNCING or not authentication.federated_service:
|
||||
logger.debug("Team syncing is disabled; sleeping")
|
||||
while True:
|
||||
|
Loading…
x
Reference in New Issue
Block a user