geenforce: HTTPS payload delivery (content-addressed blob store + endpoint)
Lets share-less (Intune/local-account) PCs pull installers the manifest references over HTTPS instead of SMB - the general capability the whole fleet migrates toward. New ManifestBlob registry (migration 0002) with bytes on disk at instance/geenforce/payloads/<sha256> (deduped by content); service.store_blob + blob_path; client-facing GET /api/geenforce/payload/<sha256> (geenforce.fetch token, ETag=hash, serves the blob store or an inline DB payload by hash). The serializer now emits PayloadSource/PayloadSha256/PayloadRef for http/inline entries only (smb entries round-trip unchanged - parity green). CLI 'flask geenforce add-payload <file>' registers a blob and prints its sha256. This is the shopdb half (B1); the PS client/engine fetch is B2.
This commit is contained in:
42
plugins/geenforce/migrations/versions/0002_manifest_blobs.py
Normal file
42
plugins/geenforce/migrations/versions/0002_manifest_blobs.py
Normal file
@@ -0,0 +1,42 @@
|
||||
"""geenforce: manifestblobs (content-addressed http payload store)
|
||||
|
||||
Big installers reach share-less (Intune/local-account) PCs by HTTPS download
|
||||
instead of SMB. The bytes live on disk at <instance>/geenforce/payloads/<sha>;
|
||||
this table is the registry (dedup by content hash). Idempotent guard.
|
||||
|
||||
Revision ID: geenforce0002blobs
|
||||
Revises: geenforce0001baseline
|
||||
Create Date: 2026-07-21
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
revision = 'geenforce0002blobs'
|
||||
down_revision = 'geenforce0001baseline'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
bind = op.get_bind()
|
||||
insp = sa.inspect(bind)
|
||||
if 'manifestblobs' in insp.get_table_names():
|
||||
return
|
||||
op.create_table(
|
||||
'manifestblobs',
|
||||
sa.Column('sha256', sa.String(length=64), nullable=False),
|
||||
sa.Column('filename', sa.String(length=255), nullable=False),
|
||||
sa.Column('contenttype', sa.String(length=128), nullable=True),
|
||||
sa.Column('sizebytes', sa.BigInteger(), nullable=False),
|
||||
sa.Column('createdat', sa.DateTime(), nullable=False),
|
||||
sa.PrimaryKeyConstraint('sha256'),
|
||||
)
|
||||
|
||||
|
||||
def downgrade():
|
||||
bind = op.get_bind()
|
||||
insp = sa.inspect(bind)
|
||||
if 'manifestblobs' in insp.get_table_names():
|
||||
op.drop_table('manifestblobs')
|
||||
Reference in New Issue
Block a user