mirror of
https://github.com/theupdateframework/python-tuf
synced 2026-05-24 10:08:28 +00:00
Merge branch 'master' into path_hash_prefix
This commit is contained in:
commit
e86f458a2f
5 changed files with 170 additions and 36 deletions
187
tuf/log.py
187
tuf/log.py
|
|
@ -12,10 +12,9 @@
|
|||
See LICENSE for licensing information.
|
||||
|
||||
<Purpose>
|
||||
A central location for all logging-related configuration.
|
||||
This module should be imported once by the main program.
|
||||
If other modules wish to incorporate 'tuf' logging, they
|
||||
should do the following:
|
||||
A central location for all logging-related configuration. This module should
|
||||
be imported once by the main program. If other modules wish to incorporate
|
||||
'tuf' logging, they should do the following:
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger('tuf')
|
||||
|
|
@ -26,18 +25,28 @@
|
|||
instance. In this 'log.py' module, we perform the initial setup for the name
|
||||
'tuf'. The 'log.py' module should only be imported once by the main program.
|
||||
When any other module does a logging.getLogger('tuf'), it is referring to the
|
||||
same 'tuf' instance and its associated settings we set up here in 'log.py'.
|
||||
See http://docs.python.org/library/logging.html#logger-objects
|
||||
for more information.
|
||||
same 'tuf' instance, and its associated settings, set here in 'log.py'.
|
||||
See http://docs.python.org/library/logging.html#logger-objects for more
|
||||
information.
|
||||
|
||||
We use multiple handlers to process log messages in various ways and to
|
||||
configure each one independently. Instead of using one single manner of
|
||||
processing log messages, we can use two built-in handlers that have already
|
||||
been configured for us. For example, the built-in FileHandler will catch
|
||||
log message and dump them to a file. If we wanted, we could set this file
|
||||
handler to only catch CRITICAL (and greater) messages and save them to a
|
||||
file. The other stream handler would still handle DEBUG-level (and greater)
|
||||
messages.
|
||||
log messages and dump them to a file. If we wanted, we could set this file
|
||||
handler to only catch CRITICAL (and greater) messages and save them to a
|
||||
file. Other handlers (e.g., StreamHandler) could handle INFO-level
|
||||
(and greater) messages.
|
||||
|
||||
Logging Levels:
|
||||
|
||||
--Level-- --Value--
|
||||
logging.CRITICAL 50
|
||||
logging.ERROR 40
|
||||
logging.WARNING 30
|
||||
logging.INFO 20
|
||||
logging.DEBUG 10
|
||||
logging.NOTSET 0
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -45,35 +54,46 @@
|
|||
import logging
|
||||
import time
|
||||
|
||||
import tuf
|
||||
|
||||
_DEFAULT_LOG_LEVEL = logging.INFO
|
||||
# Setting a handler's log level filters only logging messages of that level
|
||||
# (and above). For example, setting the built-in StreamHandler's log level to
|
||||
# 'logging.WARNING' will cause the stream handler to only process messages
|
||||
# of levels: WARNING, ERROR, and CRITICAL.
|
||||
_DEFAULT_LOG_FILENAME = 'tuf.log'
|
||||
_DEFAULT_LOG_LEVEL = logging.DEBUG
|
||||
_DEFAULT_CONSOLE_LOG_LEVEL = logging.INFO
|
||||
_DEFAULT_FILE_LOG_LEVEL = logging.DEBUG
|
||||
|
||||
# Set the format for logging messages.
|
||||
# Example format for '_FORMAT_STRING':
|
||||
# [2013-08-13 15:21:18,068 UTC] [tuf] [INFO][_update_metadata:851@updater.py]
|
||||
_FORMAT_STRING = '[%(asctime)s UTC] [%(name)s] [%(levelname)s]'+\
|
||||
'[%(funcName)s:%(lineno)s@%(filename)s] %(message)s'
|
||||
|
||||
|
||||
logging.Formatter.converter = time.gmtime
|
||||
formatter = logging.Formatter(_FORMAT_STRING)
|
||||
|
||||
# Set the handlers for the logger.
|
||||
# The built-in stream handler will log
|
||||
# messages to 'sys.stderr' and capture
|
||||
# '_DEFAULT_LOG_LEVEL' messages.
|
||||
stream_handler = logging.StreamHandler()
|
||||
stream_handler.setLevel(_DEFAULT_LOG_LEVEL)
|
||||
stream_handler.setFormatter(formatter)
|
||||
# Set the handlers for the logger. The console handler is unset by default. A
|
||||
# module importing 'log.py' should explicitly set the console handler if
|
||||
# outputting log messages to the screen is needed. Adding a console handler
|
||||
# can be done with tuf.log.add_console_handler(). Logging messages to a file
|
||||
# *is* set by default.
|
||||
console_handler = None
|
||||
|
||||
# Set the built-in file handler. Messages
|
||||
# will be logged to '_DEFAULT_LOG_FILENAME'
|
||||
# and use the logger's default log level.
|
||||
# The file will be opened in append mode.
|
||||
# Set the built-in file handler. Messages will be logged to
|
||||
# '_DEFAULT_LOG_FILENAME', and only those messages with a log level of
|
||||
# '_DEFAULT_LOG_LEVEL'. The log level of messages handled by 'file_handler'
|
||||
# may be modified with 'set_filehandler_log_level()'. '_DEFAULT_LOG_FILENAME'
|
||||
# will be opened in append mode.
|
||||
file_handler = logging.FileHandler(_DEFAULT_LOG_FILENAME)
|
||||
file_handler.setLevel(_DEFAULT_LOG_LEVEL)
|
||||
file_handler.setFormatter(formatter)
|
||||
|
||||
# Set the logger and its settings.
|
||||
logger = logging.getLogger('tuf')
|
||||
logger.setLevel(_DEFAULT_LOG_LEVEL)
|
||||
logger.addHandler(stream_handler)
|
||||
logger.addHandler(file_handler)
|
||||
|
||||
# Silently ignore logger exceptions.
|
||||
|
|
@ -83,27 +103,132 @@
|
|||
|
||||
|
||||
|
||||
def set_log_level(log_level):
|
||||
def set_log_level(log_level=_DEFAULT_LOG_LEVEL):
|
||||
"""
|
||||
<Purpose>
|
||||
Allow the default log level to be overridden.
|
||||
|
||||
<Arguments>
|
||||
log_level:
|
||||
The log level to set for the logger and handler(s).
|
||||
E.g., logging.INFO; logging.CRITICAL.
|
||||
The log level to set for the 'log.py' file handler.
|
||||
'log_level' examples: logging.INFO; logging.CRITICAL.
|
||||
|
||||
<Exceptions>
|
||||
None.
|
||||
|
||||
<Side Effects>
|
||||
Overrides the logging level for the internal
|
||||
'logger' and 'handler'.
|
||||
Overrides the logging level for the 'log.py' file handler.
|
||||
|
||||
<Returns>
|
||||
None.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
# Does 'log_level' have the correct format?
|
||||
# Raise 'tuf.FormatError' if there is a mismatch.
|
||||
tuf.formats.LENGTH_SCHEMA.check_match(log_level)
|
||||
|
||||
logger.setLevel(log_level)
|
||||
stream_handler.setLevel(log_level)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def set_filehandler_log_level(log_level=_DEFAULT_FILE_LOG_LEVEL):
|
||||
"""
|
||||
<Purpose>
|
||||
Allow the default file handler log level to be overridden.
|
||||
|
||||
<Arguments>
|
||||
log_level:
|
||||
The log level to set for the 'log.py' file handler.
|
||||
'log_level' examples: logging.INFO; logging.CRITICAL.
|
||||
|
||||
<Exceptions>
|
||||
None.
|
||||
|
||||
<Side Effects>
|
||||
Overrides the logging level for the 'log.py' file handler.
|
||||
|
||||
<Returns>
|
||||
None.
|
||||
|
||||
"""
|
||||
|
||||
# Does 'log_level' have the correct format?
|
||||
# Raise 'tuf.FormatError' if there is a mismatch.
|
||||
tuf.formats.LENGTH_SCHEMA.check_match(log_level)
|
||||
|
||||
file_handler.setLevel(log_level)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def set_console_log_level(log_level=_DEFAULT_CONSOLE_LOG_LEVEL):
|
||||
"""
|
||||
<Purpose>
|
||||
Allow the default log level for console messages to be overridden.
|
||||
|
||||
<Arguments>
|
||||
log_level:
|
||||
The log level to set for the console handler.
|
||||
'log_level' examples: logging.INFO; logging.CRITICAL.
|
||||
|
||||
<Exceptions>
|
||||
tuf.Error, if the 'log.py' console handler has not been set yet with
|
||||
add_console_handler().
|
||||
|
||||
<Side Effects>
|
||||
Overrides the logging level for the console handler.
|
||||
|
||||
<Returns>
|
||||
None.
|
||||
|
||||
"""
|
||||
|
||||
# Does 'log_level' have the correct format?
|
||||
# Raise 'tuf.FormatError' if there is a mismatch.
|
||||
tuf.formats.LENGTH_SCHEMA.check_match(log_level)
|
||||
|
||||
if console_handler is not None:
|
||||
console_handler.setLevel(log_level)
|
||||
else:
|
||||
message = 'The console handler has not been set with add_console_handler().'
|
||||
raise tuf.Error(message)
|
||||
|
||||
|
||||
|
||||
|
||||
def add_console_handler(log_level=_DEFAULT_CONSOLE_LOG_LEVEL):
|
||||
"""
|
||||
<Purpose>
|
||||
Add a console handler and set its log level to 'log_level'.
|
||||
|
||||
<Arguments>
|
||||
log_level:
|
||||
The log level to set for the console handler.
|
||||
'log_level' examples: logging.INFO; logging.CRITICAL.
|
||||
|
||||
<Exceptions>
|
||||
None.
|
||||
|
||||
<Side Effects>
|
||||
Adds a console handler to the 'log.py' logger and sets its logging level to
|
||||
'log_level'.
|
||||
|
||||
<Returns>
|
||||
None.
|
||||
|
||||
"""
|
||||
|
||||
# Does 'log_level' have the correct format?
|
||||
# Raise 'tuf.FormatError' if there is a mismatch.
|
||||
tuf.formats.LENGTH_SCHEMA.check_match(log_level)
|
||||
|
||||
# Set the console handler for the logger. The built-in console handler will
|
||||
# log messages to 'sys.stderr' and capture 'log_level' messages.
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setLevel(log_level)
|
||||
console_handler.setFormatter(formatter)
|
||||
logger.addHandler(console_handler)
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ def load_keystore_from_keyfiles(directory_name, keyids, passwords):
|
|||
<Arguments>
|
||||
directory_name:
|
||||
The name of the directory containing the key files ('<keyid>.key'),
|
||||
conformant to tuf.formats.RELPATH_SCHEMA.
|
||||
conformant to 'tuf.formats.RELPATH_SCHEMA'.
|
||||
|
||||
keyids:
|
||||
A list containing the keyids of the signing keys to load.
|
||||
|
|
@ -188,10 +188,8 @@ def load_keystore_from_keyfiles(directory_name, keyids, passwords):
|
|||
|
||||
logger.info('Loading private key(s) from '+repr(directory_name))
|
||||
|
||||
# Make sure the directory exists.
|
||||
if not os.path.exists(directory_name):
|
||||
logger.warn('...no such directory. Keystore cannot be loaded.')
|
||||
else:
|
||||
# Load the private key(s) if 'directory_name' exists, otherwise log a warning.
|
||||
if os.path.exists(directory_name):
|
||||
# Decrypt the keys we can from those stored in 'keyids'.
|
||||
for keyid in keyids:
|
||||
try:
|
||||
|
|
@ -243,7 +241,11 @@ def load_keystore_from_keyfiles(directory_name, keyids, passwords):
|
|||
logger.warn(repr(full_filepath)+' contains an invalid key type.')
|
||||
continue
|
||||
|
||||
else:
|
||||
logger.warn('...no such directory. Keystore cannot be loaded.')
|
||||
|
||||
logger.info('Done.')
|
||||
|
||||
return loaded_keys
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,12 +19,19 @@
|
|||
import unittest
|
||||
import shutil
|
||||
import os
|
||||
import logging
|
||||
|
||||
import tuf.repo.keystore
|
||||
import tuf.rsa_key
|
||||
import tuf.formats
|
||||
import tuf.util
|
||||
|
||||
logger = logging.getLogger('tuf')
|
||||
|
||||
# Disable all logging calls of level CRITICAL and below.
|
||||
# Comment the line below to enable logging.
|
||||
logging.disable(logging.CRITICAL)
|
||||
|
||||
# We'll need json module for testing '_encrypt()' and '_decrypt()'
|
||||
# internal function.
|
||||
json = tuf.util.import_json()
|
||||
|
|
|
|||
0
tuf/tests/test_push.py
Normal file → Executable file
0
tuf/tests/test_push.py
Normal file → Executable file
0
tuf/tests/test_pushtoolslib.py
Normal file → Executable file
0
tuf/tests/test_pushtoolslib.py
Normal file → Executable file
Loading…
Reference in a new issue