InRelease file: support Signed-By field

https://wiki.debian.org/DebianRepository/Format#Signed-By says:
> **Signed-By**
> An optional field containing a comma separated list of
> OpenPGP key fingerprints to be used for validating
> the next Release file. The fingerprints must consist
> only of hex digits and may not contain spaces.
> The fingerprint specifies either the key the Release file
> must be signed with or the key the signature key must be
> a subkey of. The later match can be disabled by appending
> an exclamation mark to the fingerprint.
>
> If the field is present, a client should only accept future updates
> to the repository that are signed with keys listed in the field.
> The field should be ignored if the Valid-Until field is not present
> or if it is expired.

For both the CLI tools and JSON, the field is taken as a string verbatim.

When specified, we must also provide `Valid-Until` field,
and i'm not sure there is an 'infinity' value for it,
so 100 years will have to do?

Fixes https://github.com/aptly-dev/aptly/issues/1497
This commit is contained in:
Roman Lebedev
2025-12-29 23:15:40 +03:00
parent 836d9f3b8b
commit a4cc9211d6
25 changed files with 569 additions and 5 deletions
+4
View File
@@ -14,6 +14,7 @@
"Origin": "LP-PPA-gladky-anton-gnuplot",
"Path": "./maverick",
"Prefix": ".",
"SignedBy": "",
"SkipContents": false,
"SourceKind": "snapshot",
"Sources": [
@@ -39,6 +40,7 @@
"Origin": "",
"Path": "ppa/smira/wheezy",
"Prefix": "ppa/smira",
"SignedBy": "",
"SkipContents": false,
"SourceKind": "snapshot",
"Sources": [
@@ -65,6 +67,7 @@
"Origin": "origin1",
"Path": "ppa/tr1/maverick",
"Prefix": "ppa/tr1",
"SignedBy": "",
"SkipContents": false,
"SourceKind": "snapshot",
"Sources": [
@@ -91,6 +94,7 @@
"Origin": "",
"Path": "ppa/tr2/maverick",
"Prefix": "ppa/tr2",
"SignedBy": "",
"SkipContents": false,
"SourceKind": "snapshot",
"Sources": [
+14
View File
@@ -0,0 +1,14 @@
Loading packages...
Generating metadata files and linking package files...
Finalizing metadata files...
Signing file 'Release' with gpg, please enter your passphrase when prompted:
Clearsigning file 'Release' with gpg, please enter your passphrase when prompted:
Local repo local-repo has been successfully published.
Please setup your webserver to serve directory '${HOME}/.aptly/public' with autoindexing.
Now you can add following line to apt sources:
deb http://your-server/ maverick contrib
deb-src http://your-server/ maverick contrib
Don't forget to add your GPG key to apt with apt-key.
You can also use `aptly serve` to publish your repositories over HTTP quickly.
@@ -0,0 +1,12 @@
Origin: . maverick
Label: label35
Suite: maverick
Codename: maverick
Signed-By: comma,separated,string
Architectures: i386
Components: contrib
Description: Generated by aptly
MD5Sum:
SHA1:
SHA256:
SHA512:
+1
View File
@@ -13,6 +13,7 @@
"Origin": "LP-PPA-gladky-anton-gnuplot",
"Path": "./maverick",
"Prefix": ".",
"SignedBy": "",
"SkipContents": false,
"SourceKind": "snapshot",
"Sources": [
+1
View File
@@ -13,6 +13,7 @@
"Origin": "LP-PPA-gladky-anton-gnuplot",
"Path": "ppa/smira/maverick",
"Prefix": "ppa/smira",
"SignedBy": "",
"SkipContents": false,
"SourceKind": "snapshot",
"Sources": [
@@ -0,0 +1,13 @@
Loading packages...
Generating metadata files and linking package files...
Finalizing metadata files...
Signing file 'Release' with gpg, please enter your passphrase when prompted:
Clearsigning file 'Release' with gpg, please enter your passphrase when prompted:
Snapshot snap43 has been successfully published.
Please setup your webserver to serve directory '/home/runner/.aptly/public' with autoindexing.
Now you can add following line to apt sources:
deb http://your-server/ maverick main
Don't forget to add your GPG key to apt with apt-key.
You can also use `aptly serve` to publish your repositories over HTTP quickly.
@@ -0,0 +1,12 @@
Origin: LP-PPA-gladky-anton-gnuplot
Label: . maverick
Suite: maverick
Codename: maverick
Signed-By: string,separated,by,commas
Architectures: amd64 i386
Components: main
Description: Generated by aptly
MD5Sum:
SHA1:
SHA256:
SHA512:
@@ -0,0 +1,9 @@
Loading packages...
Generating metadata files and linking package files...
Finalizing metadata files...
Signing file 'Release' with gpg, please enter your passphrase when prompted:
Clearsigning file 'Release' with gpg, please enter your passphrase when prompted:
Cleaning up published repository ./maverick...
Cleaning up component 'main'...
Published snapshot repository ./maverick (origin: LP-PPA-gladky-anton-gnuplot) [amd64, i386] publishes {main: [snap2]: Snapshot from mirror [gnuplot-maverick]: http://ppa.launchpad.net/gladky-anton/gnuplot/ubuntu/ maverick} has been successfully switched to new source.
@@ -0,0 +1,12 @@
Origin: LP-PPA-gladky-anton-gnuplot
Label: . maverick
Suite: maverick
Codename: maverick
Signed-By: a,string
Architectures: amd64 i386
Components: main
Description: Generated by aptly
MD5Sum:
SHA1:
SHA256:
SHA512:
@@ -0,0 +1,9 @@
Loading packages...
Generating metadata files and linking package files...
Finalizing metadata files...
Signing file 'Release' with gpg, please enter your passphrase when prompted:
Clearsigning file 'Release' with gpg, please enter your passphrase when prompted:
Cleaning up published repository ./maverick...
Cleaning up component 'main'...
Published local repository ./maverick [i386, source] publishes {main: [local-repo]} has been updated successfully.
@@ -0,0 +1,12 @@
Origin: . maverick
Label: . maverick
Suite: maverick
Codename: maverick
Signed-By: some,string
Architectures: i386
Components: main
Description: Generated by aptly
MD5Sum:
SHA1:
SHA256:
SHA512:
+20 -1
View File
@@ -6,7 +6,7 @@ from lib import BaseTest, ungzip_if_required
def strip_processor(output):
return "\n".join([l for l in output.split("\n") if not l.startswith(' ') and not l.startswith('Date:')])
return "\n".join([l for l in output.split("\n") if not l.startswith(' ') and not l.startswith('Date:') and not l.startswith('Valid-Until:')])
class PublishRepo1Test(BaseTest):
@@ -951,3 +951,22 @@ class PublishRepo34Test(BaseTest):
if 'main/dep11/README' not in pathsSeen:
raise Exception("README file not included in release file")
class PublishRepo35Test(BaseTest):
"""
publish repo: signed-by
"""
fixtureCmds = [
"aptly repo create local-repo",
"aptly repo add local-repo ${files}",
]
runCmd = "aptly publish repo -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick -component=contrib -label=label35 -signed-by=comma,separated,string local-repo"
gold_processor = BaseTest.expand_environ
def check(self):
super(PublishRepo35Test, self).check()
# verify contents except of sums
self.check_file_contents(
'public/dists/maverick/Release', 'release', match_prepare=strip_processor)
+21 -1
View File
@@ -6,7 +6,7 @@ from lib import BaseTest, ungzip_if_required
def strip_processor(output):
return "\n".join([l for l in output.split("\n") if not l.startswith(' ') and not l.startswith('Date:')])
return "\n".join([l for l in output.split("\n") if not l.startswith(' ') and not l.startswith('Date:') and not l.startswith('Valid-Until:')])
def sorted_processor(output):
@@ -1419,3 +1419,23 @@ class PublishSnapshot42Test(BaseTest):
'public/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb')
self.check_exists(
'public/pool/maverick/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb')
class PublishSnapshot43Test(BaseTest):
"""
publish snapshot: signed-by
"""
fixtureDB = True
fixturePool = True
fixtureCmds = [
"aptly snapshot create snap43 from mirror gnuplot-maverick",
]
sortOutput = True
runCmd = "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -signed-by=string,separated,by,commas snap43"
gold_processor = BaseTest.expand_environ
def check(self):
super(PublishSnapshot43Test, self).check()
self.check_file_contents(
'public/dists/maverick/Release', 'release', match_prepare=strip_processor)
+21 -1
View File
@@ -5,7 +5,7 @@ from lib import BaseTest
def strip_processor(output):
return "\n".join([l for l in output.split("\n") if not l.startswith(' ') and not l.startswith('Date:')])
return "\n".join([l for l in output.split("\n") if not l.startswith(' ') and not l.startswith('Date:') and not l.startswith('Valid-Until:')])
class PublishSwitch1Test(BaseTest):
@@ -603,3 +603,23 @@ class PublishSwitch16Test(BaseTest):
self.check_exists('public/dists/bookworm/main/binary-amd64/Packages.gz')
self.check_exists('public/pool/bookworm/main/g/gnuplot/gnuplot-x11_4.6.1-1~maverick2_amd64.deb')
class PublishSwitch17Test(BaseTest):
"""
publish switch: signed-by
"""
fixtureDB = True
fixturePool = True
fixtureCmds = [
"aptly snapshot create snap1 from mirror gnuplot-maverick",
"aptly snapshot create snap2 from mirror gnuplot-maverick",
"aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick snap1",
]
runCmd = "aptly publish switch -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -signed-by=a,string maverick snap2"
gold_processor = BaseTest.expand_environ
def check(self):
super(PublishSwitch17Test, self).check()
self.check_file_contents('public/dists/maverick/Release', 'release', match_prepare=strip_processor)
+20 -1
View File
@@ -5,7 +5,7 @@ from lib import BaseTest
def strip_processor(output):
return "\n".join([l for l in output.split("\n") if not l.startswith(' ') and not l.startswith('Date:')])
return "\n".join([l for l in output.split("\n") if not l.startswith(' ') and not l.startswith('Date:') and not l.startswith('Valid-Until:')])
class PublishUpdate1Test(BaseTest):
@@ -606,3 +606,22 @@ class PublishUpdate18Test(BaseTest):
components = sorted(components.split(' '))
if ['other-test', 'test'] != components:
raise Exception("value of 'Components' in release file is '%s' and does not match '%s'." % (' '.join(components), 'other-test test'))
class PublishUpdate19Test(BaseTest):
"""
publish update: signed-by
"""
fixtureCmds = [
"aptly repo create local-repo",
"aptly repo add local-repo ${files}/",
"aptly publish repo -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick local-repo",
"aptly repo remove local-repo pyspi"
]
runCmd = "aptly publish update -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -signed-by=some,string maverick"
gold_processor = BaseTest.expand_environ
def check(self):
super(PublishUpdate19Test, self).check()
self.check_file_contents('public/dists/maverick/Release', 'release', match_prepare=strip_processor)
+313
View File
@@ -51,6 +51,7 @@ class PublishAPITestRepo(APITest):
'ButAutomaticUpgrades': '',
'Path': prefix + '/' + 'wheezy',
'Prefix': prefix,
'SignedBy': '',
'SkipContents': False,
'MultiDist': False,
'SourceKind': 'local',
@@ -96,6 +97,7 @@ class PublishAPITestRepo(APITest):
'ButAutomaticUpgrades': '',
'Path': './' + distribution,
'Prefix': ".",
'SignedBy': '',
'SkipContents': False,
'MultiDist': False,
'SourceKind': 'local',
@@ -167,6 +169,7 @@ class PublishAPITestRepoMultiDist(APITest):
'ButAutomaticUpgrades': '',
'Path': prefix + '/' + 'bookworm',
'Prefix': prefix,
'SignedBy': '',
'SkipContents': False,
'MultiDist': True,
'SourceKind': 'local',
@@ -189,6 +192,62 @@ class PublishAPITestRepoMultiDist(APITest):
"public/" + prefix + "/pool/bookworm/main/b/boost-defaults/libboost-program-options-dev_1.49.0.1_i386.deb")
class PublishAPITestRepoSignedBy(APITest):
"""
POST /publish/:prefix (local repos), GET /publish
"""
fixtureGpg = True
def check(self):
repo_name = self.random_name()
self.check_equal(self.post(
"/api/repos", json={"Name": repo_name, "DefaultDistribution": "wheezy"}).status_code, 201)
d = self.random_name()
self.check_equal(self.upload("/api/files/" + d,
"libboost-program-options-dev_1.49.0.1_i386.deb", "pyspi_0.6.1-1.3.dsc",
"pyspi_0.6.1-1.3.diff.gz", "pyspi_0.6.1.orig.tar.gz",
"pyspi-0.6.1-1.3.stripped.dsc").status_code, 200)
task = self.post_task("/api/repos/" + repo_name + "/file/" + d)
self.check_task(task)
# publishing under prefix, default distribution
prefix = self.random_name()
task = self.post_task(
"/api/publish/" + prefix,
json={
"SourceKind": "local",
"Sources": [{"Name": repo_name}],
"Signing": DefaultSigningOptions,
"SignedBy": "just,a,string"
}
)
self.check_task(task)
repo_expected = {
'AcquireByHash': False,
'Architectures': ['i386', 'source'],
'Codename': '',
'Distribution': 'wheezy',
'Label': '',
'Origin': '',
'NotAutomatic': '',
'ButAutomaticUpgrades': '',
'Path': prefix + '/' + 'wheezy',
'Prefix': prefix,
'SignedBy': 'just,a,string',
'SkipContents': False,
'MultiDist': False,
'SourceKind': 'local',
'Sources': [{'Component': 'main', 'Name': repo_name}],
'Storage': '',
'Suite': ''}
all_repos = self.get("/api/publish")
self.check_equal(all_repos.status_code, 200)
self.check_in(repo_expected, all_repos.json())
class PublishSnapshotAPITest(APITest):
"""
POST /publish/:prefix (snapshots), GET /publish
@@ -244,6 +303,7 @@ class PublishSnapshotAPITest(APITest):
'ButAutomaticUpgrades': 'yes',
'Path': prefix + '/' + 'squeeze',
'Prefix': prefix,
'SignedBy': '',
'SkipContents': False,
'SourceKind': 'snapshot',
'Sources': [{'Component': 'main', 'Name': snapshot_name}],
@@ -265,6 +325,74 @@ class PublishSnapshotAPITest(APITest):
"public/" + prefix + "/pool/main/b/boost-defaults/libboost-program-options-dev_1.49.0.1_i386.deb")
class PublishSnapshotAPITestSignedBy(APITest):
"""
POST /publish/:prefix (snapshots), GET /publish
"""
def check(self):
repo_name = self.random_name()
snapshot_name = self.random_name()
self.check_equal(
self.post("/api/repos", json={"Name": repo_name}).status_code, 201)
d = self.random_name()
self.check_equal(self.upload("/api/files/" + d,
"libboost-program-options-dev_1.49.0.1_i386.deb").status_code, 200)
task = self.post_task("/api/repos/" + repo_name + "/file/" + d)
self.check_task(task)
task = self.post_task("/api/repos/" + repo_name + '/snapshots', json={'Name': snapshot_name})
self.check_task(task)
prefix = self.random_name()
task = self.post_task(
"/api/publish/" + prefix,
json={
"AcquireByHash": True,
"SourceKind": "snapshot",
"Sources": [{"Name": snapshot_name}],
"Signing": DefaultSigningOptions,
"Distribution": "squeeze",
"NotAutomatic": "yes",
"ButAutomaticUpgrades": "yes",
"Origin": "earth",
"Label": "fun",
"SignedBy": "just,a,string",
}
)
self.check_task(task)
_id = task.json()['ID']
resp = self.get("/api/tasks/" + str(_id) + "/detail")
self.check_equal(resp.json()['RemainingNumberOfPackages'], 0)
self.check_equal(resp.json()['TotalNumberOfPackages'], 1)
repo_expected = {
'AcquireByHash': True,
'Architectures': ['i386'],
'Codename': '',
'Distribution': 'squeeze',
'Label': 'fun',
'Origin': 'earth',
'MultiDist': False,
'NotAutomatic': 'yes',
'ButAutomaticUpgrades': 'yes',
'Path': prefix + '/' + 'squeeze',
'Prefix': prefix,
'SignedBy': 'just,a,string',
'SkipContents': False,
'SourceKind': 'snapshot',
'Sources': [{'Component': 'main', 'Name': snapshot_name}],
'Storage': '',
'Suite': '',
}
all_repos = self.get("/api/publish")
self.check_equal(all_repos.status_code, 200)
self.check_in(repo_expected, all_repos.json())
class PublishUpdateAPITestRepo(APITest):
"""
PUT /publish/:prefix/:distribution (local repos), DELETE /publish/:prefix/:distribution
@@ -332,6 +460,7 @@ class PublishUpdateAPITestRepo(APITest):
'ButAutomaticUpgrades': '',
'Path': prefix + '/' + 'wheezy',
'Prefix': prefix,
'SignedBy': '',
'SkipContents': False,
'MultiDist': False,
'SourceKind': 'local',
@@ -356,6 +485,86 @@ class PublishUpdateAPITestRepo(APITest):
self.check_not_exists("public/" + prefix + "dists/")
class PublishUpdateAPITestRepoSignedBy(APITest):
"""
PUT /publish/:prefix/:distribution (local repos), DELETE /publish/:prefix/:distribution
"""
fixtureGpg = True
def check(self):
repo_name = self.random_name()
self.check_equal(self.post(
"/api/repos", json={"Name": repo_name, "DefaultDistribution": "wheezy"}).status_code, 201)
d = self.random_name()
self.check_equal(
self.upload("/api/files/" + d,
"pyspi_0.6.1-1.3.dsc",
"pyspi_0.6.1-1.3.diff.gz", "pyspi_0.6.1.orig.tar.gz",
"pyspi-0.6.1-1.3.stripped.dsc").status_code, 200)
task = self.post_task("/api/repos/" + repo_name + "/file/" + d)
self.check_task(task)
prefix = self.random_name()
task = self.post_task(
"/api/publish/" + prefix,
json={
"Architectures": ["i386", "source"],
"SourceKind": "local",
"Sources": [{"Name": repo_name}],
"Signing": DefaultSigningOptions,
}
)
self.check_task(task)
self.check_not_exists(
"public/" + prefix + "/pool/main/b/boost-defaults/libboost-program-options-dev_1.49.0.1_i386.deb")
self.check_exists("public/" + prefix +
"/pool/main/p/pyspi/pyspi-0.6.1-1.3.stripped.dsc")
d = self.random_name()
self.check_equal(self.upload("/api/files/" + d,
"libboost-program-options-dev_1.49.0.1_i386.deb").status_code, 200)
task = self.post_task("/api/repos/" + repo_name + "/file/" + d)
self.check_task(task)
task = self.delete_task("/api/repos/" + repo_name + "/packages/",
json={"PackageRefs": ['Psource pyspi 0.6.1-1.4 f8f1daa806004e89']})
self.check_task(task)
# Update and specify SignedBy.
task = self.put_task(
"/api/publish/" + prefix + "/wheezy",
json={
"Signing": DefaultSigningOptions,
"SignedBy": "just,a,string",
}
)
self.check_task(task)
repo_expected = {
'AcquireByHash': False,
'Architectures': ['i386', 'source'],
'Codename': '',
'Distribution': 'wheezy',
'Label': '',
'Origin': '',
'NotAutomatic': '',
'ButAutomaticUpgrades': '',
'Path': prefix + '/' + 'wheezy',
'Prefix': prefix,
'SignedBy': 'just,a,string',
'SkipContents': False,
'MultiDist': False,
'SourceKind': 'local',
'Sources': [{'Component': 'main', 'Name': repo_name}],
'Storage': '',
'Suite': ''}
all_repos = self.get("/api/publish")
self.check_equal(all_repos.status_code, 200)
self.check_in(repo_expected, all_repos.json())
class PublishUpdateAPIMultiDist(APITest):
"""
Test MultiDist publishing to subdirectory
@@ -423,6 +632,7 @@ class PublishUpdateAPIMultiDist(APITest):
'ButAutomaticUpgrades': '',
'Path': prefix + '/' + 'bookworm',
'Prefix': prefix,
'SignedBy': '',
'SkipContents': False,
'MultiDist': True,
'SourceKind': 'local',
@@ -524,6 +734,7 @@ class PublishConcurrentUpdateAPITestRepo(APITest):
'ButAutomaticUpgrades': '',
'Path': prefix + '/' + 'wheezy',
'Prefix': prefix,
'SignedBy': '',
'SkipContents': False,
'MultiDist': False,
'SourceKind': 'local',
@@ -622,6 +833,7 @@ class PublishUpdateSkipCleanupAPITestRepo(APITest):
'ButAutomaticUpgrades': '',
'Path': prefix + '/' + 'wheezy',
'Prefix': prefix,
'SignedBy': '',
'SkipContents': False,
'MultiDist': False,
'SourceKind': 'local',
@@ -690,6 +902,7 @@ class PublishSwitchAPITestRepo(APITest):
'Origin': '',
'Path': prefix + '/' + 'wheezy',
'Prefix': prefix,
'SignedBy': '',
'SkipContents': False,
'MultiDist': False,
'SourceKind': 'snapshot',
@@ -738,6 +951,7 @@ class PublishSwitchAPITestRepo(APITest):
'ButAutomaticUpgrades': '',
'Path': prefix + '/' + 'wheezy',
'Prefix': prefix,
'SignedBy': '',
'SkipContents': True,
'MultiDist': False,
'SourceKind': 'snapshot',
@@ -759,6 +973,100 @@ class PublishSwitchAPITestRepo(APITest):
self.check_not_exists("public/" + prefix + "dists/")
class PublishSwitchAPITestRepoSignedBy(APITest):
"""
PUT /publish/:prefix/:distribution (snapshots), DELETE /publish/:prefix/:distribution
"""
fixtureGpg = True
def check(self):
repo_name = self.random_name()
self.check_equal(self.post(
"/api/repos", json={"Name": repo_name, "DefaultDistribution": "wheezy"}).status_code, 201)
d = self.random_name()
self.check_equal(
self.upload("/api/files/" + d,
"pyspi_0.6.1-1.3.dsc",
"pyspi_0.6.1-1.3.diff.gz", "pyspi_0.6.1.orig.tar.gz",
"pyspi-0.6.1-1.3.stripped.dsc").status_code, 200)
task = self.post_task("/api/repos/" + repo_name + "/file/" + d)
self.check_task(task)
snapshot1_name = self.random_name()
task = self.post_task("/api/repos/" + repo_name + '/snapshots', json={'Name': snapshot1_name})
self.check_task(task)
prefix = self.random_name()
task = self.post_task(
"/api/publish/" + prefix,
json={
"Architectures": ["i386", "source"],
"SourceKind": "snapshot",
"Sources": [{"Name": snapshot1_name}],
"Signing": DefaultSigningOptions,
})
self.check_task(task)
repo_expected = {
'AcquireByHash': False,
'Architectures': ['i386', 'source'],
'Codename': '',
'Distribution': 'wheezy',
'Label': '',
'NotAutomatic': '',
'ButAutomaticUpgrades': '',
'Origin': '',
'Path': prefix + '/' + 'wheezy',
'Prefix': prefix,
'SignedBy': '',
'SkipContents': False,
'MultiDist': False,
'SourceKind': 'snapshot',
'Sources': [{'Component': 'main', 'Name': snapshot1_name}],
'Storage': '',
'Suite': ''}
all_repos = self.get("/api/publish")
self.check_equal(all_repos.status_code, 200)
self.check_in(repo_expected, all_repos.json())
snapshot2_name = self.random_name()
task = self.post_task("/api/repos/" + repo_name + '/snapshots', json={'Name': snapshot2_name})
self.check_task(task)
task = self.put_task(
"/api/publish/" + prefix + "/wheezy",
json={
"Snapshots": [{"Component": "main", "Name": snapshot2_name}],
"Signing": DefaultSigningOptions,
"SkipContents": True,
"SignedBy": "just,a,string",
})
self.check_task(task)
repo_expected = {
'AcquireByHash': False,
'Architectures': ['i386', 'source'],
'Codename': '',
'Distribution': 'wheezy',
'Label': '',
'Origin': '',
'NotAutomatic': '',
'ButAutomaticUpgrades': '',
'Path': prefix + '/' + 'wheezy',
'Prefix': prefix,
'SignedBy': 'just,a,string',
'SkipContents': True,
'MultiDist': False,
'SourceKind': 'snapshot',
'Sources': [{'Component': 'main', 'Name': snapshot2_name}],
'Storage': '',
'Suite': ''}
all_repos = self.get("/api/publish")
self.check_equal(all_repos.status_code, 200)
self.check_in(repo_expected, all_repos.json())
class PublishSwitchAPISkipCleanupTestRepo(APITest):
"""
PUT /publish/:prefix/:distribution (snapshots), DELETE /publish/:prefix/:distribution
@@ -804,6 +1112,7 @@ class PublishSwitchAPISkipCleanupTestRepo(APITest):
'Origin': '',
'Path': prefix + '/' + 'wheezy',
'Prefix': prefix,
'SignedBy': '',
'SkipContents': False,
'MultiDist': False,
'SourceKind': 'snapshot',
@@ -842,6 +1151,7 @@ class PublishSwitchAPISkipCleanupTestRepo(APITest):
'Origin': '',
'Path': prefix + '/' + 'otherdist',
'Prefix': prefix,
'SignedBy': '',
'SkipContents': False,
'MultiDist': False,
'SourceKind': 'snapshot',
@@ -885,6 +1195,7 @@ class PublishSwitchAPISkipCleanupTestRepo(APITest):
'ButAutomaticUpgrades': '',
'Path': prefix + '/' + 'wheezy',
'Prefix': prefix,
'SignedBy': '',
'SkipContents': True,
'MultiDist': False,
'SourceKind': 'snapshot',
@@ -946,6 +1257,7 @@ class PublishShowAPITestRepo(APITest):
'Origin': '',
'Path': prefix + '/' + 'wheezy',
'Prefix': prefix,
'SignedBy': '',
'SkipContents': False,
'MultiDist': False,
'SourceKind': 'local',
@@ -1547,6 +1859,7 @@ class PublishUpdateSourcesAPITestRepo(APITest):
'ButAutomaticUpgrades': '',
'Path': prefix + '/' + 'wheezy',
'Prefix': prefix,
'SignedBy': '',
'SkipContents': True,
'MultiDist': False,
'SourceKind': 'local',