Compare commits

..

No commits in common. "main" and "v1.1.0-0c47da4-202410210702" have entirely different histories.

6 changed files with 60 additions and 142 deletions

View File

@ -360,9 +360,6 @@ def dump_known_requests(filename, requests, status="SEEN"):
@click.option( @click.option(
"--private-key-file", help="The private key for decrypting config.", required=True "--private-key-file", help="The private key for decrypting config.", required=True
) )
@click.option(
"--registry-lock-file", help="File path to use for registry mutex lock", default=None
)
@click.option( @click.option(
"--private-key-passphrase", "--private-key-passphrase",
help="The passphrase for the private key.", help="The passphrase for the private key.",
@ -396,7 +393,6 @@ def command( # noqa: C901
private_key_passphrase, private_key_passphrase,
all_requests, all_requests,
auction_requests, auction_requests,
registry_lock_file,
): ):
if request_id and discover: if request_id and discover:
print("Cannot specify both --request-id and --discover", file=sys.stderr) print("Cannot specify both --request-id and --discover", file=sys.stderr)
@ -448,7 +444,7 @@ def command( # noqa: C901
include_tags = [tag.strip() for tag in include_tags.split(",") if tag] include_tags = [tag.strip() for tag in include_tags.split(",") if tag]
exclude_tags = [tag.strip() for tag in exclude_tags.split(",") if tag] exclude_tags = [tag.strip() for tag in exclude_tags.split(",") if tag]
laconic = LaconicRegistryClient(laconic_config, log_file=sys.stderr, mutex_lock_file=registry_lock_file) laconic = LaconicRegistryClient(laconic_config, log_file=sys.stderr)
webapp_deployer_record = laconic.get_record(lrn, require=True) webapp_deployer_record = laconic.get_record(lrn, require=True)
payment_address = webapp_deployer_record.attributes.paymentAddress payment_address = webapp_deployer_record.attributes.paymentAddress
main_logger.log(f"Payment address: {payment_address}") main_logger.log(f"Payment address: {payment_address}")
@ -653,7 +649,7 @@ def command( # noqa: C901
) )
run_log_file = open(run_log_file_path, "wt") run_log_file = open(run_log_file_path, "wt")
run_reg_client = LaconicRegistryClient( run_reg_client = LaconicRegistryClient(
laconic_config, log_file=run_log_file, mutex_lock_file=registry_lock_file laconic_config, log_file=run_log_file
) )
build_logger = TimedLogger(run_id, run_log_file) build_logger = TimedLogger(run_id, run_log_file)

View File

@ -120,9 +120,6 @@ def dump_known_auction_requests(filename, requests, status="SEEN"):
help="Bid to place on application deployment auctions (in alnt)", help="Bid to place on application deployment auctions (in alnt)",
required=True, required=True,
) )
@click.option(
"--registry-lock-file", help="File path to use for registry mutex lock", default=None
)
@click.option( @click.option(
"--dry-run", help="Don't do anything, just report what would be done.", is_flag=True "--dry-run", help="Don't do anything, just report what would be done.", is_flag=True
) )
@ -132,7 +129,6 @@ def command(
laconic_config, laconic_config,
state_file, state_file,
bid_amount, bid_amount,
registry_lock_file,
dry_run, dry_run,
): ):
if int(bid_amount) < 0: if int(bid_amount) < 0:
@ -142,7 +138,7 @@ def command(
logger = TimedLogger(file=sys.stderr) logger = TimedLogger(file=sys.stderr)
try: try:
laconic = LaconicRegistryClient(laconic_config, log_file=sys.stderr, mutex_lock_file=registry_lock_file) laconic = LaconicRegistryClient(laconic_config, log_file=sys.stderr)
auctions_requests = laconic.app_deployment_auctions() auctions_requests = laconic.app_deployment_auctions()
previous_requests = {} previous_requests = {}

View File

@ -102,7 +102,7 @@ def command(
"max_price": max_price, "max_price": max_price,
"num_providers": num_providers, "num_providers": num_providers,
} }
auction_id = laconic.create_deployment_auction(provider_auction_params) auction_id = laconic.create_auction(provider_auction_params)
print("Deployment auction created:", auction_id) print("Deployment auction created:", auction_id)
if not auction_id: if not auction_id:

View File

