bazaar-compute-node 0.1.36__tar.gz → 0.1.37__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.
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/PKG-INFO +1 -1
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/pyproject.toml +1 -1
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/pyproject.toml.orig +1 -1
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/agent.py +1 -1
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/application.py +11 -6
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/resource_dispatch.py +14 -4
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/system_service.py +11 -70
- bazaar_compute_node-0.1.37/src/bazaar_compute_node/app/upgrade.py +151 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/bcc.py +14 -3
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/orchestration/turn.py +4 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/inbox_notice.tpl +1 -1
- bazaar_compute_node-0.1.37/src/bazaar_compute_node/resources/system_service/windows.ps1 +98 -0
- bazaar_compute_node-0.1.36/src/bazaar_compute_node/app/upgrade.py +0 -321
- bazaar_compute_node-0.1.36/src/bazaar_compute_node/resources/system_service/replace_managed_file.ps1 +0 -16
- bazaar_compute_node-0.1.36/src/bazaar_compute_node/resources/system_service/windows.ps1 +0 -157
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/LICENSE +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/README.md +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/agent_management.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/attachments.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/command.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/config.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/registry.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/transport.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/version_check.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/windows_pipe.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/wrapper.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/cli.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/claude/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/claude/approval.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/claude/client.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/claude/events.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/claude/plugin.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/claude/process.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/claude/protocol.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/claude/runtime.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/codex/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/codex/approval.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/codex/client.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/codex/events.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/codex/plugin.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/codex/process.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/codex/protocol.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/codex/runtime.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/lark/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/lark/api.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/lark/approval.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/lark/attachments.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/lark/channel.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/lark/frame.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/lark/identity.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/lark/outbound.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/lark/plugin.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/lark/transport.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/logging/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/logging/audit.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/logging/plugin.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/codec.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/database.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/executor.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/model.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/registry.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v01_initial_node_schema.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v02_session_mapping_indexes.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v03_message_log_indexes.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v04_runtime_attempt_facts.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v05_inbound_message_references.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v06_inbound_message_reference_integrity.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v07_inbound_provider_identity.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v08_transient_stream_events.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v09_remove_runtime_events.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v10_add_outbound_attachments.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v11_remove_runtime_session_mapping.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v12_add_reminders.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v13_add_agent_ownership.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v14_add_inbox_discovery_indexes.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v15_add_handoffs.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v16_remove_outbound_drafts.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v17_remove_agent_identity_triggers.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v18_unify_messages.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v19_reminder_system_messages.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v20_remove_freshness_persistence.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v21_remove_handoffs.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v22_readable_targets.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v23_persist_sender_identity.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/migrations/v24_persist_sender_display_name.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/plugin.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/reminder_codec.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/repository/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/repository/base.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/repository/facade.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/repository/messages.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/repository/reminders.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/repository/sessions.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/sqlite/storage.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/telegram/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/telegram/api.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/telegram/approval.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/telegram/attachments.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/telegram/channel.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/telegram/identity.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/telegram/markdown.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/telegram/outbound.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/telegram/plugin.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/wecom/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/wecom/channel.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/wecom/markdown.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/wecom/outbound.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/contrib/wecom/plugin.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/approval.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/audit.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/channel.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/client.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/command.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/concurrency.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/correlation.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/inbox.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/instruction.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/lifecycle.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/models/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/models/entities.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/models/reminder.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/models/reminder_owner.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/models/states.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/observability.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/orchestration/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/orchestration/command.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/orchestration/delivery.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/orchestration/error_feedback.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/orchestration/reminder.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/orchestration/reminder_command.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/orchestration/runtime_pool.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/orchestration/services.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/orchestration/session.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/orchestration/upgrade_notice.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/outcomes.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/paths.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/reminder.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/reminder_schedule.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/restart.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/runtime.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/storage.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/timerwheel.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/utils/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/core/utils/line_reader.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/i18n/__init__.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/i18n/catalog.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/rendering.py +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/bcc/check.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/bcc/error.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/bcc/inbox_list.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/bcc/inbox_target.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/bcc/read.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/bcc/reminder_list.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/bcc/reminder_mutation.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/bcc/reminder_schedule.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/bcc/unfollow.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/bcc/upgrade.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/bcc/version.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/command/attachment_suffix.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/command/check_message.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/command/freshness_hold.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/command/read_message.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/command/send_result.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/command/sender.tpl +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/developer_instructions.md +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/locales/en.toml +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/locales/zh-CN.toml +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/system_service/launchd.plist +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/system_service/launchd.sh +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/system_service/systemd.service +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/system_service/windows.vbs +0 -0
- {bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/resources/system_service/windows.xml +0 -0
{bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/agent.py
RENAMED
|
@@ -79,7 +79,7 @@ class AgentApplication:
|
|
|
79
79
|
endpoint: Callable[[], str],
|
|
80
80
|
timeout_budget: TimeoutBudget,
|
|
81
81
|
translator: Translator,
|
|
82
|
-
upgrade_service: UpgradeService,
|
|
82
|
+
upgrade_service: UpgradeService | None,
|
|
83
83
|
upgrade_notice: Callable[[], tuple[str, str] | None] = lambda: None,
|
|
84
84
|
) -> None:
|
|
85
85
|
self.configuration = configuration
|
{bazaar_compute_node-0.1.36 → bazaar_compute_node-0.1.37}/src/bazaar_compute_node/app/application.py
RENAMED
|
@@ -24,7 +24,7 @@ from .agent import AgentApplication
|
|
|
24
24
|
from .config import AgentConfiguration, NodeConfiguration
|
|
25
25
|
from .registry import AdapterRegistry, SharedAdapterFactories
|
|
26
26
|
from .transport import LocalCommandServer
|
|
27
|
-
from .upgrade import UpgradeService
|
|
27
|
+
from .upgrade import UpgradeService
|
|
28
28
|
from .version_check import VersionWatcher
|
|
29
29
|
|
|
30
30
|
|
|
@@ -94,10 +94,16 @@ class NodeApplication:
|
|
|
94
94
|
request_timeout_seconds=self.timeout_budget.command_seconds,
|
|
95
95
|
)
|
|
96
96
|
self._restart_requested = False
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
# Windows has nothing that brings the node back after it exits, so
|
|
98
|
+
# there it offers no upgrade command at all
|
|
99
|
+
self.upgrade_service = (
|
|
100
|
+
None
|
|
101
|
+
if os.name == "nt"
|
|
102
|
+
else UpgradeService(
|
|
103
|
+
available_version=self.version_watcher.available_version,
|
|
104
|
+
installed_version=__version__,
|
|
105
|
+
request_restart=self.request_restart,
|
|
106
|
+
)
|
|
101
107
|
)
|
|
102
108
|
self.command_server = LocalCommandServer(
|
|
103
109
|
self._dispatch,
|
|
@@ -155,7 +161,6 @@ class NodeApplication:
|
|
|
155
161
|
raise
|
|
156
162
|
self._ready = True
|
|
157
163
|
self._accepting = True
|
|
158
|
-
await asyncio.to_thread(discard_replaced_release, __version__)
|
|
159
164
|
started_count = len(self.agents)
|
|
160
165
|
failed_count = len(self.configuration.agents) - started_count
|
|
161
166
|
self._log(
|
|
@@ -195,7 +195,7 @@ class CommandDispatcher(_MessageCommandDispatcher):
|
|
|
195
195
|
reminder_service: IReminderService,
|
|
196
196
|
timeout_budget: TimeoutBudget,
|
|
197
197
|
session_binding_validator: SessionBindingValidator | None = None,
|
|
198
|
-
upgrade_service: UpgradeService,
|
|
198
|
+
upgrade_service: UpgradeService | None,
|
|
199
199
|
) -> None:
|
|
200
200
|
super().__init__(
|
|
201
201
|
service,
|
|
@@ -247,6 +247,14 @@ class CommandDispatcher(_MessageCommandDispatcher):
|
|
|
247
247
|
if resource == "inbox":
|
|
248
248
|
return await super()._dispatch_command(raw_request)
|
|
249
249
|
if resource == "node":
|
|
250
|
+
upgrade_service = self._upgrade_service
|
|
251
|
+
if upgrade_service is None:
|
|
252
|
+
# nothing on this platform would bring the node back after an
|
|
253
|
+
# upgrade exits it, so the Agent is given no upgrade to run
|
|
254
|
+
raise CommandDispatchError(
|
|
255
|
+
"UNKNOWN_RESOURCE",
|
|
256
|
+
f"unsupported command resource: {resource}",
|
|
257
|
+
)
|
|
250
258
|
if command not in {"upgrade", "version"}:
|
|
251
259
|
raise CommandDispatchError(
|
|
252
260
|
"UNKNOWN_COMMAND",
|
|
@@ -256,7 +264,7 @@ class CommandDispatcher(_MessageCommandDispatcher):
|
|
|
256
264
|
return {
|
|
257
265
|
"ok": True,
|
|
258
266
|
"result": {
|
|
259
|
-
"version":
|
|
267
|
+
"version": upgrade_service.installed_version,
|
|
260
268
|
},
|
|
261
269
|
}
|
|
262
270
|
request = _parse_command_request(
|
|
@@ -275,6 +283,7 @@ class CommandDispatcher(_MessageCommandDispatcher):
|
|
|
275
283
|
return await self._dispatch_upgrade(
|
|
276
284
|
session_id,
|
|
277
285
|
cast(_NodeUpgradeRequest, request),
|
|
286
|
+
upgrade_service,
|
|
278
287
|
)
|
|
279
288
|
if resource != "reminder":
|
|
280
289
|
raise CommandDispatchError(
|
|
@@ -311,6 +320,7 @@ class CommandDispatcher(_MessageCommandDispatcher):
|
|
|
311
320
|
self,
|
|
312
321
|
session_id: str,
|
|
313
322
|
request: _NodeUpgradeRequest,
|
|
323
|
+
upgrade_service: UpgradeService,
|
|
314
324
|
) -> Mapping[str, object]:
|
|
315
325
|
async def wake_after(upgrade_version: str) -> str | None:
|
|
316
326
|
# the reminder is how the Agent is prompted to check the node over
|
|
@@ -335,7 +345,7 @@ class CommandDispatcher(_MessageCommandDispatcher):
|
|
|
335
345
|
return result.reminder.reminder_id
|
|
336
346
|
|
|
337
347
|
try:
|
|
338
|
-
upgrade_version, reminder_id = await
|
|
348
|
+
upgrade_version, reminder_id = await upgrade_service.upgrade(
|
|
339
349
|
wake_after=wake_after,
|
|
340
350
|
)
|
|
341
351
|
except UpgradeUnavailable as error:
|
|
@@ -355,7 +365,7 @@ class CommandDispatcher(_MessageCommandDispatcher):
|
|
|
355
365
|
return {
|
|
356
366
|
"ok": True,
|
|
357
367
|
"result": {
|
|
358
|
-
"installed_version":
|
|
368
|
+
"installed_version": upgrade_service.installed_version,
|
|
359
369
|
"upgrade_version": upgrade_version,
|
|
360
370
|
"reminder_id": reminder_id,
|
|
361
371
|
},
|
|
@@ -6,7 +6,6 @@ import getpass
|
|
|
6
6
|
import locale
|
|
7
7
|
import os
|
|
8
8
|
import platform
|
|
9
|
-
import re
|
|
10
9
|
import shlex
|
|
11
10
|
import shutil
|
|
12
11
|
import subprocess
|
|
@@ -16,9 +15,7 @@ import time
|
|
|
16
15
|
from dataclasses import dataclass
|
|
17
16
|
from pathlib import Path
|
|
18
17
|
|
|
19
|
-
from .. import __distribution__
|
|
20
18
|
from ..core.paths import resolve_data_dir
|
|
21
|
-
from ..core.restart import RESTART_EXIT_CODE
|
|
22
19
|
from ..i18n import Translator, create_translator
|
|
23
20
|
from ..rendering import TextTemplate
|
|
24
21
|
from .config import ConfigurationError, load_control_configuration, resolve_config_path
|
|
@@ -28,10 +25,6 @@ SYSTEMD_UNIT_NAME = "bcn.service"
|
|
|
28
25
|
LAUNCHD_LABEL = "io.github.yuchanns.bazaar-compute-node"
|
|
29
26
|
WINDOWS_TASK_NAME = r"\BazaarComputeNode"
|
|
30
27
|
MANAGED_MARKER = "Managed by bazaar-compute-node."
|
|
31
|
-
# raised whenever a managed file's content changes, so an upgrade can tell that
|
|
32
|
-
# the installed copy predates what this release expects of it
|
|
33
|
-
TEMPLATE_REVISION = 1
|
|
34
|
-
MANAGED_MARKER_LINE = f"{MANAGED_MARKER} template-revision={TEMPLATE_REVISION}"
|
|
35
28
|
WINDOWS_STOP_ATTEMPTS = 100
|
|
36
29
|
WINDOWS_STOP_INTERVAL = 0.05
|
|
37
30
|
|
|
@@ -180,7 +173,7 @@ def _powershell_literal(path: Path | str | None) -> str:
|
|
|
180
173
|
def _render_systemd_unit(context: SystemServiceContext) -> str:
|
|
181
174
|
return _SYSTEMD_UNIT_TEMPLATE.render(
|
|
182
175
|
{
|
|
183
|
-
"managed_marker":
|
|
176
|
+
"managed_marker": MANAGED_MARKER,
|
|
184
177
|
"executable": _systemd_quote(_require_executable(context)),
|
|
185
178
|
"config_path": _systemd_quote(context.config_path),
|
|
186
179
|
"data_dir": _systemd_quote(context.data_dir),
|
|
@@ -192,7 +185,7 @@ def _render_systemd_unit(context: SystemServiceContext) -> str:
|
|
|
192
185
|
|
|
193
186
|
|
|
194
187
|
def _render_launchd_wrapper() -> str:
|
|
195
|
-
return _LAUNCHD_WRAPPER_TEMPLATE.render({"managed_marker":
|
|
188
|
+
return _LAUNCHD_WRAPPER_TEMPLATE.render({"managed_marker": MANAGED_MARKER})
|
|
196
189
|
|
|
197
190
|
|
|
198
191
|
def _render_launchd_plist(
|
|
@@ -202,7 +195,7 @@ def _render_launchd_plist(
|
|
|
202
195
|
return _LAUNCHD_PLIST_TEMPLATE.render(
|
|
203
196
|
{
|
|
204
197
|
"label": LAUNCHD_LABEL,
|
|
205
|
-
"managed_marker":
|
|
198
|
+
"managed_marker": MANAGED_MARKER,
|
|
206
199
|
"wrapper_path": str(wrapper_path),
|
|
207
200
|
"data_dir": str(context.data_dir),
|
|
208
201
|
"config_path": str(context.config_path),
|
|
@@ -215,70 +208,18 @@ def _render_launchd_plist(
|
|
|
215
208
|
).encode("utf-8")
|
|
216
209
|
|
|
217
210
|
|
|
218
|
-
def
|
|
219
|
-
*,
|
|
220
|
-
executable: str,
|
|
221
|
-
config_path: str,
|
|
222
|
-
environment_script: str,
|
|
223
|
-
log_path: str,
|
|
224
|
-
) -> str:
|
|
225
|
-
"""Render the launcher from PowerShell literals, however they were obtained."""
|
|
226
|
-
|
|
211
|
+
def _render_windows_wrapper(context: SystemServiceContext) -> str:
|
|
227
212
|
return _WINDOWS_WRAPPER_TEMPLATE.render(
|
|
228
213
|
{
|
|
229
|
-
"managed_marker":
|
|
230
|
-
"executable":
|
|
231
|
-
"config_path": config_path,
|
|
232
|
-
"environment_script":
|
|
233
|
-
"log_path": log_path,
|
|
234
|
-
"distribution": _powershell_literal(__distribution__),
|
|
235
|
-
"restart_exit_code": RESTART_EXIT_CODE,
|
|
214
|
+
"managed_marker": MANAGED_MARKER,
|
|
215
|
+
"executable": _powershell_literal(_require_executable(context)),
|
|
216
|
+
"config_path": _powershell_literal(context.config_path),
|
|
217
|
+
"environment_script": _powershell_literal(context.env_file),
|
|
218
|
+
"log_path": _powershell_literal(context.log_path),
|
|
236
219
|
}
|
|
237
220
|
)
|
|
238
221
|
|
|
239
222
|
|
|
240
|
-
def _render_windows_wrapper(context: SystemServiceContext) -> str:
|
|
241
|
-
return render_windows_wrapper(
|
|
242
|
-
executable=_powershell_literal(_require_executable(context)),
|
|
243
|
-
config_path=_powershell_literal(context.config_path),
|
|
244
|
-
environment_script=_powershell_literal(context.env_file),
|
|
245
|
-
log_path=_powershell_literal(context.log_path),
|
|
246
|
-
)
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
def windows_wrapper_path() -> Path:
|
|
250
|
-
"""Return where the launcher lives, without needing the install arguments."""
|
|
251
|
-
|
|
252
|
-
return resolve_data_dir() / "bcn-system-service.ps1"
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
def windows_tool_directory() -> Path | None:
|
|
256
|
-
"""Return the directory uv keeps its installed tools in, where there is one."""
|
|
257
|
-
|
|
258
|
-
configured = os.environ.get("UV_TOOL_DIR")
|
|
259
|
-
if configured:
|
|
260
|
-
return Path(configured).expanduser()
|
|
261
|
-
app_data = os.environ.get("APPDATA")
|
|
262
|
-
return None if not app_data else Path(app_data) / "uv" / "tools"
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
def windows_live_directory() -> Path | None:
|
|
266
|
-
"""Return the installed tool directory an upgrade swaps into place."""
|
|
267
|
-
|
|
268
|
-
tools = windows_tool_directory()
|
|
269
|
-
return None if tools is None else tools / __distribution__
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
def installed_template_revision(content: str) -> int | None:
|
|
273
|
-
"""Read the revision a managed file was written from, if it declares one."""
|
|
274
|
-
|
|
275
|
-
first_line = content.splitlines()[0] if content else ""
|
|
276
|
-
if MANAGED_MARKER not in first_line:
|
|
277
|
-
return None
|
|
278
|
-
match = re.search(r"template-revision=(\d+)", first_line)
|
|
279
|
-
return int(match.group(1)) if match is not None else None
|
|
280
|
-
|
|
281
|
-
|
|
282
223
|
def _vbs_literal(value: Path | str) -> str:
|
|
283
224
|
return '"' + str(value).replace('"', '""') + '"'
|
|
284
225
|
|
|
@@ -290,7 +231,7 @@ def _render_windows_launcher(wrapper_path: Path) -> str:
|
|
|
290
231
|
)
|
|
291
232
|
return _WINDOWS_LAUNCHER_TEMPLATE.render(
|
|
292
233
|
{
|
|
293
|
-
"managed_marker":
|
|
234
|
+
"managed_marker": MANAGED_MARKER,
|
|
294
235
|
"command": command,
|
|
295
236
|
}
|
|
296
237
|
)
|
|
@@ -303,7 +244,7 @@ def _render_windows_task(
|
|
|
303
244
|
rendered = _WINDOWS_TASK_TEMPLATE.render(
|
|
304
245
|
{
|
|
305
246
|
"user": context.user,
|
|
306
|
-
"managed_marker":
|
|
247
|
+
"managed_marker": MANAGED_MARKER,
|
|
307
248
|
"arguments": f'//B //Nologo "{launcher_path}"',
|
|
308
249
|
"data_dir": str(context.data_dir),
|
|
309
250
|
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"""Install a newer bcn release and hand this node over to it."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import asyncio
|
|
6
|
+
import os
|
|
7
|
+
import shutil
|
|
8
|
+
import subprocess
|
|
9
|
+
from collections.abc import Awaitable, Callable, Mapping
|
|
10
|
+
|
|
11
|
+
from packaging.version import InvalidVersion, Version
|
|
12
|
+
|
|
13
|
+
from .. import __distribution__
|
|
14
|
+
|
|
15
|
+
# uv writes UTF-8 whatever the console is set to, so a node in a non-UTF-8
|
|
16
|
+
# locale would otherwise report its diagnostics as mojibake
|
|
17
|
+
_UV_OUTPUT_ENCODING = "utf-8"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class UpgradeError(RuntimeError):
|
|
21
|
+
"""Raised when the node cannot install or hand over to the new release."""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class UpgradeUnavailable(UpgradeError):
|
|
25
|
+
"""Raised when no newer release has been announced."""
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _uv_executable() -> str:
|
|
29
|
+
executable = shutil.which("uv")
|
|
30
|
+
if executable is None:
|
|
31
|
+
# a node started by a service manager inherits that manager's PATH,
|
|
32
|
+
# which often does not include wherever uv was installed, so this says
|
|
33
|
+
# nothing about whether uv exists on the machine
|
|
34
|
+
raise UpgradeError(
|
|
35
|
+
"uv is not on this node's PATH, so the release cannot be "
|
|
36
|
+
"installed; add the directory holding uv to the PATH the node "
|
|
37
|
+
"runs with, then try again"
|
|
38
|
+
)
|
|
39
|
+
return executable
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _run(
|
|
43
|
+
command: list[str],
|
|
44
|
+
*,
|
|
45
|
+
env: Mapping[str, str] | None = None,
|
|
46
|
+
encoding: str | None = None,
|
|
47
|
+
) -> None:
|
|
48
|
+
# no deadline: uv already gives up on a request that never answers, and a
|
|
49
|
+
# second limit would only cut short an install that was merely slow
|
|
50
|
+
result = subprocess.run(
|
|
51
|
+
command,
|
|
52
|
+
capture_output=True,
|
|
53
|
+
check=False,
|
|
54
|
+
text=True,
|
|
55
|
+
encoding=encoding,
|
|
56
|
+
errors="replace",
|
|
57
|
+
env=None if env is None else {**os.environ, **env},
|
|
58
|
+
)
|
|
59
|
+
if result.returncode != 0:
|
|
60
|
+
detail = (result.stderr or result.stdout).strip()
|
|
61
|
+
suffix = f": {detail}" if detail else ""
|
|
62
|
+
raise UpgradeError(
|
|
63
|
+
f"upgrade command failed ({result.returncode}): {' '.join(command)}{suffix}"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _install(version: str) -> None:
|
|
68
|
+
_run(
|
|
69
|
+
[
|
|
70
|
+
_uv_executable(),
|
|
71
|
+
"tool",
|
|
72
|
+
"install",
|
|
73
|
+
"--force",
|
|
74
|
+
# the release was announced by PyPI's own API minutes ago, while uv
|
|
75
|
+
# resolves against a separately cached index that can still predate
|
|
76
|
+
# it and would then report the version as one that does not exist
|
|
77
|
+
"--refresh-package",
|
|
78
|
+
__distribution__,
|
|
79
|
+
f"{__distribution__}=={version}",
|
|
80
|
+
],
|
|
81
|
+
encoding=_UV_OUTPUT_ENCODING,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class UpgradeService:
|
|
86
|
+
"""Install the release the user agreed to, then hand the node over to it."""
|
|
87
|
+
|
|
88
|
+
def __init__(
|
|
89
|
+
self,
|
|
90
|
+
*,
|
|
91
|
+
available_version: Callable[[], str | None],
|
|
92
|
+
installed_version: str,
|
|
93
|
+
request_restart: Callable[[], None],
|
|
94
|
+
) -> None:
|
|
95
|
+
self._available_version = available_version
|
|
96
|
+
self._installed_version = installed_version
|
|
97
|
+
self._request_restart = request_restart
|
|
98
|
+
self._lock = asyncio.Lock()
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def installed_version(self) -> str:
|
|
102
|
+
return self._installed_version
|
|
103
|
+
|
|
104
|
+
def available_version(self) -> str | None:
|
|
105
|
+
return self._available_version()
|
|
106
|
+
|
|
107
|
+
async def upgrade(
|
|
108
|
+
self,
|
|
109
|
+
*,
|
|
110
|
+
wake_after: Callable[[str], Awaitable[str | None]],
|
|
111
|
+
) -> tuple[str, str | None]:
|
|
112
|
+
"""Install the release on offer and hand the node over to it.
|
|
113
|
+
|
|
114
|
+
The whole thing is one transaction. Two sessions can accept an offer at
|
|
115
|
+
the same time, and by then the offers need not even name the same
|
|
116
|
+
release; letting the second in before the first has asked to restart
|
|
117
|
+
would boot a version nobody was told about, and an install cannot be
|
|
118
|
+
called back once its thread is running.
|
|
119
|
+
|
|
120
|
+
``wake_after`` records how the Agent is prompted to check the node over
|
|
121
|
+
afterwards, and returns the reminder it left, or None if it could not
|
|
122
|
+
leave one.
|
|
123
|
+
"""
|
|
124
|
+
|
|
125
|
+
async with self._lock:
|
|
126
|
+
version = self.available_version()
|
|
127
|
+
if version is None:
|
|
128
|
+
raise UpgradeUnavailable(
|
|
129
|
+
"No newer release has been announced for this node."
|
|
130
|
+
)
|
|
131
|
+
try:
|
|
132
|
+
Version(version)
|
|
133
|
+
except InvalidVersion as error:
|
|
134
|
+
raise UpgradeError(f"{version!r} is not a release version") from error
|
|
135
|
+
await self.install(version)
|
|
136
|
+
reminder_id = await wake_after(version)
|
|
137
|
+
# the node cannot restart itself from the inside: on Windows the
|
|
138
|
+
# stop it would ask for kills the process tree it is asking from.
|
|
139
|
+
# Exiting is the one thing it can do that its host watches for.
|
|
140
|
+
self._request_restart()
|
|
141
|
+
return version, reminder_id
|
|
142
|
+
|
|
143
|
+
async def install(self, version: str) -> None:
|
|
144
|
+
await asyncio.to_thread(_install, version)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
__all__ = [
|
|
148
|
+
"UpgradeError",
|
|
149
|
+
"UpgradeService",
|
|
150
|
+
"UpgradeUnavailable",
|
|
151
|
+
]
|
|
@@ -24,6 +24,10 @@ from .app.transport import LocalCommandClient
|
|
|
24
24
|
from .core.reminder import format_utc_timestamp
|
|
25
25
|
from .rendering import TextTemplate
|
|
26
26
|
|
|
27
|
+
# Windows has nothing that brings the node back after an upgrade exits it, so
|
|
28
|
+
# there the node offers no upgrade and the commands would only ever be refused
|
|
29
|
+
_NODE_COMMANDS_HIDDEN = os.name == "nt"
|
|
30
|
+
|
|
27
31
|
|
|
28
32
|
class BccCommandError(RuntimeError):
|
|
29
33
|
def __init__(
|
|
@@ -47,8 +51,8 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
47
51
|
description=(
|
|
48
52
|
"Session-scoped collaboration commands for a Bazaar Compute Node. "
|
|
49
53
|
"Use these commands from the current agent session to inspect messages, "
|
|
50
|
-
"send replies, manage thread attention, schedule "
|
|
51
|
-
"persistent reminders
|
|
54
|
+
"send replies, manage thread attention, and schedule "
|
|
55
|
+
"persistent reminders."
|
|
52
56
|
),
|
|
53
57
|
epilog=(
|
|
54
58
|
"Run `bcc <resource> --help` or "
|
|
@@ -58,7 +62,11 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
58
62
|
subparsers = parser.add_subparsers(
|
|
59
63
|
dest="resource",
|
|
60
64
|
required=True,
|
|
61
|
-
metavar=
|
|
65
|
+
metavar=(
|
|
66
|
+
"{message,inbox,thread,reminder}"
|
|
67
|
+
if _NODE_COMMANDS_HIDDEN
|
|
68
|
+
else "{message,inbox,thread,reminder,node}"
|
|
69
|
+
),
|
|
62
70
|
title="resources",
|
|
63
71
|
)
|
|
64
72
|
|
|
@@ -330,6 +338,9 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
330
338
|
help="Reminder id (full uuid)",
|
|
331
339
|
)
|
|
332
340
|
|
|
341
|
+
if _NODE_COMMANDS_HIDDEN:
|
|
342
|
+
return parser
|
|
343
|
+
|
|
333
344
|
node_parser = subparsers.add_parser(
|
|
334
345
|
"node",
|
|
335
346
|
help="Operations on the node this session runs on",
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import logging
|
|
5
|
+
import os
|
|
5
6
|
from collections.abc import Awaitable, Callable, Sequence
|
|
6
7
|
from dataclasses import dataclass, replace
|
|
7
8
|
|
|
@@ -144,6 +145,9 @@ def inbox_notice(
|
|
|
144
145
|
"rows": [row[2] for row in rows],
|
|
145
146
|
"upgrade_version": upgrade_version,
|
|
146
147
|
"installed_version": installed_version,
|
|
148
|
+
# Windows has nothing that would bring the node back after an
|
|
149
|
+
# upgrade exits it, so there the user runs the commands themselves
|
|
150
|
+
"manual_upgrade": os.name == "nt",
|
|
147
151
|
"closing_bracket_on_own_line": closing_bracket_on_own_line,
|
|
148
152
|
}
|
|
149
153
|
)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[inbox notice:
|
|
2
2
|
Inbox update: {{ total_unread_count }} unread {{ "message" if total_unread_count == 1 else "messages" }} total; {{ rows | length }} changed {{ "target" if rows | length == 1 else "targets" }}{% for row in rows %}
|
|
3
3
|
{{ row.target }} pending: {{ row.pending_count }} {{ "message" if row.pending_count == 1 else "messages" }} · first msg={{ row.first_id }}{% if row.latest_sender is not none %} · latest sender @{{ row.latest_sender }}{% endif %} · latest msg={{ row.latest_id }}{% for flag in row.flags %} · {{ "you were mentioned" if flag == "mention" else flag }}{% endfor %}{% endfor %}{% if upgrade_version is not none and installed_version is not none %}
|
|
4
|
-
Upgrade available: {{ distribution }} {{ upgrade_version }} (installed {{ installed_version }}). Mention it in passing when you reply and offer to upgrade
|
|
4
|
+
Upgrade available: {{ distribution }} {{ upgrade_version }} (installed {{ installed_version }}). Mention it in passing when you reply and offer to upgrade. {% if manual_upgrade %}Upgrading is theirs to run on this platform: if they want it, give them these three commands in this order, and say the second one needs the node stopped: `bcn system-service stop`, `uv tool install --force --refresh-package {{ distribution }} {{ distribution }}=={{ upgrade_version }}`, `bcn system-service start`.{% else %}If the user agrees, run `bcc node upgrade`.{% endif %} If they do not want it, just carry on.{% endif %}{% if closing_bracket_on_own_line %}
|
|
5
5
|
{% endif %}]{{ "" -}}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# {{ managed_marker }}
|
|
2
|
+
$ErrorActionPreference = 'Stop'
|
|
3
|
+
|
|
4
|
+
$executable = {{ executable }}
|
|
5
|
+
$configPath = {{ config_path }}
|
|
6
|
+
$environmentScript = {{ environment_script }}
|
|
7
|
+
$logPath = {{ log_path }}
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
Add-Type -TypeDefinition @'
|
|
11
|
+
using System;
|
|
12
|
+
using System.Diagnostics;
|
|
13
|
+
using System.IO;
|
|
14
|
+
using System.Threading.Tasks;
|
|
15
|
+
|
|
16
|
+
public static class BcnNoWindowProcess
|
|
17
|
+
{
|
|
18
|
+
public static int Run(string executable, string configPath, string logPath)
|
|
19
|
+
{
|
|
20
|
+
ProcessStartInfo startInfo = new ProcessStartInfo();
|
|
21
|
+
startInfo.FileName = executable;
|
|
22
|
+
startInfo.Arguments = "run --config \"" + configPath + "\"";
|
|
23
|
+
startInfo.UseShellExecute = false;
|
|
24
|
+
startInfo.CreateNoWindow = true;
|
|
25
|
+
startInfo.RedirectStandardInput = true;
|
|
26
|
+
startInfo.RedirectStandardOutput = true;
|
|
27
|
+
startInfo.RedirectStandardError = true;
|
|
28
|
+
|
|
29
|
+
using (Process process = new Process())
|
|
30
|
+
using (FileStream logStream = new FileStream(
|
|
31
|
+
logPath,
|
|
32
|
+
FileMode.Append,
|
|
33
|
+
FileAccess.Write,
|
|
34
|
+
FileShare.ReadWrite | FileShare.Delete
|
|
35
|
+
))
|
|
36
|
+
{
|
|
37
|
+
process.StartInfo = startInfo;
|
|
38
|
+
process.Start();
|
|
39
|
+
process.StandardInput.Close();
|
|
40
|
+
|
|
41
|
+
object writeLock = new object();
|
|
42
|
+
Task stdoutTask = CopyToLogAsync(
|
|
43
|
+
process.StandardOutput.BaseStream,
|
|
44
|
+
logStream,
|
|
45
|
+
writeLock
|
|
46
|
+
);
|
|
47
|
+
Task stderrTask = CopyToLogAsync(
|
|
48
|
+
process.StandardError.BaseStream,
|
|
49
|
+
logStream,
|
|
50
|
+
writeLock
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
process.WaitForExit();
|
|
54
|
+
Task.WaitAll(stdoutTask, stderrTask);
|
|
55
|
+
return process.ExitCode;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private static async Task CopyToLogAsync(
|
|
60
|
+
Stream source,
|
|
61
|
+
Stream destination,
|
|
62
|
+
object writeLock
|
|
63
|
+
)
|
|
64
|
+
{
|
|
65
|
+
byte[] buffer = new byte[8192];
|
|
66
|
+
int bytesRead;
|
|
67
|
+
while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length)) > 0)
|
|
68
|
+
{
|
|
69
|
+
lock (writeLock)
|
|
70
|
+
{
|
|
71
|
+
destination.Write(buffer, 0, bytesRead);
|
|
72
|
+
destination.Flush();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
'@
|
|
78
|
+
} catch {
|
|
79
|
+
$_ | Out-String | Add-Content -LiteralPath $logPath -Encoding utf8
|
|
80
|
+
exit 1
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if ($environmentScript -and (Test-Path -LiteralPath $environmentScript)) {
|
|
84
|
+
try {
|
|
85
|
+
. $environmentScript
|
|
86
|
+
} catch {
|
|
87
|
+
$_ | Out-String | Add-Content -LiteralPath $logPath -Encoding utf8
|
|
88
|
+
exit 1
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
$exitCode = [BcnNoWindowProcess]::Run($executable, $configPath, $logPath)
|
|
94
|
+
} catch {
|
|
95
|
+
$_ | Out-String | Add-Content -LiteralPath $logPath -Encoding utf8
|
|
96
|
+
exit 1
|
|
97
|
+
}
|
|
98
|
+
exit $exitCode
|