mirror of https://github.com/nucypher/nucypher.git
Merge pull request #665 from KPrasch/fix-demo
Heartbeat Demo Compatibility: Storage Defaults, File-based Temp DBpull/672/head
commit
c5bbcd01fc
|
@ -23,12 +23,10 @@ POLICY_FILENAME = "policy-metadata.json"
|
||||||
# # Twisted Logger
|
# # Twisted Logger
|
||||||
globalLogPublisher.addObserver(SimpleObserver())
|
globalLogPublisher.addObserver(SimpleObserver())
|
||||||
#
|
#
|
||||||
# # Temporary file storage
|
TEMP_ALICE_DIR = "alicia-files".format(os.path.dirname(os.path.abspath(__file__)))
|
||||||
TEMP_ALICE_DIR = "{}/alicia-files".format(os.path.dirname(os.path.abspath(__file__)))
|
|
||||||
TEMP_URSULA_CERTIFICATE_DIR = "{}/ursula-certs".format(TEMP_ALICE_DIR)
|
|
||||||
|
|
||||||
# We expect the url of the seednode as the first argument.
|
# We expect the url of the seednode as the first argument.
|
||||||
SEEDNODE_URL = sys.argv[1]
|
SEEDNODE_URL = 'localhost:11500'
|
||||||
|
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
|
@ -37,9 +35,11 @@ SEEDNODE_URL = sys.argv[1]
|
||||||
|
|
||||||
|
|
||||||
# We get a persistent Alice.
|
# We get a persistent Alice.
|
||||||
|
# If we had an existing Alicia in disk, let's get it from there
|
||||||
|
|
||||||
passphrase = "TEST_ALICIA_INSECURE_DEVELOPMENT_PASSWORD"
|
passphrase = "TEST_ALICIA_INSECURE_DEVELOPMENT_PASSWORD"
|
||||||
try: # If we had an existing Alicia in disk, let's get it from there
|
try:
|
||||||
alice_config_file = os.path.join(TEMP_ALICE_DIR, "config_root", "alice.config")
|
alice_config_file = os.path.join(TEMP_ALICE_DIR, "alice.config")
|
||||||
new_alice_config = AliceConfiguration.from_configuration_file(
|
new_alice_config = AliceConfiguration.from_configuration_file(
|
||||||
filepath=alice_config_file,
|
filepath=alice_config_file,
|
||||||
network_middleware=RestMiddleware(),
|
network_middleware=RestMiddleware(),
|
||||||
|
@ -47,25 +47,29 @@ try: # If we had an existing Alicia in disk, let's get it from there
|
||||||
save_metadata=False,
|
save_metadata=False,
|
||||||
)
|
)
|
||||||
alicia = new_alice_config(passphrase=passphrase)
|
alicia = new_alice_config(passphrase=passphrase)
|
||||||
except: # If anything fails, let's create Alicia from scratch
|
|
||||||
|
except:
|
||||||
|
|
||||||
|
# If anything fails, let's create Alicia from scratch
|
||||||
# Remove previous demo files and create new ones
|
# Remove previous demo files and create new ones
|
||||||
|
|
||||||
shutil.rmtree(TEMP_ALICE_DIR, ignore_errors=True)
|
shutil.rmtree(TEMP_ALICE_DIR, ignore_errors=True)
|
||||||
os.mkdir(TEMP_ALICE_DIR)
|
|
||||||
os.mkdir(TEMP_URSULA_CERTIFICATE_DIR)
|
|
||||||
|
|
||||||
ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URL,
|
ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URL,
|
||||||
federated_only=True,
|
federated_only=True,
|
||||||
minimum_stake=0)
|
minimum_stake=0)
|
||||||
|
|
||||||
alice_config = AliceConfiguration(
|
alice_config = AliceConfiguration(
|
||||||
config_root=os.path.join(TEMP_ALICE_DIR, "config_root"),
|
config_root=os.path.join(TEMP_ALICE_DIR),
|
||||||
is_me=True,
|
is_me=True,
|
||||||
known_nodes={ursula},
|
known_nodes={ursula},
|
||||||
start_learning_now=False,
|
start_learning_now=False,
|
||||||
federated_only=True,
|
federated_only=True,
|
||||||
learn_on_same_thread=True,
|
learn_on_same_thread=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
alice_config.initialize(password=passphrase)
|
alice_config.initialize(password=passphrase)
|
||||||
|
|
||||||
alice_config.keyring.unlock(password=passphrase)
|
alice_config.keyring.unlock(password=passphrase)
|
||||||
alicia = alice_config.produce()
|
alicia = alice_config.produce()
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,9 @@ from timeit import default_timer as timer
|
||||||
|
|
||||||
from nucypher.characters.lawful import Bob, Ursula
|
from nucypher.characters.lawful import Bob, Ursula
|
||||||
from nucypher.crypto.kits import UmbralMessageKit
|
from nucypher.crypto.kits import UmbralMessageKit
|
||||||
from nucypher.crypto.powers import EncryptingPower, SigningPower
|
from nucypher.crypto.powers import DecryptingPower, SigningPower
|
||||||
from nucypher.data_sources import DataSource
|
from nucypher.data_sources import DataSource
|
||||||
from nucypher.keystore.keypairs import EncryptingKeypair, SigningKeypair
|
from nucypher.keystore.keypairs import DecryptingKeypair, SigningKeypair
|
||||||
from nucypher.network.middleware import RestMiddleware
|
from nucypher.network.middleware import RestMiddleware
|
||||||
|
|
||||||
from umbral.keys import UmbralPublicKey
|
from umbral.keys import UmbralPublicKey
|
||||||
|
@ -21,22 +21,15 @@ from umbral.keys import UmbralPublicKey
|
||||||
# Boring setup stuff #
|
# Boring setup stuff #
|
||||||
######################
|
######################
|
||||||
|
|
||||||
SEEDNODE_URL = sys.argv[1]
|
SEEDNODE_URL = 'localhost:11501'
|
||||||
|
|
||||||
# TODO: path joins?
|
# TODO: path joins?
|
||||||
TEMP_DOCTOR_DIR = "{}/doctor-files".format(os.path.dirname(os.path.abspath(__file__)))
|
TEMP_DOCTOR_DIR = "{}/doctor-files".format(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
TEMP_URSULA_CERTIFICATE_DIR = "{}/ursula-certs".format(TEMP_DOCTOR_DIR)
|
|
||||||
TEMP_DOCTOR_CERTIFICATE_DIR = "{}/doctor-certs".format(TEMP_DOCTOR_DIR)
|
|
||||||
|
|
||||||
# Remove previous demo files and create new ones
|
# Remove previous demo files and create new ones
|
||||||
shutil.rmtree(TEMP_DOCTOR_DIR, ignore_errors=True)
|
shutil.rmtree(TEMP_DOCTOR_DIR, ignore_errors=True)
|
||||||
os.mkdir(TEMP_DOCTOR_DIR)
|
|
||||||
os.mkdir(TEMP_URSULA_CERTIFICATE_DIR)
|
|
||||||
os.mkdir(TEMP_DOCTOR_CERTIFICATE_DIR)
|
|
||||||
|
|
||||||
ursula = Ursula.from_seed_and_stake_info(host=SEEDNODE_URL,
|
ursula = Ursula.from_seed_and_stake_info(seed_uri=SEEDNODE_URL,
|
||||||
certificates_directory=TEMP_URSULA_CERTIFICATE_DIR,
|
|
||||||
federated_only=True,
|
federated_only=True,
|
||||||
minimum_stake=0)
|
minimum_stake=0)
|
||||||
|
|
||||||
|
@ -44,9 +37,9 @@ ursula = Ursula.from_seed_and_stake_info(host=SEEDNODE_URL,
|
||||||
from doctor_keys import get_doctor_privkeys
|
from doctor_keys import get_doctor_privkeys
|
||||||
doctor_keys = get_doctor_privkeys()
|
doctor_keys = get_doctor_privkeys()
|
||||||
|
|
||||||
bob_enc_keypair = EncryptingKeypair(private_key=doctor_keys["enc"])
|
bob_enc_keypair = DecryptingKeypair(private_key=doctor_keys["enc"])
|
||||||
bob_sig_keypair = SigningKeypair(private_key=doctor_keys["sig"])
|
bob_sig_keypair = SigningKeypair(private_key=doctor_keys["sig"])
|
||||||
enc_power = EncryptingPower(keypair=bob_enc_keypair)
|
enc_power = DecryptingPower(keypair=bob_enc_keypair)
|
||||||
sig_power = SigningPower(keypair=bob_sig_keypair)
|
sig_power = SigningPower(keypair=bob_sig_keypair)
|
||||||
power_ups = [enc_power, sig_power]
|
power_ups = [enc_power, sig_power]
|
||||||
|
|
||||||
|
@ -57,7 +50,6 @@ doctor = Bob(
|
||||||
federated_only=True,
|
federated_only=True,
|
||||||
crypto_power_ups=power_ups,
|
crypto_power_ups=power_ups,
|
||||||
start_learning_now=True,
|
start_learning_now=True,
|
||||||
known_certificates_dir=TEMP_DOCTOR_CERTIFICATE_DIR,
|
|
||||||
abort_on_learning_error=True,
|
abort_on_learning_error=True,
|
||||||
known_nodes=[ursula],
|
known_nodes=[ursula],
|
||||||
save_metadata=False,
|
save_metadata=False,
|
||||||
|
|
|
@ -707,7 +707,7 @@ class Ursula(Teacher, Character, Miner):
|
||||||
seed_uri: str,
|
seed_uri: str,
|
||||||
federated_only: bool,
|
federated_only: bool,
|
||||||
minimum_stake: int = 0,
|
minimum_stake: int = 0,
|
||||||
checksum_address: str = None,
|
checksum_address: str = None, # TODO: Why is this unused?
|
||||||
network_middleware: RestMiddleware = None,
|
network_middleware: RestMiddleware = None,
|
||||||
*args,
|
*args,
|
||||||
**kwargs
|
**kwargs
|
||||||
|
|
|
@ -17,16 +17,17 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
|
|
||||||
import click
|
import click
|
||||||
import shutil
|
|
||||||
from constant_sorrow.constants import NO_BLOCKCHAIN_CONNECTION, NO_PASSWORD
|
|
||||||
from constant_sorrow.constants import TEMPORARY_DOMAIN
|
|
||||||
from nacl.exceptions import CryptoError
|
from nacl.exceptions import CryptoError
|
||||||
from twisted.internet import stdio
|
from twisted.internet import stdio
|
||||||
from twisted.logger import Logger
|
from twisted.logger import Logger
|
||||||
from twisted.logger import globalLogPublisher
|
from twisted.logger import globalLogPublisher
|
||||||
|
|
||||||
|
from constant_sorrow import constants
|
||||||
|
from constant_sorrow.constants import NO_BLOCKCHAIN_CONNECTION, NO_PASSWORD
|
||||||
|
from constant_sorrow.constants import TEMPORARY_DOMAIN
|
||||||
from nucypher.blockchain.eth.constants import MIN_LOCKED_PERIODS, MAX_MINTING_PERIODS
|
from nucypher.blockchain.eth.constants import MIN_LOCKED_PERIODS, MAX_MINTING_PERIODS
|
||||||
from nucypher.blockchain.eth.registry import EthereumContractRegistry
|
from nucypher.blockchain.eth.registry import EthereumContractRegistry
|
||||||
from nucypher.characters.lawful import Ursula
|
from nucypher.characters.lawful import Ursula
|
||||||
|
@ -341,9 +342,15 @@ Delete {}?'''.format(ursula_config.config_root), abort=True)
|
||||||
# Authenticated Configurations
|
# Authenticated Configurations
|
||||||
else:
|
else:
|
||||||
|
|
||||||
# Restore configuration from file
|
# Deserialize network domain name if override passed
|
||||||
|
if network:
|
||||||
|
domain_constant = getattr(constants, network.upper())
|
||||||
|
domains = {domain_constant}
|
||||||
|
else:
|
||||||
|
domains = None
|
||||||
|
|
||||||
ursula_config = UrsulaConfiguration.from_configuration_file(filepath=config_file,
|
ursula_config = UrsulaConfiguration.from_configuration_file(filepath=config_file,
|
||||||
domains={network} if network else None,
|
domains=domains,
|
||||||
registry_filepath=registry_filepath,
|
registry_filepath=registry_filepath,
|
||||||
provider_uri=provider_uri,
|
provider_uri=provider_uri,
|
||||||
rest_host=rest_host,
|
rest_host=rest_host,
|
||||||
|
|
|
@ -21,7 +21,6 @@ import os
|
||||||
from constant_sorrow.constants import (
|
from constant_sorrow.constants import (
|
||||||
UNINITIALIZED_CONFIGURATION
|
UNINITIALIZED_CONFIGURATION
|
||||||
)
|
)
|
||||||
|
|
||||||
from nucypher.config.constants import DEFAULT_CONFIG_ROOT
|
from nucypher.config.constants import DEFAULT_CONFIG_ROOT
|
||||||
from nucypher.config.keyring import NucypherKeyring
|
from nucypher.config.keyring import NucypherKeyring
|
||||||
from nucypher.config.node import NodeConfiguration
|
from nucypher.config.node import NodeConfiguration
|
||||||
|
@ -41,8 +40,6 @@ class UrsulaConfiguration(NodeConfiguration):
|
||||||
dev_mode: bool = False,
|
dev_mode: bool = False,
|
||||||
db_filepath: str = None,
|
db_filepath: str = None,
|
||||||
*args, **kwargs) -> None:
|
*args, **kwargs) -> None:
|
||||||
if dev_mode is True:
|
|
||||||
db_filepath = ':memory:' # sqlite in-memory db
|
|
||||||
self.db_filepath = db_filepath or UNINITIALIZED_CONFIGURATION
|
self.db_filepath = db_filepath or UNINITIALIZED_CONFIGURATION
|
||||||
super().__init__(dev_mode=dev_mode, *args, **kwargs)
|
super().__init__(dev_mode=dev_mode, *args, **kwargs)
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,20 @@ import binascii
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import secrets
|
import secrets
|
||||||
|
import shutil
|
||||||
import string
|
import string
|
||||||
from abc import ABC
|
from abc import ABC
|
||||||
from json import JSONDecodeError
|
from json import JSONDecodeError
|
||||||
from tempfile import TemporaryDirectory
|
from tempfile import TemporaryDirectory
|
||||||
|
from typing import List, Set
|
||||||
|
|
||||||
import shutil
|
from cryptography.hazmat.primitives.asymmetric import ec
|
||||||
|
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve
|
||||||
|
from cryptography.x509 import Certificate
|
||||||
|
from twisted.logger import Logger
|
||||||
|
from umbral.signing import Signature
|
||||||
|
|
||||||
|
from constant_sorrow import constants
|
||||||
from constant_sorrow.constants import GLOBAL_DOMAIN
|
from constant_sorrow.constants import GLOBAL_DOMAIN
|
||||||
from constant_sorrow.constants import (
|
from constant_sorrow.constants import (
|
||||||
UNINITIALIZED_CONFIGURATION,
|
UNINITIALIZED_CONFIGURATION,
|
||||||
|
@ -34,13 +42,6 @@ from constant_sorrow.constants import (
|
||||||
LIVE_CONFIGURATION,
|
LIVE_CONFIGURATION,
|
||||||
NO_KEYRING_ATTACHED
|
NO_KEYRING_ATTACHED
|
||||||
)
|
)
|
||||||
from cryptography.hazmat.primitives.asymmetric import ec
|
|
||||||
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve
|
|
||||||
from cryptography.x509 import Certificate
|
|
||||||
from twisted.logger import Logger
|
|
||||||
from typing import List, Set
|
|
||||||
from umbral.signing import Signature
|
|
||||||
|
|
||||||
from nucypher.blockchain.eth.agents import PolicyAgent, MinerAgent, NucypherTokenAgent
|
from nucypher.blockchain.eth.agents import PolicyAgent, MinerAgent, NucypherTokenAgent
|
||||||
from nucypher.blockchain.eth.chains import Blockchain
|
from nucypher.blockchain.eth.chains import Blockchain
|
||||||
from nucypher.config.constants import DEFAULT_CONFIG_ROOT, BASE_DIR, USER_LOG_DIR
|
from nucypher.config.constants import DEFAULT_CONFIG_ROOT, BASE_DIR, USER_LOG_DIR
|
||||||
|
@ -64,6 +65,8 @@ class NodeConfiguration(ABC):
|
||||||
|
|
||||||
# Mode
|
# Mode
|
||||||
DEFAULT_OPERATING_MODE = 'decentralized'
|
DEFAULT_OPERATING_MODE = 'decentralized'
|
||||||
|
|
||||||
|
# Domains
|
||||||
DEFAULT_DOMAIN = GLOBAL_DOMAIN
|
DEFAULT_DOMAIN = GLOBAL_DOMAIN
|
||||||
|
|
||||||
# Serializers
|
# Serializers
|
||||||
|
@ -76,7 +79,7 @@ class NodeConfiguration(ABC):
|
||||||
TEMP_CONFIGURATION_DIR_PREFIX = "nucypher-tmp-"
|
TEMP_CONFIGURATION_DIR_PREFIX = "nucypher-tmp-"
|
||||||
|
|
||||||
# Blockchain
|
# Blockchain
|
||||||
DEFAULT_PROVIDER_URI = 'tester://pyevm' # FIXME: Needs to be updated in tandem with manual providers for interface.connect
|
DEFAULT_PROVIDER_URI = 'tester://pyevm'
|
||||||
|
|
||||||
# Registry
|
# Registry
|
||||||
__REGISTRY_NAME = 'contract_registry.json'
|
__REGISTRY_NAME = 'contract_registry.json'
|
||||||
|
@ -371,7 +374,10 @@ class NodeConfiguration(ABC):
|
||||||
serializer=cls.NODE_SERIALIZER,
|
serializer=cls.NODE_SERIALIZER,
|
||||||
deserializer=cls.NODE_DESERIALIZER)
|
deserializer=cls.NODE_DESERIALIZER)
|
||||||
|
|
||||||
payload.update(dict(node_storage=node_storage, domains=set(payload['domains'])))
|
# Deserialize domains to Constants vis Constant Sorrow
|
||||||
|
domains = set(getattr(constants, domain.upper()) for domain in payload['domains'])
|
||||||
|
|
||||||
|
payload.update(dict(node_storage=node_storage, domains=domains))
|
||||||
|
|
||||||
# Filter out Nones from overrides to detect, well, overrides
|
# Filter out Nones from overrides to detect, well, overrides
|
||||||
overrides = {k: v for k, v in overrides.items() if v is not None}
|
overrides = {k: v for k, v in overrides.items() if v is not None}
|
||||||
|
@ -391,7 +397,7 @@ class NodeConfiguration(ABC):
|
||||||
del payload['is_me'] # TODO
|
del payload['is_me'] # TODO
|
||||||
|
|
||||||
# Serialize domains
|
# Serialize domains
|
||||||
domains = list(str(d) for d in self.domains)
|
domains = list(str(domain) for domain in self.domains)
|
||||||
|
|
||||||
# Save node connection data
|
# Save node connection data
|
||||||
payload.update(dict(node_storage=self.node_storage.payload(), domains=domains))
|
payload.update(dict(node_storage=self.node_storage.payload(), domains=domains))
|
||||||
|
|
|
@ -302,9 +302,7 @@ class Learner:
|
||||||
|
|
||||||
def load_seednodes(self,
|
def load_seednodes(self,
|
||||||
read_storages: bool = True,
|
read_storages: bool = True,
|
||||||
retry_attempts: int = 3,
|
retry_attempts: int = 3): # TODO: why are these unused?
|
||||||
retry_rate: int = 2,
|
|
||||||
timeout=3): # TODO: why are these unused?
|
|
||||||
"""
|
"""
|
||||||
Engage known nodes from storages and pre-fetch hardcoded seednode certificates for node learning.
|
Engage known nodes from storages and pre-fetch hardcoded seednode certificates for node learning.
|
||||||
"""
|
"""
|
||||||
|
@ -312,8 +310,9 @@ class Learner:
|
||||||
self.log.debug("Already done seeding; won't try again.")
|
self.log.debug("Already done seeding; won't try again.")
|
||||||
return
|
return
|
||||||
|
|
||||||
def __attempt_seednode_learning(seednode_metadata, current_attempt=1):
|
from nucypher.characters.lawful import Ursula
|
||||||
from nucypher.characters.lawful import Ursula
|
for seednode_metadata in self._seed_nodes:
|
||||||
|
|
||||||
self.log.debug(
|
self.log.debug(
|
||||||
"Seeding from: {}|{}:{}".format(seednode_metadata.checksum_public_address,
|
"Seeding from: {}|{}:{}".format(seednode_metadata.checksum_public_address,
|
||||||
seednode_metadata.rest_host,
|
seednode_metadata.rest_host,
|
||||||
|
@ -328,17 +327,15 @@ class Learner:
|
||||||
self.unresponsive_seed_nodes.discard(seednode_metadata)
|
self.unresponsive_seed_nodes.discard(seednode_metadata)
|
||||||
self.remember_node(seed_node)
|
self.remember_node(seed_node)
|
||||||
|
|
||||||
for seednode_metadata in self._seed_nodes:
|
if not self.unresponsive_seed_nodes:
|
||||||
__attempt_seednode_learning(seednode_metadata=seednode_metadata)
|
|
||||||
|
|
||||||
if not self.unresponsive_seed_nodes and not self.lonely:
|
|
||||||
self.log.info("Finished learning about all seednodes.")
|
self.log.info("Finished learning about all seednodes.")
|
||||||
|
|
||||||
self.done_seeding = True
|
self.done_seeding = True
|
||||||
|
|
||||||
if read_storages is True:
|
if read_storages is True:
|
||||||
self.read_nodes_from_storage()
|
self.read_nodes_from_storage()
|
||||||
|
|
||||||
if not self.known_nodes and not self.lonely:
|
if not self.known_nodes:
|
||||||
self.log.warn("No seednodes were available after {} attempts".format(retry_attempts))
|
self.log.warn("No seednodes were available after {} attempts".format(retry_attempts))
|
||||||
# TODO: Need some actual logic here for situation with no seed nodes (ie, maybe try again much later)
|
# TODO: Need some actual logic here for situation with no seed nodes (ie, maybe try again much later)
|
||||||
|
|
||||||
|
@ -401,8 +398,14 @@ class Learner:
|
||||||
return False
|
return False
|
||||||
elif now:
|
elif now:
|
||||||
self.log.info("Starting Learning Loop NOW.")
|
self.log.info("Starting Learning Loop NOW.")
|
||||||
if not self.lonely:
|
|
||||||
|
if self.lonely:
|
||||||
|
self.done_seeding = True
|
||||||
|
self.read_nodes_from_storage()
|
||||||
|
|
||||||
|
else:
|
||||||
self.load_seednodes()
|
self.load_seednodes()
|
||||||
|
|
||||||
self.learn_from_teacher_node()
|
self.learn_from_teacher_node()
|
||||||
self.learning_deferred = self._learning_task.start(interval=self._SHORT_LEARNING_DELAY)
|
self.learning_deferred = self._learning_task.start(interval=self._SHORT_LEARNING_DELAY)
|
||||||
self.learning_deferred.addErrback(self.handle_learning_errors)
|
self.learning_deferred.addErrback(self.handle_learning_errors)
|
||||||
|
@ -458,7 +461,7 @@ class Learner:
|
||||||
self.teacher_nodes.extend(nodes_we_know_about)
|
self.teacher_nodes.extend(nodes_we_know_about)
|
||||||
|
|
||||||
def cycle_teacher_node(self):
|
def cycle_teacher_node(self):
|
||||||
# To ensure that all the best teachers are availalble, first let's make sure
|
# To ensure that all the best teachers are available, first let's make sure
|
||||||
# that we have connected to all the seed nodes.
|
# that we have connected to all the seed nodes.
|
||||||
if self.unresponsive_seed_nodes and not self.lonely:
|
if self.unresponsive_seed_nodes and not self.lonely:
|
||||||
self.log.info("Still have unresponsive seed nodes; trying again to connect.")
|
self.log.info("Still have unresponsive seed nodes; trying again to connect.")
|
||||||
|
@ -666,7 +669,8 @@ class Learner:
|
||||||
# In this case, this node knows about no other nodes. Hopefully we've taught it something.
|
# In this case, this node knows about no other nodes. Hopefully we've taught it something.
|
||||||
if response.content == b"":
|
if response.content == b"":
|
||||||
return NO_KNOWN_NODES
|
return NO_KNOWN_NODES
|
||||||
# In the other case - where the status code is 204 but the repsonse isn't blank - we'll keep parsing. It's possible that our fleet states match, and we'll check for that later.
|
# In the other case - where the status code is 204 but the repsonse isn't blank - we'll keep parsing.
|
||||||
|
# It's possible that our fleet states match, and we'll check for that later.
|
||||||
|
|
||||||
elif response.status_code != 200:
|
elif response.status_code != 200:
|
||||||
self.log.info("Bad response from teacher {}: {} - {}".format(current_teacher, response, response.content))
|
self.log.info("Bad response from teacher {}: {} - {}".format(current_teacher, response, response.content))
|
||||||
|
|
|
@ -147,8 +147,12 @@ class ProxyRESTRoutes:
|
||||||
self.log.info("Starting datastore {}".format(self.db_filepath))
|
self.log.info("Starting datastore {}".format(self.db_filepath))
|
||||||
|
|
||||||
# See: https://docs.sqlalchemy.org/en/rel_0_9/dialects/sqlite.html#connect-strings
|
# See: https://docs.sqlalchemy.org/en/rel_0_9/dialects/sqlite.html#connect-strings
|
||||||
db_filepath = (self.db_filepath or '') # Capture None
|
if self.db_filepath:
|
||||||
engine = create_engine('sqlite:///{}'.format(db_filepath))
|
db_uri = f'sqlite:///{self.db_filepath}'
|
||||||
|
else:
|
||||||
|
db_uri = 'sqlite://' # TODO: Is this a sane default? See #667
|
||||||
|
|
||||||
|
engine = create_engine(db_uri)
|
||||||
|
|
||||||
Base.metadata.create_all(engine)
|
Base.metadata.create_all(engine)
|
||||||
self.datastore = keystore.KeyStore(engine)
|
self.datastore = keystore.KeyStore(engine)
|
||||||
|
|
|
@ -42,7 +42,6 @@ def test_run_lone_federated_default_development_ursula(click_runner):
|
||||||
|
|
||||||
time.sleep(Learner._SHORT_LEARNING_DELAY)
|
time.sleep(Learner._SHORT_LEARNING_DELAY)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert ":memory:" in result.output
|
|
||||||
assert "Running Ursula on 127.0.0.1:{}".format(MOCK_URSULA_STARTING_PORT)
|
assert "Running Ursula on 127.0.0.1:{}".format(MOCK_URSULA_STARTING_PORT)
|
||||||
|
|
||||||
reserved_ports = (NodeConfiguration.DEFAULT_REST_PORT, NodeConfiguration.DEFAULT_DEVELOPMENT_REST_PORT)
|
reserved_ports = (NodeConfiguration.DEFAULT_REST_PORT, NodeConfiguration.DEFAULT_DEVELOPMENT_REST_PORT)
|
||||||
|
|
|
@ -25,7 +25,7 @@ def test_ursula_development_configuration(federated_only=True):
|
||||||
# A Temporary Ursula
|
# A Temporary Ursula
|
||||||
port = ursula_one.rest_information()[0].port
|
port = ursula_one.rest_information()[0].port
|
||||||
assert port == UrsulaConfiguration.DEFAULT_DEVELOPMENT_REST_PORT
|
assert port == UrsulaConfiguration.DEFAULT_DEVELOPMENT_REST_PORT
|
||||||
assert ursula_one.datastore.engine.url.database == ":memory:"
|
assert '/tmp' in ursula_one.datastore.engine.url.database
|
||||||
assert ursula_one.certificate_filepath is CERTIFICATE_NOT_SAVED
|
assert ursula_one.certificate_filepath is CERTIFICATE_NOT_SAVED
|
||||||
assert UrsulaConfiguration.TEMP_CONFIGURATION_DIR_PREFIX in ursula_one.keyring_dir
|
assert UrsulaConfiguration.TEMP_CONFIGURATION_DIR_PREFIX in ursula_one.keyring_dir
|
||||||
assert isinstance(ursula_one.node_storage, ForgetfulNodeStorage)
|
assert isinstance(ursula_one.node_storage, ForgetfulNodeStorage)
|
||||||
|
|
Loading…
Reference in New Issue