@ -1,77 +0,0 @@
from functools import wraps
import os
import time
# Define default file path for the lock
DEFAULT_LOCK_FILE_PATH = "/tmp/registry_mutex_lock_file"
LOCK_TIMEOUT = 30
LOCK_RETRY_INTERVAL = 3
def acquire_lock(client, lock_file_path, timeout):
# Lock alreay acquired by the current client
if client.mutex_lock_acquired:
return
while True:
try:
# Check if lock file exists and is potentially stale
if os.path.exists(lock_file_path):
with open(lock_file_path, 'r') as lock_file:
timestamp = float(lock_file.read().strip())
# If lock is stale, remove the lock file
if time.time() - timestamp > timeout:
print(f"Stale lock detected, removing lock file {lock_file_path}")
os.remove(lock_file_path)
else:
print(f"Lock file {lock_file_path} exists and is recent, waiting...")
time.sleep(LOCK_RETRY_INTERVAL)
continue
# Try to create a new lock file with the current timestamp
fd = os.open(lock_file_path, os.O_CREAT | os.O_EXCL | os.O_RDWR)
with os.fdopen(fd, 'w') as lock_file:
lock_file.write(str(time.time()))
client.mutex_lock_acquired = True
print(f"Registry lock acquired, {lock_file_path}")
# Lock successfully acquired
return
except FileExistsError:
print(f"Lock file {lock_file_path} exists, waiting...")
time.sleep(LOCK_RETRY_INTERVAL)
def release_lock(client, lock_file_path):
try:
os.remove(lock_file_path)
client.mutex_lock_acquired = False
print(f"Registry lock released, {lock_file_path}")
except FileNotFoundError:
# Lock file already removed
pass
def registry_mutex():
def decorator(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
lock_file_path = DEFAULT_LOCK_FILE_PATH
if self.mutex_lock_file:
lock_file_path = self.mutex_lock_file
# Acquire the lock before running the function
acquire_lock(self, lock_file_path, LOCK_TIMEOUT)
try:
return func(self, *args, **kwargs)
finally:
# Release the lock after the function completes
release_lock(self, lock_file_path)
return wrapper
return decorator

View File

@ -178,9 +178,6 @@ def dump_known_requests(filename, requests):
"my payment address are examined).", "my payment address are examined).",
is_flag=True, is_flag=True,
) )
@click.option(
"--registry-lock-file", help="File path to use for registry mutex lock", default=None
)
@click.pass_context @click.pass_context
def command( # noqa: C901 def command( # noqa: C901
ctx, ctx,
@ -198,7 +195,6 @@ def command( # noqa: C901
min_required_payment, min_required_payment,
lrn, lrn,
all_requests, all_requests,
registry_lock_file,
): ):
if request_id and discover: if request_id and discover:
print("Cannot specify both --request-id and --discover", file=sys.stderr) print("Cannot specify both --request-id and --discover", file=sys.stderr)
@ -216,7 +212,7 @@ def command( # noqa: C901
include_tags = [tag.strip() for tag in include_tags.split(",") if tag] include_tags = [tag.strip() for tag in include_tags.split(",") if tag]
exclude_tags = [tag.strip() for tag in exclude_tags.split(",") if tag] exclude_tags = [tag.strip() for tag in exclude_tags.split(",") if tag]
laconic = LaconicRegistryClient(laconic_config, log_file=sys.stderr, mutex_lock_file=registry_lock_file) laconic = LaconicRegistryClient(laconic_config, log_file=sys.stderr)
deployer_record = laconic.get_record(lrn, require=True) deployer_record = laconic.get_record(lrn, require=True)
payment_address = deployer_record.attributes.paymentAddress payment_address = deployer_record.attributes.paymentAddress
main_logger.log(f"Payment address: {payment_address}") main_logger.log(f"Payment address: {payment_address}")

View File

@ -26,8 +26,6 @@ import yaml
from enum import Enum from enum import Enum
from stack_orchestrator.deploy.webapp.registry_mutex import registry_mutex
class AuctionStatus(str, Enum): class AuctionStatus(str, Enum):
COMMIT = "commit" COMMIT = "commit"
@ -114,7 +112,7 @@ def is_id(name_or_id: str):
class LaconicRegistryClient: class LaconicRegistryClient:
def __init__(self, config_file, log_file=None, mutex_lock_file=None): def __init__(self, config_file, log_file=None):
self.config_file = config_file self.config_file = config_file
self.log_file = log_file self.log_file = log_file
self.cache = AttrDict( self.cache = AttrDict(
@ -125,9 +123,6 @@ class LaconicRegistryClient:
} }
) )
self.mutex_lock_file = mutex_lock_file
self.mutex_lock_acquired = False
def whoami(self, refresh=False): def whoami(self, refresh=False):
if not refresh and "whoami" in self.cache: if not refresh and "whoami" in self.cache:
return self.cache["whoami"] return self.cache["whoami"]
@ -396,7 +391,6 @@ class LaconicRegistryClient:
criteria["type"] = "ApplicationDeploymentAuction" criteria["type"] = "ApplicationDeploymentAuction"
return self.list_records(criteria, all) return self.list_records(criteria, all)
@registry_mutex()
def publish(self, record, names=None): def publish(self, record, names=None):
if names is None: if names is None:
names = [] names = []
@ -427,7 +421,6 @@ class LaconicRegistryClient:
finally: finally:
logged_cmd(self.log_file, "rm", "-rf", tmpdir) logged_cmd(self.log_file, "rm", "-rf", tmpdir)
@registry_mutex()
def set_name(self, name, record_id): def set_name(self, name, record_id):
logged_cmd( logged_cmd(
self.log_file, self.log_file,
@ -441,7 +434,6 @@ class LaconicRegistryClient:
record_id, record_id,
) )
@registry_mutex()
def delete_name(self, name): def delete_name(self, name):
logged_cmd( logged_cmd(
self.log_file, self.log_file,
@ -454,7 +446,6 @@ class LaconicRegistryClient:
name, name,
) )
@registry_mutex()
def send_tokens(self, address, amount, type="alnt"): def send_tokens(self, address, amount, type="alnt"):
args = [ args = [
"laconic", "laconic",
@ -473,36 +464,58 @@ class LaconicRegistryClient:
return AttrDict(json.loads(logged_cmd(self.log_file, *args))) return AttrDict(json.loads(logged_cmd(self.log_file, *args)))
@registry_mutex() def create_auction(self, auction):
def create_deployment_auction(self, auction): if auction["kind"] == AUCTION_KIND_PROVIDER:
args = [ args = [
"laconic", "laconic",
"-c", "-c",
self.config_file, self.config_file,
"registry", "registry",
"auction", "auction",
"create", "create",
"--kind", "--kind",
auction["kind"], auction["kind"],
"--commits-duration", "--commits-duration",
str(auction["commits_duration"]), str(auction["commits_duration"]),
"--reveals-duration", "--reveals-duration",
str(auction["reveals_duration"]), str(auction["reveals_duration"]),
"--denom", "--denom",
auction["denom"], auction["denom"],
"--commit-fee", "--commit-fee",
str(auction["commit_fee"]), str(auction["commit_fee"]),
"--reveal-fee", "--reveal-fee",
str(auction["reveal_fee"]), str(auction["reveal_fee"]),
"--max-price", "--max-price",
str(auction["max_price"]), str(auction["max_price"]),
"--num-providers", "--num-providers",
str(auction["num_providers"]) str(auction["num_providers"])
] ]
else:
args = [
"laconic",
"-c",
self.config_file,
"registry",
"auction",
"create",
"--kind",
auction["kind"],
"--commits-duration",
str(auction["commits_duration"]),
"--reveals-duration",
str(auction["reveals_duration"]),
"--denom",
auction["denom"],
"--commit-fee",
str(auction["commit_fee"]),
"--reveal-fee",
str(auction["reveal_fee"]),
"--minimum-bid",
str(auction["minimum_bid"])
]
return json.loads(logged_cmd(self.log_file, *args))["auctionId"] return json.loads(logged_cmd(self.log_file, *args))["auctionId"]
@registry_mutex()
def commit_bid(self, auction_id, amount, type="alnt"): def commit_bid(self, auction_id, amount, type="alnt"):
args = [ args = [
"laconic", "laconic",
@ -519,7 +532,6 @@ class LaconicRegistryClient:
return json.loads(logged_cmd(self.log_file, *args))["reveal_file"] return json.loads(logged_cmd(self.log_file, *args))["reveal_file"]
@registry_mutex()
def reveal_bid(self, auction_id, reveal_file_path): def reveal_bid(self, auction_id, reveal_file_path):
logged_cmd( logged_cmd(
self.log_file, self.log_file,
@ -846,21 +858,16 @@ def confirm_payment(laconic: LaconicRegistryClient, record, payment_address, min
) )
return False return False
# Check if the payment was already used on a deployment # Check if the payment was already used on a
used = laconic.app_deployments( used = laconic.app_deployments(
{"deployer": record.attributes.deployer, "payment": tx.hash}, all=True {"deployer": payment_address, "payment": tx.hash}, all=True
) )
if len(used): if len(used):
# Fetch the app name from request record logger.log(f"{record.id}: payment {tx.hash} already used on deployment {used}")
used_request = laconic.get_record(used[0].attributes.request, require=True) return False
# Check that payment was used for deployment of same application
if record.attributes.application != used_request.attributes.application:
logger.log(f"{record.id}: payment {tx.hash} already used on a different application deployment {used}")
return False
used = laconic.app_deployment_removals( used = laconic.app_deployment_removals(
{"deployer": record.attributes.deployer, "payment": tx.hash}, all=True {"deployer": payment_address, "payment": tx.hash}, all=True
) )
if len(used): if len(used):
logger.log( logger.log(