qalita 2.3.0__tar.gz → 2.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {qalita-2.3.0 → qalita-2.3.1}/PKG-INFO +1 -1
- {qalita-2.3.0 → qalita-2.3.1}/pyproject.toml +1 -1
- {qalita-2.3.0 → qalita-2.3.1}/qalita/commands/agent.py +89 -1
- {qalita-2.3.0 → qalita-2.3.1}/qalita/commands/pack.py +116 -143
- {qalita-2.3.0 → qalita-2.3.1}/qalita/internal/utils.py +1 -1
- {qalita-2.3.0 → qalita-2.3.1}/LICENSE +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/docs/README.md +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/__init__.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/__main__.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/commands/__init__.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/commands/source.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/internal/__init__.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/internal/config.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/internal/error_patterns.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/internal/logger.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/internal/request.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/__init__.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/app.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/blueprints/agents.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/blueprints/context.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/blueprints/dashboard.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/blueprints/helpers.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/blueprints/sources.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/blueprints/studio.py +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/chatgpt.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/claude.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/favicon.ico +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/gemini.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/logo-no-slogan.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/logo-white-no-slogan.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/mistral.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/noise.webp +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/ollama.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/platform.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/alloy-db.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/amazon-athena.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/amazon-rds.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/api.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/avro.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/azure-database-mysql.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/azure-database-postgresql.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/azure-sql-database.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/azure-sql-managed-instance.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/azure-synapse-analytics.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/azure_blob.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/bigquery.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/cassandra.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/clickhouse.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/cloud-sql.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/cockroach-db.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/csv.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/database.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/databricks.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/duckdb.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/elasticsearch.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/excel.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/file.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/folder.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/gcs.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/hdfs.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/ibm-db2.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/json.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/maria-db.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/mongodb.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/mssql.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/mysql.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/oracle.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/parquet.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/picture.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/postgresql.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/questdb.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/redshift.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/s3.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/sap-hana.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/sftp.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/single-store.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/snowflake.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/sqlite.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/sqlserver.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/starburst.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/stream.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/teradata.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/timescale.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/xls.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/xlsx.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/yugabyte-db.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/studio-logo.svg +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/studio.css +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/studio.png +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/styles.css +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/templates/dashboard.html +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/templates/navbar.html +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/templates/sources/added.html +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/templates/sources/edit.html +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/templates/sources/select-source.html +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/templates/studio/agent-panel.html +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/templates/studio/context-panel.html +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/templates/studio/index.html +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/templates/studio/navbar.html +0 -0
- {qalita-2.3.0 → qalita-2.3.1}/qalita/web/templates/studio/view-panel.html +0 -0
|
@@ -465,6 +465,9 @@ def run(
|
|
|
465
465
|
# check routines before checking jobs
|
|
466
466
|
check_routines(config, agent_start_datetime)
|
|
467
467
|
|
|
468
|
+
# try to claim one pending unassigned job compatible with this agent
|
|
469
|
+
claim_unassigned_jobs(config)
|
|
470
|
+
|
|
468
471
|
check_job = send_api_request(
|
|
469
472
|
request=f'/api/v1/agents/{agent_conf["context"]["remote"]["id"]}/jobs/next',
|
|
470
473
|
mode="get",
|
|
@@ -1066,7 +1069,6 @@ def create_scheduled_job(routine, agent_conf):
|
|
|
1066
1069
|
request=f"/api/v2/jobs/create",
|
|
1067
1070
|
mode="post",
|
|
1068
1071
|
data={
|
|
1069
|
-
"agent_id": agent_conf["context"]["remote"]["id"],
|
|
1070
1072
|
"source_id": routine["source"]["id"],
|
|
1071
1073
|
"target_id": routine["target"]["id"] if routine.get("target") else None,
|
|
1072
1074
|
"pack_id": routine["pack"]["id"],
|
|
@@ -1238,3 +1240,89 @@ def check_routines(config, agent_start_datetime):
|
|
|
1238
1240
|
ROUTINE_LAST_SCHEDULED_UTC[routine.get("id")] = datetime.now(timezone.utc)
|
|
1239
1241
|
else:
|
|
1240
1242
|
logger.warning("Can't fetch routines or jobs from the platform")
|
|
1243
|
+
|
|
1244
|
+
|
|
1245
|
+
def claim_unassigned_jobs(config):
|
|
1246
|
+
"""Claim one pending unassigned job that this agent can execute.
|
|
1247
|
+
|
|
1248
|
+
Strategy:
|
|
1249
|
+
- Fetch all jobs (v2)
|
|
1250
|
+
- Select first job with status == pending and no agent assigned
|
|
1251
|
+
- Check local capability: source (and target if provided) must exist locally
|
|
1252
|
+
- PUT to assign agent_id to this agent; on success, run job
|
|
1253
|
+
- On contention (another agent already claimed), ignore and return
|
|
1254
|
+
"""
|
|
1255
|
+
try:
|
|
1256
|
+
source_conf = config.load_source_config(verbose=False)
|
|
1257
|
+
agent_conf = config.load_agent_config()
|
|
1258
|
+
local_source_ids = [s["id"] for s in source_conf["sources"] if "id" in s]
|
|
1259
|
+
|
|
1260
|
+
r = send_api_request(
|
|
1261
|
+
request=f"/api/v2/jobs",
|
|
1262
|
+
mode="get",
|
|
1263
|
+
)
|
|
1264
|
+
if r.status_code not in [200, 204]:
|
|
1265
|
+
return
|
|
1266
|
+
jobs = r.json()
|
|
1267
|
+
if not isinstance(jobs, list):
|
|
1268
|
+
return
|
|
1269
|
+
|
|
1270
|
+
def extract_id(maybe_obj, fallback_key):
|
|
1271
|
+
if isinstance(maybe_obj, dict):
|
|
1272
|
+
return maybe_obj.get("id")
|
|
1273
|
+
return maybe_obj if isinstance(maybe_obj, int) else None
|
|
1274
|
+
|
|
1275
|
+
for job in jobs:
|
|
1276
|
+
try:
|
|
1277
|
+
if job.get("status") != "pending":
|
|
1278
|
+
continue
|
|
1279
|
+
# unassigned: support either agent_id field or nested agent object
|
|
1280
|
+
is_unassigned = (
|
|
1281
|
+
(job.get("agent_id") is None or job.get("agent_id") == 0)
|
|
1282
|
+
and not job.get("agent")
|
|
1283
|
+
)
|
|
1284
|
+
if not is_unassigned:
|
|
1285
|
+
continue
|
|
1286
|
+
|
|
1287
|
+
src_id = extract_id(job.get("source"), "source_id") or job.get("source_id")
|
|
1288
|
+
if src_id not in local_source_ids:
|
|
1289
|
+
continue
|
|
1290
|
+
tgt_id = extract_id(job.get("target"), "target_id") or job.get("target_id")
|
|
1291
|
+
if tgt_id is not None and tgt_id not in local_source_ids:
|
|
1292
|
+
continue
|
|
1293
|
+
|
|
1294
|
+
# attempt to claim
|
|
1295
|
+
claim_resp = send_api_request(
|
|
1296
|
+
request=f"/api/v2/jobs/{job['id']}",
|
|
1297
|
+
mode="put",
|
|
1298
|
+
data={
|
|
1299
|
+
"agent_id": agent_conf["context"]["remote"]["id"],
|
|
1300
|
+
},
|
|
1301
|
+
)
|
|
1302
|
+
if claim_resp.status_code != 200:
|
|
1303
|
+
# likely contention: someone else claimed
|
|
1304
|
+
continue
|
|
1305
|
+
|
|
1306
|
+
# extract version ids if present
|
|
1307
|
+
src_ver_id = extract_id(job.get("source_version"), "source_version_id") or job.get("source_version_id")
|
|
1308
|
+
tgt_ver_id = extract_id(job.get("target_version"), "target_version_id") or job.get("target_version_id")
|
|
1309
|
+
pack_id = extract_id(job.get("pack"), "pack_id") or job.get("pack_id")
|
|
1310
|
+
pack_ver_id = extract_id(job.get("pack_version"), "pack_version_id") or job.get("pack_version_id")
|
|
1311
|
+
|
|
1312
|
+
logger.info(f"Claimed unassigned job {job['id']} for source {src_id} pack {pack_id}")
|
|
1313
|
+
job_run(
|
|
1314
|
+
src_id,
|
|
1315
|
+
src_ver_id,
|
|
1316
|
+
tgt_id,
|
|
1317
|
+
tgt_ver_id,
|
|
1318
|
+
pack_id,
|
|
1319
|
+
pack_ver_id,
|
|
1320
|
+
job=job,
|
|
1321
|
+
)
|
|
1322
|
+
# claim and run only one per loop
|
|
1323
|
+
return
|
|
1324
|
+
except Exception as _:
|
|
1325
|
+
# Be resilient; don't break the worker loop on any unexpected job shape
|
|
1326
|
+
continue
|
|
1327
|
+
except Exception as _:
|
|
1328
|
+
return
|
|
@@ -586,20 +586,37 @@ def publish_new_pack_version(api_url, pack_id, pack_version, registry_id, pack_n
|
|
|
586
586
|
source_dir=source_dir,
|
|
587
587
|
config=config,
|
|
588
588
|
)
|
|
589
|
-
# Best-effort: also update
|
|
589
|
+
# Best-effort: also update metadata (avatar, description, url, visibility, config, readme)
|
|
590
|
+
# and compatibility if provided in properties.yaml so the new version push also refreshes pack details.
|
|
590
591
|
try:
|
|
591
592
|
pack_dir = source_dir or f"./{pack_name}_pack"
|
|
592
593
|
props = load_pack_properties(pack_dir) or {}
|
|
594
|
+
pack_icon = load_base64_encoded_image(os.path.join(pack_dir, "icon.png"))
|
|
595
|
+
readme = load_base64_encoded_text(os.path.join(pack_dir, "README.md"))
|
|
596
|
+
pack_config = load_json_config(os.path.join(pack_dir, "pack_conf.json"))
|
|
597
|
+
pack_type = props.get("type", "")
|
|
598
|
+
pack_description = props.get("description", "")
|
|
599
|
+
pack_url = props.get("url", "")
|
|
600
|
+
pack_visibility = props.get("visibility", "private")
|
|
593
601
|
compat = props.get("compatible_sources")
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
+
|
|
603
|
+
# Update full metadata
|
|
604
|
+
update_pack_metadata(
|
|
605
|
+
api_url,
|
|
606
|
+
pack_id,
|
|
607
|
+
pack_icon,
|
|
608
|
+
pack_config,
|
|
609
|
+
pack_type,
|
|
610
|
+
pack_description,
|
|
611
|
+
pack_url,
|
|
612
|
+
pack_version,
|
|
613
|
+
pack_visibility,
|
|
614
|
+
readme,
|
|
615
|
+
compatible_sources=compat,
|
|
616
|
+
config=config,
|
|
617
|
+
)
|
|
602
618
|
except Exception:
|
|
619
|
+
# Non-fatal if metadata refresh fails; continue to publish version
|
|
603
620
|
pass
|
|
604
621
|
publish_response = _request_with_optional_config(
|
|
605
622
|
config,
|
|
@@ -689,6 +706,84 @@ def handle_version_matching(existing_versions, new_version):
|
|
|
689
706
|
return None
|
|
690
707
|
|
|
691
708
|
|
|
709
|
+
def _push_with_context(agent_conf, pack_properties, pack_directory, config):
|
|
710
|
+
"""Shared push routine used by CLI and Web UI.
|
|
711
|
+
|
|
712
|
+
Expects absolute or relative `pack_directory` and a loaded `pack_properties` dict.
|
|
713
|
+
"""
|
|
714
|
+
# Extract pack details
|
|
715
|
+
pack_name = pack_properties.get("name")
|
|
716
|
+
pack_version = pack_properties.get("version")
|
|
717
|
+
pack_description = pack_properties.get("description", "")
|
|
718
|
+
pack_url = pack_properties.get("url", "")
|
|
719
|
+
pack_type = pack_properties.get("type", "")
|
|
720
|
+
pack_visibility = pack_properties.get("visibility", "private")
|
|
721
|
+
|
|
722
|
+
# Handle pack icon and README/config
|
|
723
|
+
pack_icon = load_base64_encoded_image(os.path.join(pack_directory, "icon.png"))
|
|
724
|
+
readme = load_base64_encoded_text(os.path.join(pack_directory, "README.md"))
|
|
725
|
+
pack_config = load_json_config(os.path.join(pack_directory, "pack_conf.json"))
|
|
726
|
+
|
|
727
|
+
# Check existing packs and versions
|
|
728
|
+
pack_id, existing_versions = find_existing_pack(
|
|
729
|
+
agent_conf["context"]["local"]["url"], pack_name, config=config
|
|
730
|
+
)
|
|
731
|
+
|
|
732
|
+
if pack_id:
|
|
733
|
+
new_version_entry = handle_version_matching(existing_versions, pack_version)
|
|
734
|
+
if not new_version_entry:
|
|
735
|
+
# Try to load compatible_sources from properties.yaml (optional)
|
|
736
|
+
compat = (
|
|
737
|
+
pack_properties.get("compatible_sources")
|
|
738
|
+
if isinstance(pack_properties, dict)
|
|
739
|
+
else None
|
|
740
|
+
)
|
|
741
|
+
update_pack_metadata(
|
|
742
|
+
agent_conf["context"]["local"]["url"],
|
|
743
|
+
pack_id,
|
|
744
|
+
pack_icon,
|
|
745
|
+
pack_config,
|
|
746
|
+
pack_type,
|
|
747
|
+
pack_description,
|
|
748
|
+
pack_url,
|
|
749
|
+
pack_version,
|
|
750
|
+
pack_visibility,
|
|
751
|
+
readme,
|
|
752
|
+
compatible_sources=compat,
|
|
753
|
+
config=config,
|
|
754
|
+
)
|
|
755
|
+
logger.success(
|
|
756
|
+
"Pack metadata updated successfully ! \nIf you wanted to upload a new pack version, you must change the pack [version] attribute in properties.yaml"
|
|
757
|
+
)
|
|
758
|
+
else:
|
|
759
|
+
publish_new_pack_version(
|
|
760
|
+
agent_conf["context"]["local"]["url"],
|
|
761
|
+
pack_id,
|
|
762
|
+
pack_version,
|
|
763
|
+
agent_conf["registries"][0]["id"],
|
|
764
|
+
pack_name,
|
|
765
|
+
source_dir=pack_directory,
|
|
766
|
+
config=config,
|
|
767
|
+
)
|
|
768
|
+
else:
|
|
769
|
+
create_new_pack(
|
|
770
|
+
agent_conf["context"]["local"]["url"],
|
|
771
|
+
agent_conf["registries"][0]["id"],
|
|
772
|
+
pack_name,
|
|
773
|
+
pack_icon,
|
|
774
|
+
pack_config,
|
|
775
|
+
pack_type,
|
|
776
|
+
pack_description,
|
|
777
|
+
pack_url,
|
|
778
|
+
pack_version,
|
|
779
|
+
pack_visibility,
|
|
780
|
+
readme,
|
|
781
|
+
source_dir=pack_directory,
|
|
782
|
+
config=config,
|
|
783
|
+
)
|
|
784
|
+
logger.success("New pack created successfully!")
|
|
785
|
+
|
|
786
|
+
|
|
692
787
|
@pack.command()
|
|
693
788
|
@click.option("-n", "--name", help="Name of the package", envvar="QALITA_PACK_NAME")
|
|
694
789
|
@pass_config
|
|
@@ -725,78 +820,14 @@ def push(config, name):
|
|
|
725
820
|
logger.error("Failed to load agent configuration.")
|
|
726
821
|
return
|
|
727
822
|
|
|
728
|
-
#
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
pack_visibility = pack_properties.get("visibility", "private")
|
|
735
|
-
|
|
736
|
-
# Handle pack icon
|
|
737
|
-
pack_icon = load_base64_encoded_image(f"{pack_directory}/icon.png")
|
|
738
|
-
|
|
739
|
-
# Handle README file
|
|
740
|
-
readme = load_base64_encoded_text(f"{pack_directory}/README.md")
|
|
741
|
-
|
|
742
|
-
# Load pack config
|
|
743
|
-
pack_config = load_json_config(f"{pack_directory}/pack_conf.json")
|
|
744
|
-
|
|
745
|
-
# Check existing packs and versions
|
|
746
|
-
pack_id, existing_versions = find_existing_pack(
|
|
747
|
-
agent_conf["context"]["local"]["url"], pack_name, config=config
|
|
823
|
+
# Shared push routine
|
|
824
|
+
_push_with_context(
|
|
825
|
+
agent_conf,
|
|
826
|
+
pack_properties,
|
|
827
|
+
os.path.abspath(pack_directory),
|
|
828
|
+
config,
|
|
748
829
|
)
|
|
749
830
|
|
|
750
|
-
if pack_id:
|
|
751
|
-
# Handle version matching and decide whether to add a new asset or update metadata
|
|
752
|
-
new_version_entry = handle_version_matching(existing_versions, pack_version)
|
|
753
|
-
|
|
754
|
-
if not new_version_entry:
|
|
755
|
-
# Try to load compatible_sources from properties.yaml (optional)
|
|
756
|
-
compat = pack_properties.get("compatible_sources") if isinstance(pack_properties, dict) else None
|
|
757
|
-
update_pack_metadata(
|
|
758
|
-
agent_conf["context"]["local"]["url"],
|
|
759
|
-
pack_id,
|
|
760
|
-
pack_icon,
|
|
761
|
-
pack_config,
|
|
762
|
-
pack_type,
|
|
763
|
-
pack_description,
|
|
764
|
-
pack_url,
|
|
765
|
-
pack_version,
|
|
766
|
-
pack_visibility,
|
|
767
|
-
readme,
|
|
768
|
-
compatible_sources=compat,
|
|
769
|
-
config=config,
|
|
770
|
-
)
|
|
771
|
-
logger.success("Pack metadata updated successfully ! \nIf you wanted to upload a new pack version, you must change the pack [version] attribute in properties.yaml")
|
|
772
|
-
else:
|
|
773
|
-
publish_new_pack_version(
|
|
774
|
-
agent_conf["context"]["local"]["url"],
|
|
775
|
-
pack_id,
|
|
776
|
-
pack_version,
|
|
777
|
-
agent_conf["registries"][0]["id"],
|
|
778
|
-
pack_name,
|
|
779
|
-
source_dir=os.path.abspath(pack_directory),
|
|
780
|
-
config=config,
|
|
781
|
-
)
|
|
782
|
-
else:
|
|
783
|
-
create_new_pack(
|
|
784
|
-
agent_conf["context"]["local"]["url"],
|
|
785
|
-
agent_conf["registries"][0]["id"],
|
|
786
|
-
pack_name,
|
|
787
|
-
pack_icon,
|
|
788
|
-
pack_config,
|
|
789
|
-
pack_type,
|
|
790
|
-
pack_description,
|
|
791
|
-
pack_url,
|
|
792
|
-
pack_version,
|
|
793
|
-
pack_visibility,
|
|
794
|
-
readme,
|
|
795
|
-
source_dir=os.path.abspath(pack_directory),
|
|
796
|
-
config=config,
|
|
797
|
-
)
|
|
798
|
-
logger.success("New pack created successfully!")
|
|
799
|
-
|
|
800
831
|
logger.info("Pack pushed successfully.")
|
|
801
832
|
|
|
802
833
|
except Exception as e:
|
|
@@ -842,72 +873,14 @@ def push_from_directory(config, pack_directory):
|
|
|
842
873
|
logger.error(msg)
|
|
843
874
|
return False, msg
|
|
844
875
|
|
|
845
|
-
#
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
pack_visibility = pack_properties.get("visibility", "private")
|
|
852
|
-
|
|
853
|
-
# Handle pack icon and README
|
|
854
|
-
pack_icon = load_base64_encoded_image(os.path.join(pack_directory, "icon.png"))
|
|
855
|
-
readme = load_base64_encoded_text(os.path.join(pack_directory, "README.md"))
|
|
856
|
-
pack_config = load_json_config(os.path.join(pack_directory, "pack_conf.json"))
|
|
857
|
-
|
|
858
|
-
# Check existing packs and versions
|
|
859
|
-
pack_id, existing_versions = find_existing_pack(
|
|
860
|
-
agent_conf["context"]["local"]["url"], pack_name, config=config
|
|
876
|
+
# Shared push routine
|
|
877
|
+
_push_with_context(
|
|
878
|
+
agent_conf,
|
|
879
|
+
pack_properties,
|
|
880
|
+
pack_directory,
|
|
881
|
+
config,
|
|
861
882
|
)
|
|
862
883
|
|
|
863
|
-
if pack_id:
|
|
864
|
-
new_version_entry = handle_version_matching(existing_versions, pack_version)
|
|
865
|
-
if not new_version_entry:
|
|
866
|
-
# Try to load compatible_sources from properties.yaml (optional)
|
|
867
|
-
compat = pack_properties.get("compatible_sources") if isinstance(pack_properties, dict) else None
|
|
868
|
-
update_pack_metadata(
|
|
869
|
-
agent_conf["context"]["local"]["url"],
|
|
870
|
-
pack_id,
|
|
871
|
-
pack_icon,
|
|
872
|
-
pack_config,
|
|
873
|
-
pack_type,
|
|
874
|
-
pack_description,
|
|
875
|
-
pack_url,
|
|
876
|
-
pack_version,
|
|
877
|
-
pack_visibility,
|
|
878
|
-
readme,
|
|
879
|
-
compatible_sources=compat,
|
|
880
|
-
config=config,
|
|
881
|
-
)
|
|
882
|
-
logger.success("Pack metadata updated successfully ! \nIf you wanted to upload a new pack version, you must change the pack [version] attribute in properties.yaml")
|
|
883
|
-
else:
|
|
884
|
-
publish_new_pack_version(
|
|
885
|
-
agent_conf["context"]["local"]["url"],
|
|
886
|
-
pack_id,
|
|
887
|
-
pack_version,
|
|
888
|
-
agent_conf["registries"][0]["id"],
|
|
889
|
-
pack_name,
|
|
890
|
-
source_dir=pack_directory,
|
|
891
|
-
config=config,
|
|
892
|
-
)
|
|
893
|
-
else:
|
|
894
|
-
create_new_pack(
|
|
895
|
-
agent_conf["context"]["local"]["url"],
|
|
896
|
-
agent_conf["registries"][0]["id"],
|
|
897
|
-
pack_name,
|
|
898
|
-
pack_icon,
|
|
899
|
-
pack_config,
|
|
900
|
-
pack_type,
|
|
901
|
-
pack_description,
|
|
902
|
-
pack_url,
|
|
903
|
-
pack_version,
|
|
904
|
-
pack_visibility,
|
|
905
|
-
readme,
|
|
906
|
-
source_dir=pack_directory,
|
|
907
|
-
config=config,
|
|
908
|
-
)
|
|
909
|
-
logger.success("New pack created successfully!")
|
|
910
|
-
|
|
911
884
|
logger.info("Pack pushed successfully.")
|
|
912
885
|
return True, "Pack pushed successfully."
|
|
913
886
|
except Exception as e:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qalita-2.3.0 → qalita-2.3.1}/qalita/web/public/sources-logos/azure-sql-managed-instance.png
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|