zog 0.1.0__py3-none-any.whl
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.
- zog/__init__.py +3 -0
- zog/_release_manifest.json +142 -0
- zog/archive_mirror/__init__.py +3 -0
- zog/archive_mirror/__main__.py +2 -0
- zog/archive_mirror/apps.py +6 -0
- zog/archive_mirror/cli.py +91 -0
- zog/archive_mirror/collector.py +70 -0
- zog/archive_mirror/config.py +22 -0
- zog/archive_mirror/lease.py +22 -0
- zog/archive_mirror/management/__init__.py +0 -0
- zog/archive_mirror/management/commands/__init__.py +0 -0
- zog/archive_mirror/migrations/0001_initial.py +55 -0
- zog/archive_mirror/migrations/0002_collectionstatus.py +22 -0
- zog/archive_mirror/migrations/0003_reviewed_sources.py +33 -0
- zog/archive_mirror/migrations/__init__.py +0 -0
- zog/archive_mirror/models.py +51 -0
- zog/archive_mirror/notice_contract.py +200 -0
- zog/archive_mirror/notices.py +84 -0
- zog/archive_mirror/observation.py +166 -0
- zog/archive_mirror/preflight.py +52 -0
- zog/archive_mirror/receipt_notices.py +131 -0
- zog/archive_mirror/runtime.py +58 -0
- zog/archive_mirror/settings.py +14 -0
- zog/archive_mirror/source_inputs.py +173 -0
- zog/archive_mirror/source_notices.py +79 -0
- zog/archive_mirror/store.py +101 -0
- zog/archive_mirror/urls.py +10 -0
- zog/archive_mirror/views.py +156 -0
- zog/box_control/__init__.py +25 -0
- zog/box_control/__main__.py +2 -0
- zog/box_control/api.py +552 -0
- zog/box_control/application_storage.py +286 -0
- zog/box_control/boot.py +19 -0
- zog/box_control/build_jobs.py +297 -0
- zog/box_control/build_protocol.py +75 -0
- zog/box_control/cancellation.py +102 -0
- zog/box_control/cli.py +7 -0
- zog/box_control/dependency.py +139 -0
- zog/box_control/diagnostics.py +43 -0
- zog/box_control/durability.py +103 -0
- zog/box_control/errors.py +44 -0
- zog/box_control/events.py +70 -0
- zog/box_control/explanations.py +97 -0
- zog/box_control/generation.py +122 -0
- zog/box_control/host_gateway.py +51 -0
- zog/box_control/images.py +66 -0
- zog/box_control/inspection.py +245 -0
- zog/box_control/locking.py +58 -0
- zog/box_control/model.py +118 -0
- zog/box_control/mounts.py +92 -0
- zog/box_control/operations.py +515 -0
- zog/box_control/preflight.py +111 -0
- zog/box_control/project.py +76 -0
- zog/box_control/reconcile.py +681 -0
- zog/box_control/requests.py +199 -0
- zog/box_control/retention.py +135 -0
- zog/box_control/root_protocol.py +34 -0
- zog/box_control/runtime/__init__.py +35 -0
- zog/box_control/runtime/reference.py +367 -0
- zog/box_control/runtime/root_control.py +188 -0
- zog/box_control/runtime/systemd.py +859 -0
- zog/box_control/specification.py +336 -0
- zog/box_control/state.py +30 -0
- zog/box_control/station.py +70 -0
- zog/box_control/workspaces.py +251 -0
- zog/build_record/__init__.py +29 -0
- zog/build_record/__main__.py +3 -0
- zog/build_record/audit.py +62 -0
- zog/build_record/cli.py +68 -0
- zog/build_record/graph.py +448 -0
- zog/build_record/image_build.py +701 -0
- zog/build_record/model.py +578 -0
- zog/build_record/snapshot.py +25 -0
- zog/build_record/store.py +70 -0
- zog/build_trace/__init__.py +8 -0
- zog/build_trace/__main__.py +2 -0
- zog/build_trace/api.py +515 -0
- zog/build_trace/cli.py +208 -0
- zog/build_trace/generations.py +256 -0
- zog/build_trace/history.py +268 -0
- zog/build_trace/integration.py +100 -0
- zog/build_trace/materials.py +122 -0
- zog/build_trace/model.py +106 -0
- zog/build_trace/observations.py +409 -0
- zog/build_trace/provenance.py +165 -0
- zog/build_trace/shell.py +50 -0
- zog/build_trace/snapshot_observations.py +642 -0
- zog/build_trace/source.py +166 -0
- zog/build_trace/summaries.py +96 -0
- zog/host_deploy/__init__.py +3 -0
- zog/host_deploy/artifacts.py +141 -0
- zog/host_deploy/beacon_install.py +190 -0
- zog/host_deploy/beacon_installation/requirements-security-tested.txt +28 -0
- zog/host_deploy/beacon_payload.py +45 -0
- zog/host_deploy/beacon_sources.json +71 -0
- zog/host_deploy/bootstrap.py +59 -0
- zog/host_deploy/bulk.py +184 -0
- zog/host_deploy/checkpoint.py +142 -0
- zog/host_deploy/cli.py +206 -0
- zog/host_deploy/diagnostics.py +25 -0
- zog/host_deploy/discovery.py +112 -0
- zog/host_deploy/gateway/__init__.py +27 -0
- zog/host_deploy/gateway/github_dispatch.py +254 -0
- zog/host_deploy/gateway/protocol.py +384 -0
- zog/host_deploy/image_build_lanes.py +380 -0
- zog/host_deploy/job_worker.py +135 -0
- zog/host_deploy/jobs.py +228 -0
- zog/host_deploy/provision.py +238 -0
- zog/host_deploy/reboot_remote.py +266 -0
- zog/host_deploy/reboots.py +170 -0
- zog/host_deploy/remote.py +62 -0
- zog/host_deploy/remote_control.py +61 -0
- zog/host_deploy/runner.py +206 -0
- zog/host_deploy/station.py +65 -0
- zog/host_deploy/station_remote.py +193 -0
- zog/host_deploy/transfer.py +57 -0
- zog/host_deploy/workspace.py +63 -0
- zog/host_discover/__init__.py +1 -0
- zog/host_discover/__main__.py +2 -0
- zog/host_discover/admission.py +114 -0
- zog/host_discover/beacon.py +184 -0
- zog/host_discover/beacon_state.py +36 -0
- zog/host_discover/bootstrap.py +39 -0
- zog/host_discover/box_bridge.py +92 -0
- zog/host_discover/daemon.py +241 -0
- zog/host_discover/destinations.py +65 -0
- zog/host_discover/gateway.py +39 -0
- zog/host_discover/managed.py +156 -0
- zog/host_discover/managed_transport.py +173 -0
- zog/host_discover/recovery.py +220 -0
- zog/host_discover/retry.py +31 -0
- zog/host_discover/roles.py +116 -0
- zog/host_discover/supervisor.py +276 -0
- zog/host_discover/systemd/host-discover-beacon.service +22 -0
- zog/host_discover/systemd/host-discover-managed.service +23 -0
- zog/host_discover/systemd/host-discover-supervisor.socket +22 -0
- zog/host_discover/systemd/host-discover-supervisor@.service +18 -0
- zog/host_discover/systemd/host-discover.service +21 -0
- zog/host_identify/__init__.py +3 -0
- zog/host_identify/archive.py +56 -0
- zog/host_identify/initialization.py +211 -0
- zog/host_identify/managed.py +57 -0
- zog/host_identify/mirror_access.py +38 -0
- zog/host_identify/mirror_fixture.py +22 -0
- zog/host_identify/recovery.py +34 -0
- zog/host_identify/signatures.py +88 -0
- zog/host_identify/storage.py +168 -0
- zog/host_install/__init__.py +7 -0
- zog/host_install/__main__.py +3 -0
- zog/host_install/artifact.py +189 -0
- zog/host_install/beacon_profile.py +126 -0
- zog/host_install/cli.py +136 -0
- zog/host_install/filesystem.py +72 -0
- zog/host_install/identity_worker.py +46 -0
- zog/host_install/image.py +220 -0
- zog/host_install/layout.py +66 -0
- zog/host_install/manifest.py +118 -0
- zog/host_install/preflight.py +111 -0
- zog/host_install/state_admission.py +207 -0
- zog/host_install/state_contract.py +191 -0
- zog/host_install/state_gate.py +55 -0
- zog/host_install/state_initialize.py +222 -0
- zog/host_install/state_inspect.py +253 -0
- zog/host_install/state_io.py +128 -0
- zog/host_install/state_probe.py +66 -0
- zog/host_install/state_provision.py +196 -0
- zog/host_install/systemd/host-discover-managed.conf.example +18 -0
- zog/host_install/systemd/host-install-admission.socket +23 -0
- zog/host_install/systemd/host-install-admission@.service +20 -0
- zog/host_install/systemd/host-install-identity.service +16 -0
- zog/host_install/systemd/host-install-prepare.service +16 -0
- zog/host_install/systemd/state.mount.in +14 -0
- zog/image_build/__init__.py +26 -0
- zog/image_build/__main__.py +81 -0
- zog/image_build/application_software.py +684 -0
- zog/image_build/application_views.py +822 -0
- zog/image_build/archive_mirror.py +250 -0
- zog/image_build/artifact_observations.py +76 -0
- zog/image_build/artifacts.py +113 -0
- zog/image_build/automake_results.py +39 -0
- zog/image_build/box_control_adapter.py +219 -0
- zog/image_build/build_environment.py +45 -0
- zog/image_build/build_views.py +39 -0
- zog/image_build/cleanup.py +129 -0
- zog/image_build/compiler_environment.py +62 -0
- zog/image_build/compiler_results.py +34 -0
- zog/image_build/configuration.py +57 -0
- zog/image_build/developer/__init__.py +1 -0
- zog/image_build/developer/catalogue.py +106 -0
- zog/image_build/developer/distribution.py +129 -0
- zog/image_build/developer/host.py +178 -0
- zog/image_build/developer/seed.py +170 -0
- zog/image_build/developer/seed_build.py +188 -0
- zog/image_build/developer/source_packaging.py +71 -0
- zog/image_build/engine.py +653 -0
- zog/image_build/errors.py +2 -0
- zog/image_build/filesystem.py +163 -0
- zog/image_build/final_compiler.py +228 -0
- zog/image_build/final_math.py +66 -0
- zog/image_build/generation_provenance.py +249 -0
- zog/image_build/glibc_final.py +251 -0
- zog/image_build/glibc_publish.py +71 -0
- zog/image_build/glibc_tests.py +41 -0
- zog/image_build/host_export.py +298 -0
- zog/image_build/host_fixture.py +69 -0
- zog/image_build/host_inventory.py +51 -0
- zog/image_build/host_labels.py +83 -0
- zog/image_build/host_trust.py +91 -0
- zog/image_build/host_trust_assembly.py +109 -0
- zog/image_build/info_index.py +63 -0
- zog/image_build/installed_verification.py +121 -0
- zog/image_build/integration_observations.py +180 -0
- zog/image_build/licensing.py +354 -0
- zog/image_build/local_network.py +32 -0
- zog/image_build/metadata.py +246 -0
- zog/image_build/native.py +135 -0
- zog/image_build/native_stage.py +70 -0
- zog/image_build/native_tools.py +156 -0
- zog/image_build/observation_snapshots.py +462 -0
- zog/image_build/pins.py +60 -0
- zog/image_build/pipeline.py +207 -0
- zog/image_build/provenance.py +430 -0
- zog/image_build/public_https.py +131 -0
- zog/image_build/python_enrollment.py +167 -0
- zog/image_build/python_runtime.py +166 -0
- zog/image_build/remote_operations.py +1324 -0
- zog/image_build/retained_compiler.py +157 -0
- zog/image_build/runner.py +106 -0
- zog/image_build/source_acquisition.py +65 -0
- zog/image_build/source_libraries.py +103 -0
- zog/image_build/source_provenance.py +88 -0
- zog/image_build/sources.py +114 -0
- zog/image_build/stages.py +225 -0
- zog/image_build/temporary.py +114 -0
- zog/image_build/test_fixtures.py +90 -0
- zog/image_build/trace_records.py +147 -0
- zog/image_build/verification_observations.py +112 -0
- zog/image_build/worker.py +29 -0
- zog/integrate_observe/__init__.py +6 -0
- zog/integrate_observe/__main__.py +3 -0
- zog/integrate_observe/cli.py +77 -0
- zog/integrate_observe/observer.py +386 -0
- zog/network_register/__init__.py +3 -0
- zog/network_register/__main__.py +2 -0
- zog/network_register/adoption.py +78 -0
- zog/network_register/cli.py +57 -0
- zog/network_register/client.py +94 -0
- zog/network_register/cloudflare.py +155 -0
- zog/network_register/contracts.py +109 -0
- zog/network_register/dns.py +91 -0
- zog/network_register/dns_authority.py +190 -0
- zog/network_register/engine.py +272 -0
- zog/network_register/evidence.py +171 -0
- zog/network_register/host_demo.py +51 -0
- zog/network_register/initialization.py +97 -0
- zog/network_register/ledger.py +253 -0
- zog/network_register/lifecycle.py +145 -0
- zog/network_register/models.py +170 -0
- zog/network_register/operations.py +115 -0
- zog/network_register/porkbun.py +117 -0
- zog/network_register/porkbun_dns.py +181 -0
- zog/network_register/reservations.py +79 -0
- zog/network_register/state.py +42 -0
- zog/network_register/store.py +88 -0
- zog/root_control/__init__.py +3 -0
- zog/root_control/__main__.py +3 -0
- zog/root_control/build.py +519 -0
- zog/root_control/daemon.py +193 -0
- zog/root_control/events.py +11 -0
- zog/root_control/jobs.py +159 -0
- zog/root_control/journal.py +136 -0
- zog/root_control/journal_barrier.py +223 -0
- zog/root_control/native/journal-wait.c +29 -0
- zog/root_control/privileged.py +28 -0
- zog/root_control/processes.py +162 -0
- zog/root_control/protocol.py +30 -0
- zog/root_control/systemd.py +562 -0
- zog/root_control/workspace.py +160 -0
- zog/station_access/__init__.py +3 -0
- zog/station_access/admin.py +68 -0
- zog/station_access/api/__init__.py +0 -0
- zog/station_access/api/serializers.py +65 -0
- zog/station_access/api/urls.py +31 -0
- zog/station_access/api/views.py +652 -0
- zog/station_access/apps.py +9 -0
- zog/station_access/archive_inventory/__init__.py +0 -0
- zog/station_access/archive_inventory/apps.py +6 -0
- zog/station_access/archive_inventory/contract.py +100 -0
- zog/station_access/archive_inventory/generation_resolution.py +51 -0
- zog/station_access/archive_inventory/generation_views.py +283 -0
- zog/station_access/archive_inventory/management/__init__.py +0 -0
- zog/station_access/archive_inventory/management/commands/__init__.py +0 -0
- zog/station_access/archive_inventory/management/commands/report_archive_inventory.py +103 -0
- zog/station_access/archive_inventory/migrations/0001_initial.py +57 -0
- zog/station_access/archive_inventory/migrations/0002_noticebundle.py +13 -0
- zog/station_access/archive_inventory/migrations/__init__.py +0 -0
- zog/station_access/archive_inventory/models.py +46 -0
- zog/station_access/archive_inventory/notice_views.py +107 -0
- zog/station_access/archive_inventory/urls.py +12 -0
- zog/station_access/archive_inventory/views.py +187 -0
- zog/station_access/box_control/__init__.py +11 -0
- zog/station_access/box_control/current.py +247 -0
- zog/station_access/box_control/fixture.py +120 -0
- zog/station_access/box_control/journal.py +76 -0
- zog/station_access/box_control/logs.py +47 -0
- zog/station_access/box_control/port.py +52 -0
- zog/station_access/box_control/types.py +44 -0
- zog/station_access/box_control/unavailable.py +7 -0
- zog/station_access/cli.py +82 -0
- zog/station_access/host_registry/__init__.py +0 -0
- zog/station_access/host_registry/admin.py +9 -0
- zog/station_access/host_registry/apps.py +6 -0
- zog/station_access/host_registry/cloud_configuration.py +140 -0
- zog/station_access/host_registry/deployment_jobs.py +195 -0
- zog/station_access/host_registry/deployment_views.py +44 -0
- zog/station_access/host_registry/dns_cutover.py +210 -0
- zog/station_access/host_registry/dns_destination_views.py +37 -0
- zog/station_access/host_registry/dns_destinations.py +222 -0
- zog/station_access/host_registry/dns_evidence.py +162 -0
- zog/station_access/host_registry/dns_membership.py +165 -0
- zog/station_access/host_registry/dns_membership_views.py +28 -0
- zog/station_access/host_registry/dns_reconcile.py +221 -0
- zog/station_access/host_registry/dns_setup.py +194 -0
- zog/station_access/host_registry/dns_setup_views.py +25 -0
- zog/station_access/host_registry/dns_shared.py +140 -0
- zog/station_access/host_registry/fixtures/managed-state.json +117 -0
- zog/station_access/host_registry/identity.py +158 -0
- zog/station_access/host_registry/identity_views.py +165 -0
- zog/station_access/host_registry/inventory.py +58 -0
- zog/station_access/host_registry/managed_views.py +150 -0
- zog/station_access/host_registry/management/__init__.py +0 -0
- zog/station_access/host_registry/management/commands/__init__.py +0 -0
- zog/station_access/host_registry/management/commands/allow_legacy_host.py +19 -0
- zog/station_access/host_registry/management/commands/check_dns_evidence.py +21 -0
- zog/station_access/host_registry/management/commands/create_station_vault.py +14 -0
- zog/station_access/host_registry/management/commands/enroll_host.py +37 -0
- zog/station_access/host_registry/management/commands/manage_dns_destination.py +19 -0
- zog/station_access/host_registry/management/commands/manage_host_dns.py +23 -0
- zog/station_access/host_registry/management/commands/migrate_host_dns.py +39 -0
- zog/station_access/host_registry/management/commands/prune_host_security.py +8 -0
- zog/station_access/host_registry/management/commands/reconcile_host_dns.py +20 -0
- zog/station_access/host_registry/management/commands/run_deployment_jobs.py +12 -0
- zog/station_access/host_registry/management/commands/scan_host_inventory.py +14 -0
- zog/station_access/host_registry/matching.py +58 -0
- zog/station_access/host_registry/migrations/0001_initial.py +50 -0
- zog/station_access/host_registry/migrations/0002_dnsassignment.py +38 -0
- zog/station_access/host_registry/migrations/0003_admissionwindow_archivepolicy_enrollmentrequest_and_more.py +98 -0
- zog/station_access/host_registry/migrations/0004_security_gate.py +8 -0
- zog/station_access/host_registry/migrations/0005_mirrorrole_stationcredential.py +42 -0
- zog/station_access/host_registry/migrations/0006_host_archival.py +8 -0
- zog/station_access/host_registry/migrations/0007_setup_configuration.py +47 -0
- zog/station_access/host_registry/migrations/0008_provider_access_checks.py +29 -0
- zog/station_access/host_registry/migrations/0009_cloud_credentials.py +35 -0
- zog/station_access/host_registry/migrations/0010_deployment_jobs.py +36 -0
- zog/station_access/host_registry/migrations/0011_dns_evidence.py +10 -0
- zog/station_access/host_registry/migrations/0012_managed_admission.py +12 -0
- zog/station_access/host_registry/migrations/0013_dnsdestination_additionaldnsassignment.py +54 -0
- zog/station_access/host_registry/migrations/__init__.py +0 -0
- zog/station_access/host_registry/mirror_roles.py +76 -0
- zog/station_access/host_registry/models.py +254 -0
- zog/station_access/host_registry/operations_views.py +65 -0
- zog/station_access/host_registry/provider_checks.py +130 -0
- zog/station_access/host_registry/readiness.py +126 -0
- zog/station_access/host_registry/retirement.py +129 -0
- zog/station_access/host_registry/services.py +26 -0
- zog/station_access/host_registry/setup_configuration.py +131 -0
- zog/station_access/host_registry/setup_views.py +92 -0
- zog/station_access/host_registry/urls.py +6 -0
- zog/station_access/host_registry/user_views.py +114 -0
- zog/station_access/host_registry/vault.py +64 -0
- zog/station_access/host_registry/views.py +247 -0
- zog/station_access/management/__init__.py +0 -0
- zog/station_access/management/commands/__init__.py +0 -0
- zog/station_access/management/commands/export_station_login.py +26 -0
- zog/station_access/management/commands/initialize_station.py +37 -0
- zog/station_access/management/commands/reconcile_vnc_workspaces.py +21 -0
- zog/station_access/migrations/0001_initial.py +80 -0
- zog/station_access/migrations/0002_lazy_workspaces.py +36 -0
- zog/station_access/migrations/0003_workspace_network_and_sequence.py +17 -0
- zog/station_access/migrations/0004_workspace_controller_adapter.py +48 -0
- zog/station_access/migrations/__init__.py +0 -0
- zog/station_access/models.py +130 -0
- zog/station_access/project/__init__.py +0 -0
- zog/station_access/project/asgi.py +4 -0
- zog/station_access/project/settings.py +136 -0
- zog/station_access/project/urls.py +36 -0
- zog/station_access/project/wsgi.py +4 -0
- zog/station_access/services/__init__.py +0 -0
- zog/station_access/services/authorization.py +34 -0
- zog/station_access/services/controller_workspaces.py +138 -0
- zog/station_access/services/locks.py +24 -0
- zog/station_access/services/vnc.py +118 -0
- zog/station_access/services/workspace_applications.py +147 -0
- zog/station_access/services/workspace_provenance.py +73 -0
- zog/station_access/services/workspace_readiness.py +93 -0
- zog/station_access/services/workspaces.py +311 -0
- zog/station_access/signals.py +25 -0
- zog/station_access/web.py +106 -0
- zog/version_share/__init__.py +11 -0
- zog/version_share/__main__.py +130 -0
- zog/version_share/archives.py +145 -0
- zog/version_share/core.py +260 -0
- zog/version_share/handoffs.py +148 -0
- zog/version_share/publication.py +333 -0
- zog/version_share/review.py +81 -0
- zog/version_share/transfer.py +71 -0
- zog/version_share/workspace.py +136 -0
- zog-0.1.0.dist-info/METADATA +96 -0
- zog-0.1.0.dist-info/RECORD +414 -0
- zog-0.1.0.dist-info/WHEEL +5 -0
- zog-0.1.0.dist-info/entry_points.txt +17 -0
- zog-0.1.0.dist-info/licenses/LICENSES/BSD-3-Clause.txt +11 -0
- zog-0.1.0.dist-info/licenses/LICENSES/GPL-3.0-only.txt +232 -0
- zog-0.1.0.dist-info/top_level.txt +1 -0
zog/__init__.py
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
{
|
|
2
|
+
"components": [
|
|
3
|
+
{
|
|
4
|
+
"component_dependencies": [],
|
|
5
|
+
"component_version": "0.4.2",
|
|
6
|
+
"program": "archive-mirror",
|
|
7
|
+
"python_package": "zog.archive_mirror",
|
|
8
|
+
"repository": "zog144/archive-mirror",
|
|
9
|
+
"revision": "648691fecc22494dc1aaf8dbe8b2f21b2ed67af3"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"component_dependencies": [
|
|
13
|
+
"image-build"
|
|
14
|
+
],
|
|
15
|
+
"component_version": "0.1.0",
|
|
16
|
+
"program": "box-control",
|
|
17
|
+
"python_package": "zog.box_control",
|
|
18
|
+
"repository": "zog144/box-control",
|
|
19
|
+
"revision": "014c8a058889c4b6de1ad58af76cb65ce5a94b7a"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"component_dependencies": [],
|
|
23
|
+
"component_version": "0.7.2",
|
|
24
|
+
"program": "build-record",
|
|
25
|
+
"python_package": "zog.build_record",
|
|
26
|
+
"repository": "zog144/build-record",
|
|
27
|
+
"revision": "60631ae4c6904e4812bf0d38f8703a6123935aa1"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"component_dependencies": [
|
|
31
|
+
"box-control",
|
|
32
|
+
"build-record"
|
|
33
|
+
],
|
|
34
|
+
"component_version": "0.12.0",
|
|
35
|
+
"program": "build-trace",
|
|
36
|
+
"python_package": "zog.build_trace",
|
|
37
|
+
"repository": "zog144/build-trace",
|
|
38
|
+
"revision": "1158030d0a8461554ebeda42ea095b25c10133dc"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"component_dependencies": [],
|
|
42
|
+
"component_version": "0.10.6",
|
|
43
|
+
"program": "host-deploy",
|
|
44
|
+
"python_package": "zog.host_deploy",
|
|
45
|
+
"repository": "zog144/host-deploy",
|
|
46
|
+
"revision": "21d5368398b9765357fcc180ca037c6c2279f24f"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"component_dependencies": [
|
|
50
|
+
"host-identify",
|
|
51
|
+
"host-install"
|
|
52
|
+
],
|
|
53
|
+
"component_version": "0.4.6",
|
|
54
|
+
"program": "host-discover",
|
|
55
|
+
"python_package": "zog.host_discover",
|
|
56
|
+
"repository": "zog144/host-discover",
|
|
57
|
+
"revision": "aef758740ac3a3c47618e3bc6f7e66c16e1eb8d1"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"component_dependencies": [],
|
|
61
|
+
"component_version": "0.3.4",
|
|
62
|
+
"program": "host-identify",
|
|
63
|
+
"python_package": "zog.host_identify",
|
|
64
|
+
"repository": "zog144/host-identify",
|
|
65
|
+
"revision": "40fd8d901e0434ba4f819a03fa3dc71f9767da64"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"component_dependencies": [],
|
|
69
|
+
"component_version": "0.4.4",
|
|
70
|
+
"program": "host-install",
|
|
71
|
+
"python_package": "zog.host_install",
|
|
72
|
+
"repository": "zog144/host-install",
|
|
73
|
+
"revision": "e931dc7cc41e7b5a00da862b13f26325c3bd7a17"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"component_dependencies": [
|
|
77
|
+
"box-control",
|
|
78
|
+
"build-record",
|
|
79
|
+
"host-identify"
|
|
80
|
+
],
|
|
81
|
+
"component_version": "0.2.0.dev5",
|
|
82
|
+
"program": "image-build",
|
|
83
|
+
"python_package": "zog.image_build",
|
|
84
|
+
"repository": "zog144/image-build",
|
|
85
|
+
"revision": "004bf0eae67a220348926248a06fa6447070cbfb"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"component_dependencies": [
|
|
89
|
+
"build-trace"
|
|
90
|
+
],
|
|
91
|
+
"component_version": "0.2.0",
|
|
92
|
+
"program": "integrate-observe",
|
|
93
|
+
"python_package": "zog.integrate_observe",
|
|
94
|
+
"repository": "zog144/integrate-observe",
|
|
95
|
+
"revision": "d20e0ef972ea6f454b7de18f2e541b40e40e32a1"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"component_dependencies": [],
|
|
99
|
+
"component_version": "0.12.0",
|
|
100
|
+
"program": "network-register",
|
|
101
|
+
"python_package": "zog.network_register",
|
|
102
|
+
"repository": "zog144/network-register",
|
|
103
|
+
"revision": "c9af90c46cc62ad883c113ef0017a71389ee970b"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"component_dependencies": [
|
|
107
|
+
"box-control"
|
|
108
|
+
],
|
|
109
|
+
"component_version": "0.1.0",
|
|
110
|
+
"program": "root-control",
|
|
111
|
+
"python_package": "zog.root_control",
|
|
112
|
+
"repository": "zog144/root-control",
|
|
113
|
+
"revision": "3cc6cdc2c5e49232318d82797d3228c6072b9bdc"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"component_dependencies": [
|
|
117
|
+
"archive-mirror",
|
|
118
|
+
"box-control",
|
|
119
|
+
"host-deploy",
|
|
120
|
+
"host-identify",
|
|
121
|
+
"network-register"
|
|
122
|
+
],
|
|
123
|
+
"component_version": "0.4.29",
|
|
124
|
+
"program": "station-access",
|
|
125
|
+
"python_package": "zog.station_access",
|
|
126
|
+
"repository": "zog144/station-access",
|
|
127
|
+
"revision": "ab2b1cc0b74787adf7dd81d99b1de5f099fe7460"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"component_dependencies": [],
|
|
131
|
+
"component_version": "0.4.0",
|
|
132
|
+
"program": "version-share",
|
|
133
|
+
"python_package": "zog.version_share",
|
|
134
|
+
"repository": "zog144/version-share",
|
|
135
|
+
"revision": "5bb90786a46c489abb542ddb80bb2b7a7c8dc218"
|
|
136
|
+
}
|
|
137
|
+
],
|
|
138
|
+
"distribution": "zog",
|
|
139
|
+
"license_expression": "BSD-3-Clause OR GPL-3.0-only",
|
|
140
|
+
"schema": 1,
|
|
141
|
+
"version": "0.1.0"
|
|
142
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import json
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
def main():
|
|
7
|
+
parser=argparse.ArgumentParser()
|
|
8
|
+
sub=parser.add_subparsers(dest='command',required=True)
|
|
9
|
+
sub.add_parser('migrate');sub.add_parser('refresh');sub.add_parser('prune');sub.add_parser('scheduler')
|
|
10
|
+
serving=sub.add_parser('serve');serving.add_argument('--host',default='127.0.0.1');serving.add_argument('--port',type=int,default=8080)
|
|
11
|
+
importing=sub.add_parser('import');importing.add_argument('path');importing.add_argument('--collection',required=True);importing.add_argument('--kind',choices=['source','root-filesystem'],required=True)
|
|
12
|
+
reviewed=sub.add_parser('populate-sources');reviewed.add_argument('manifest')
|
|
13
|
+
release=sub.add_parser('release-source-pin-set');release.add_argument('identity')
|
|
14
|
+
notice=sub.add_parser('notices');notice.add_argument('collection');notice.add_argument('digest')
|
|
15
|
+
evidence=notice.add_mutually_exclusive_group(required=True)
|
|
16
|
+
evidence.add_argument('--source-record');evidence.add_argument('--sidecar');evidence.add_argument('--rootfs-receipts',action='store_true')
|
|
17
|
+
notice.add_argument('--generation');notice.add_argument('--retained-inputs')
|
|
18
|
+
importing.add_argument('--license-sidecar');importing.add_argument('--source-record')
|
|
19
|
+
importing.add_argument('--rootfs-receipts',action='store_true');importing.add_argument('--generation');importing.add_argument('--retained-inputs')
|
|
20
|
+
for name in ('pin','unpin'):
|
|
21
|
+
p=sub.add_parser(name);p.add_argument('collection');p.add_argument('digest');p.add_argument('name')
|
|
22
|
+
args=parser.parse_args()
|
|
23
|
+
os.environ.setdefault('DJANGO_SETTINGS_MODULE','zog.archive_mirror.settings')
|
|
24
|
+
import django;django.setup()
|
|
25
|
+
from . import store
|
|
26
|
+
try:
|
|
27
|
+
if args.command=='migrate':
|
|
28
|
+
from django.core.management import call_command
|
|
29
|
+
call_command('migrate',interactive=False)
|
|
30
|
+
elif args.command=='import':
|
|
31
|
+
record=store.publish(args.path,args.collection,args.kind,{'import':'local','release_approved':False})
|
|
32
|
+
if args.license_sidecar or args.rootfs_receipts or args.source_record:
|
|
33
|
+
attach_notices(record, args.license_sidecar, args.rootfs_receipts, args.generation, args.retained_inputs, args.source_record)
|
|
34
|
+
print(json.dumps({'sha256':record.digest,'bytes':record.size}))
|
|
35
|
+
elif args.command=='populate-sources':
|
|
36
|
+
from .source_inputs import populate
|
|
37
|
+
pin_set,archives=populate(args.manifest)
|
|
38
|
+
print(json.dumps({'pin_set':pin_set.identity,'manifest_sha256':pin_set.manifest_sha256,
|
|
39
|
+
'active':pin_set.active,'sources':len(archives),'digests':sorted({x.digest for x in archives})}))
|
|
40
|
+
elif args.command=='release-source-pin-set':
|
|
41
|
+
from .source_inputs import deactivate
|
|
42
|
+
pin_set=deactivate(args.identity)
|
|
43
|
+
print(json.dumps({'pin_set':pin_set.identity,'active':pin_set.active}))
|
|
44
|
+
elif args.command=='notices':
|
|
45
|
+
from .models import Archive
|
|
46
|
+
record=Archive.objects.get(collection=args.collection,digest=args.digest)
|
|
47
|
+
print(json.dumps(attach_notices(record,args.sidecar,args.rootfs_receipts,args.generation,args.retained_inputs,args.source_record)))
|
|
48
|
+
elif args.command in ('pin','unpin'):store.pin(args.collection,args.digest,args.name,args.command=='unpin')
|
|
49
|
+
elif args.command=='prune':store.prune()
|
|
50
|
+
elif args.command=='refresh':
|
|
51
|
+
from .collector import collect
|
|
52
|
+
from .config import configuration
|
|
53
|
+
from .lease import lease
|
|
54
|
+
from .models import CollectionStatus
|
|
55
|
+
from django.utils import timezone
|
|
56
|
+
failed=False
|
|
57
|
+
for definition in configuration().get('sources',[]):
|
|
58
|
+
lease()
|
|
59
|
+
status,_=CollectionStatus.objects.update_or_create(source=definition['name'],defaults={'last_attempt':timezone.now()})
|
|
60
|
+
try:
|
|
61
|
+
collect(definition,require_lease=True)
|
|
62
|
+
status.last_success=timezone.now();status.error='';status.save()
|
|
63
|
+
except Exception as error:
|
|
64
|
+
status.error=type(error).__name__;status.save()
|
|
65
|
+
print('Collection failed: '+type(error).__name__,file=sys.stderr);failed=True
|
|
66
|
+
lease();store.prune()
|
|
67
|
+
if failed:raise RuntimeError('Some sources failed')
|
|
68
|
+
elif args.command=='scheduler':
|
|
69
|
+
from .runtime import scheduler
|
|
70
|
+
scheduler()
|
|
71
|
+
elif args.command=='serve':
|
|
72
|
+
from .runtime import server
|
|
73
|
+
server(args.host,args.port)
|
|
74
|
+
except Exception as error:
|
|
75
|
+
print('archive-mirror failed: '+type(error).__name__,file=sys.stderr);return 1
|
|
76
|
+
return 0
|
|
77
|
+
|
|
78
|
+
def attach_notices(record, sidecar, rootfs, generation, retained_inputs, source_record=None):
|
|
79
|
+
from . import notices, notice_contract
|
|
80
|
+
if sum(bool(x) for x in (sidecar, rootfs, source_record)) != 1:
|
|
81
|
+
raise ValueError('Choose one evidence source')
|
|
82
|
+
if source_record:
|
|
83
|
+
from .source_notices import build
|
|
84
|
+
value=build(record,source_record)
|
|
85
|
+
elif rootfs:
|
|
86
|
+
from .receipt_notices import build
|
|
87
|
+
value=build(record,generation,retained_inputs)
|
|
88
|
+
else:
|
|
89
|
+
with open(sidecar,'rb') as stream:
|
|
90
|
+
value=notice_contract.decode(stream.read(notice_contract.MAX_BUNDLE+1))
|
|
91
|
+
return notices.publish(record,value)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import lzma
|
|
3
|
+
import os
|
|
4
|
+
import subprocess
|
|
5
|
+
import tarfile
|
|
6
|
+
import tempfile
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from .models import Snapshot
|
|
9
|
+
from .store import publish
|
|
10
|
+
|
|
11
|
+
def run(arguments, **kwargs):
|
|
12
|
+
environment={**os.environ,'GIT_TERMINAL_PROMPT':'0','GIT_CONFIG_NOSYSTEM':'1','GIT_CONFIG_GLOBAL':'/dev/null','GIT_ALLOW_PROTOCOL':'https:file'}
|
|
13
|
+
return subprocess.run(arguments,check=True,timeout=300,env=environment,stdout=subprocess.PIPE,stderr=subprocess.PIPE,**kwargs).stdout
|
|
14
|
+
|
|
15
|
+
def collect(definition,month=None,allow_local=False,require_lease=False):
|
|
16
|
+
name=definition['name'];url=definition['url'];branch=definition['branch']
|
|
17
|
+
import re
|
|
18
|
+
if not isinstance(name,str) or not re.fullmatch('[a-z0-9][a-z0-9_-]{0,127}',name):raise ValueError('Invalid source name')
|
|
19
|
+
month=month or datetime.datetime.now(datetime.timezone.utc).strftime('%Y-%m')
|
|
20
|
+
previous=Snapshot.objects.filter(source=name,month=month).select_related('archive').first()
|
|
21
|
+
if previous:return with_notices(previous.archive, definition)
|
|
22
|
+
if not url.startswith('https://') and not (allow_local and Path(url).is_absolute()):raise ValueError('HTTPS upstream required')
|
|
23
|
+
from urllib.parse import urlsplit
|
|
24
|
+
parts=urlsplit(url)
|
|
25
|
+
if parts.username or parts.password or parts.query or parts.fragment:raise ValueError('Credential-free upstream URL required')
|
|
26
|
+
run(['git','check-ref-format','--branch',branch])
|
|
27
|
+
with tempfile.TemporaryDirectory(prefix='archive-collect-') as work:
|
|
28
|
+
root=Path(work);repo=root/'repository'
|
|
29
|
+
run(['git','clone','--depth','1','--single-branch','--no-tags','--no-checkout','--branch',branch,'--',url,str(repo)])
|
|
30
|
+
commit=run(['git','-C',str(repo),'rev-parse','HEAD']).decode().strip()
|
|
31
|
+
listing=run(['git','-C',str(repo),'ls-tree','-r','-z','HEAD']).split(b'\0')
|
|
32
|
+
files=[]
|
|
33
|
+
if len(listing)>100001:raise ValueError('Too many tracked paths')
|
|
34
|
+
for item in filter(None,listing):
|
|
35
|
+
metadata,path=item.split(b'\t',1);mode,kind,oid=metadata.split()
|
|
36
|
+
if mode==b'160000':raise ValueError('Submodules unsupported in pass 1')
|
|
37
|
+
if path==b'.gitmodules':raise ValueError('Submodules unsupported in pass 1')
|
|
38
|
+
files.append((path,mode,oid))
|
|
39
|
+
archive=root/'source.tar.xz'
|
|
40
|
+
with lzma.open(archive,'wb',preset=6) as compressed,tarfile.open(fileobj=compressed,mode='w|',format=tarfile.PAX_FORMAT) as output:
|
|
41
|
+
import io
|
|
42
|
+
total=0
|
|
43
|
+
for path,mode,oid in sorted(files):
|
|
44
|
+
size=int(run(['git','-C',str(repo),'cat-file','-s',oid.decode()]))
|
|
45
|
+
total+=size
|
|
46
|
+
if size>64*1024**2 or total>2*1024**3:raise ValueError('Source export limit exceeded')
|
|
47
|
+
data=run(['git','-C',str(repo),'cat-file','blob',oid.decode()])
|
|
48
|
+
if data.startswith(b'version https://git-lfs.github.com/spec/v1\n'):raise ValueError('Git LFS unsupported in pass 1')
|
|
49
|
+
text=path.decode('utf-8')
|
|
50
|
+
if text.startswith('/') or '..' in Path(text).parts:raise ValueError('Unsafe tracked path')
|
|
51
|
+
entry=tarfile.TarInfo(name+'/'+text);entry.uid=entry.gid=entry.mtime=0;entry.uname=entry.gname=''
|
|
52
|
+
if mode==b'120000':entry.type=tarfile.SYMTYPE;entry.linkname=data.decode();entry.mode=0o777
|
|
53
|
+
else:entry.mode=0o755 if mode==b'100755' else 0o644;entry.size=len(data)
|
|
54
|
+
output.addfile(entry,io.BytesIO(data) if entry.isfile() else None)
|
|
55
|
+
if require_lease:
|
|
56
|
+
from .lease import lease
|
|
57
|
+
lease()
|
|
58
|
+
result = publish(archive,'sources','source',{'url':url,'branch':branch,'commit':commit,'export_recipe':'tracked-tree-v1','attributes':'ignored'},name,month,commit)
|
|
59
|
+
|
|
60
|
+
return with_notices(result, definition)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def with_notices(archive, definition):
|
|
64
|
+
"""Operator-supplied, exact export sidecar; no repository HEAD inference."""
|
|
65
|
+
if definition.get('license_sidecar'):
|
|
66
|
+
from . import notice_contract, notices
|
|
67
|
+
with open(definition['license_sidecar'], 'rb') as stream:
|
|
68
|
+
value = notice_contract.decode(stream.read(notice_contract.MAX_BUNDLE+1))
|
|
69
|
+
notices.publish(archive, value)
|
|
70
|
+
return archive
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import re
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from django.conf import settings
|
|
6
|
+
|
|
7
|
+
def configuration():
|
|
8
|
+
value = json.loads(Path(settings.ARCHIVE_MIRROR_CONFIGURATION).read_text())
|
|
9
|
+
root = Path(value['root'])
|
|
10
|
+
if not root.is_absolute() or root == Path('/') or root.is_symlink():
|
|
11
|
+
raise ValueError('Explicit persistent archive root required')
|
|
12
|
+
if not isinstance(value['collections'], list) or not value['collections']:
|
|
13
|
+
raise ValueError('Collections required')
|
|
14
|
+
for name in value['collections']:
|
|
15
|
+
if not isinstance(name,str) or not re.fullmatch(r'[a-z0-9][a-z0-9_-]{0,63}', name):
|
|
16
|
+
raise ValueError('Invalid collection')
|
|
17
|
+
return value
|
|
18
|
+
|
|
19
|
+
def collection(name):
|
|
20
|
+
if name not in configuration()['collections']:
|
|
21
|
+
raise ValueError('Unknown collection')
|
|
22
|
+
return name
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import stat
|
|
4
|
+
import time
|
|
5
|
+
import uuid
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from .config import configuration
|
|
8
|
+
|
|
9
|
+
def lease():
|
|
10
|
+
config=configuration();expected=str(uuid.UUID(config['host_id']))
|
|
11
|
+
path=Path(config['intent_file'])
|
|
12
|
+
fd=os.open(path,os.O_RDONLY|os.O_NOFOLLOW)
|
|
13
|
+
with os.fdopen(fd,'rb') as source:
|
|
14
|
+
info=os.fstat(source.fileno())
|
|
15
|
+
if not stat.S_ISREG(info.st_mode) or info.st_size>32768 or info.st_mode & 0o022:raise ValueError('Unsafe role intent')
|
|
16
|
+
value=json.load(source)
|
|
17
|
+
desired=value['desired'];expires=desired['lease_expires_at']
|
|
18
|
+
if value['version']!=1 or value['host_id']!=expected or desired['version']!=1 or desired['selected'] is not True:
|
|
19
|
+
raise ValueError('Role not selected')
|
|
20
|
+
if type(expires) is not int or not time.time()<expires<=time.time()+905:raise ValueError('Role lease expired')
|
|
21
|
+
if type(desired['revision']) is not int or desired['revision']<1 or desired['endpoint']!=config['endpoint']:raise ValueError('Role binding mismatch')
|
|
22
|
+
return value
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Generated by Django 5.2.17 on 2026-09-25 20:15
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
initial = True
|
|
10
|
+
|
|
11
|
+
dependencies = [
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
operations = [
|
|
15
|
+
migrations.CreateModel(
|
|
16
|
+
name='Archive',
|
|
17
|
+
fields=[
|
|
18
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
19
|
+
('collection', models.CharField(max_length=64)),
|
|
20
|
+
('digest', models.CharField(max_length=64)),
|
|
21
|
+
('size', models.PositiveBigIntegerField()),
|
|
22
|
+
('kind', models.CharField(max_length=32)),
|
|
23
|
+
('managed', models.BooleanField(default=False)),
|
|
24
|
+
('provenance', models.JSONField(default=dict)),
|
|
25
|
+
('created', models.DateTimeField(auto_now_add=True)),
|
|
26
|
+
],
|
|
27
|
+
options={
|
|
28
|
+
'constraints': [models.UniqueConstraint(fields=('collection', 'digest'), name='mirror_collection_digest')],
|
|
29
|
+
},
|
|
30
|
+
),
|
|
31
|
+
migrations.CreateModel(
|
|
32
|
+
name='Pin',
|
|
33
|
+
fields=[
|
|
34
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
35
|
+
('name', models.CharField(max_length=200)),
|
|
36
|
+
('archive', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='archive_mirror.archive')),
|
|
37
|
+
],
|
|
38
|
+
options={
|
|
39
|
+
'constraints': [models.UniqueConstraint(fields=('archive', 'name'), name='mirror_archive_pin')],
|
|
40
|
+
},
|
|
41
|
+
),
|
|
42
|
+
migrations.CreateModel(
|
|
43
|
+
name='Snapshot',
|
|
44
|
+
fields=[
|
|
45
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
46
|
+
('source', models.CharField(max_length=128)),
|
|
47
|
+
('month', models.CharField(max_length=7)),
|
|
48
|
+
('commit', models.CharField(max_length=64)),
|
|
49
|
+
('archive', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='archive_mirror.archive')),
|
|
50
|
+
],
|
|
51
|
+
options={
|
|
52
|
+
'constraints': [models.UniqueConstraint(fields=('source', 'month'), name='mirror_source_month')],
|
|
53
|
+
},
|
|
54
|
+
),
|
|
55
|
+
]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Generated by Django 5.2.17 on 2026-09-25 20:20
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
('archive_mirror', '0001_initial'),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.CreateModel(
|
|
14
|
+
name='CollectionStatus',
|
|
15
|
+
fields=[
|
|
16
|
+
('source', models.CharField(max_length=128, primary_key=True, serialize=False)),
|
|
17
|
+
('last_attempt', models.DateTimeField()),
|
|
18
|
+
('last_success', models.DateTimeField(null=True)),
|
|
19
|
+
('error', models.CharField(blank=True, max_length=100)),
|
|
20
|
+
],
|
|
21
|
+
),
|
|
22
|
+
]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Generated manually for reviewed source pin sets.
|
|
2
|
+
import django.db.models.deletion
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
class Migration(migrations.Migration):
|
|
6
|
+
dependencies = [('archive_mirror', '0002_collectionstatus')]
|
|
7
|
+
operations = [
|
|
8
|
+
migrations.CreateModel(
|
|
9
|
+
name='SourcePinSet',
|
|
10
|
+
fields=[
|
|
11
|
+
('identity', models.CharField(max_length=180, primary_key=True, serialize=False)),
|
|
12
|
+
('pin_date', models.DateField()),
|
|
13
|
+
('manifest_sha256', models.CharField(max_length=64)),
|
|
14
|
+
('complete', models.BooleanField(default=False)),
|
|
15
|
+
('active', models.BooleanField(default=False)),
|
|
16
|
+
('created', models.DateTimeField(auto_now_add=True)),
|
|
17
|
+
],
|
|
18
|
+
),
|
|
19
|
+
migrations.CreateModel(
|
|
20
|
+
name='ReviewedSource',
|
|
21
|
+
fields=[
|
|
22
|
+
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
23
|
+
('package', models.CharField(blank=True, max_length=200)),
|
|
24
|
+
('source', models.CharField(blank=True, max_length=200)),
|
|
25
|
+
('canonical_url', models.TextField()),
|
|
26
|
+
('archive', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reviewed_sources', to='archive_mirror.archive')),
|
|
27
|
+
('pin_set', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sources', to='archive_mirror.sourcepinset')),
|
|
28
|
+
],
|
|
29
|
+
options={
|
|
30
|
+
'constraints': [models.UniqueConstraint(fields=('pin_set','archive','package','source','canonical_url'), name='mirror_reviewed_source_identity')],
|
|
31
|
+
},
|
|
32
|
+
),
|
|
33
|
+
]
|
|
File without changes
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
class Archive(models.Model):
|
|
4
|
+
collection = models.CharField(max_length=64)
|
|
5
|
+
digest = models.CharField(max_length=64)
|
|
6
|
+
size = models.PositiveBigIntegerField()
|
|
7
|
+
kind = models.CharField(max_length=32)
|
|
8
|
+
managed = models.BooleanField(default=False)
|
|
9
|
+
provenance = models.JSONField(default=dict)
|
|
10
|
+
created = models.DateTimeField(auto_now_add=True)
|
|
11
|
+
class Meta:
|
|
12
|
+
constraints = [models.UniqueConstraint(fields=['collection','digest'], name='mirror_collection_digest')]
|
|
13
|
+
|
|
14
|
+
class Snapshot(models.Model):
|
|
15
|
+
source = models.CharField(max_length=128)
|
|
16
|
+
month = models.CharField(max_length=7)
|
|
17
|
+
archive = models.ForeignKey(Archive, on_delete=models.PROTECT)
|
|
18
|
+
commit = models.CharField(max_length=64)
|
|
19
|
+
class Meta:
|
|
20
|
+
constraints = [models.UniqueConstraint(fields=['source','month'], name='mirror_source_month')]
|
|
21
|
+
|
|
22
|
+
class Pin(models.Model):
|
|
23
|
+
archive = models.ForeignKey(Archive, on_delete=models.CASCADE)
|
|
24
|
+
name = models.CharField(max_length=200)
|
|
25
|
+
class Meta:
|
|
26
|
+
constraints = [models.UniqueConstraint(fields=['archive','name'], name='mirror_archive_pin')]
|
|
27
|
+
|
|
28
|
+
class CollectionStatus(models.Model):
|
|
29
|
+
source = models.CharField(max_length=128, primary_key=True)
|
|
30
|
+
last_attempt = models.DateTimeField()
|
|
31
|
+
last_success = models.DateTimeField(null=True)
|
|
32
|
+
error = models.CharField(max_length=100, blank=True)
|
|
33
|
+
|
|
34
|
+
class SourcePinSet(models.Model):
|
|
35
|
+
identity = models.CharField(max_length=180, primary_key=True)
|
|
36
|
+
pin_date = models.DateField()
|
|
37
|
+
manifest_sha256 = models.CharField(max_length=64)
|
|
38
|
+
complete = models.BooleanField(default=False)
|
|
39
|
+
active = models.BooleanField(default=False)
|
|
40
|
+
created = models.DateTimeField(auto_now_add=True)
|
|
41
|
+
|
|
42
|
+
class ReviewedSource(models.Model):
|
|
43
|
+
pin_set = models.ForeignKey(SourcePinSet, on_delete=models.CASCADE, related_name='sources')
|
|
44
|
+
archive = models.ForeignKey(Archive, on_delete=models.CASCADE, related_name='reviewed_sources')
|
|
45
|
+
package = models.CharField(max_length=200, blank=True)
|
|
46
|
+
source = models.CharField(max_length=200, blank=True)
|
|
47
|
+
canonical_url = models.TextField()
|
|
48
|
+
class Meta:
|
|
49
|
+
constraints = [models.UniqueConstraint(
|
|
50
|
+
fields=['pin_set','archive','package','source','canonical_url'],
|
|
51
|
+
name='mirror_reviewed_source_identity')]
|