Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Publish API returns 202 Accepted even though GPG Signing fails #1268

Open
mkasimd opened this issue Apr 11, 2024 · 5 comments
Open

Publish API returns 202 Accepted even though GPG Signing fails #1268

mkasimd opened this issue Apr 11, 2024 · 5 comments
Assignees

Comments

@mkasimd
Copy link

mkasimd commented Apr 11, 2024

When calling the Publish API without the Signing Options even though aptly uses an encrypted GPG key, signing RELEASE file and publishing obviously fails, but the API returns 202 Accepted

Detailed Description

When using a GPG key that was generated with a passphrase, calling the Publish API without Signing Options unexpectedly return 202 Accepted instead of 4xx:

$ curl -X POST -H 'Content-Type: application/json' --data '{"SourceKind": "local", "Sources": [{"Name": "test-repo"}], "Architectures": ["i386", "amd64"], "Distribution": "bookworm"}' http://localhost:8080/api/publish/:. -v
* Connected to localhost (127.0.0.1) port 8080
> POST /api/publish/:. HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.6.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 123
> 
< HTTP/1.1 202 Accepted
< Content-Type: application/json; charset=utf-8
< Date: Thu, 11 Apr 2024 14:07:59 GMT
< Content-Length: 52
< 
* Connection #0 to host localhost left intact
{"Name":"Publish local: test-repo","ID":5,"State":0}

Meanwhile the logs on the server side look like this:

[GIN] 2024/04/11 - 13:28:12 | 202 |   11.431911ms |      172.17.0.1 | POST     "/api/publish/:."
Signing file 'Release' with gpg, please enter your passphrase when prompted:
gpg: signing failed: Inappropriate ioctl for device
gpg: signing failed: Inappropriate ioctl for device

and a simple GET request to list published repos shows that the repo was not published.

Context

When utilizing the REST API to build own applications around it, it's common to assume a 2xx response code usually means that the API call was fine. There is no clear error message visible to the caller. Instead, it's only visible within the server only. It's best practice to return a status code indicating an issue.

Possible Implementation

Modify returned HTTP status code to e.g. 400 Bad Request

Your Environment

Docker with Dockerfile (excerpt):

FROM debian:bookworm

RUN apt-get update && \
    apt-get install -y\
      ca-certificates \
      gnupg2 curl procps \
      graphviz && \
    curl -fSSL https://www.aptly.info/pubkey.txt | gpg --dearmor -o /usr/share/keyrings/aptly.gpg && \
    echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/aptly.gpg] http://repo.aptly.info/ squeeze main" | tee /etc/apt/sources.list.d/aptly.list && \ 
    apt-get update && apt-get install -y aptly
$ curl http://localhost:8080/api/version                                                                                                                                 ✔ 
{"Version":"1.5.0+ds1-1+b4"}
@neolynx neolynx self-assigned this Apr 11, 2024
@neolynx
Copy link
Member

neolynx commented Jun 15, 2024

this might be fixed with #1271

are you using async mode for the API calls (_async=true) ?

could you check with latest ?

deb http://repo.aptly.info/nightly-DIST DIST main

Where DIST needs to be changed to the distribution: buster / bullseye / bookworm (Debian) or focal / jammy (Ubuntu).

@mkasimd
Copy link
Author

mkasimd commented Jul 15, 2024

Sorry for late reply. Just checked it, but doesn't seem to have fixed it. I'll dump some details below for context in hopes that it helps:

Details

aptly version

$ cat /etc/apt/sources.list.d/aptly.list
deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/aptly.gpg] http://repo.aptly.info/nightly-bookworm bookworm main

$ aptly version
aptly version: 1.5.0+ds1-1+b4

aptly publish

$ curl -X POST -H 'Content-Type: application/json' --data '{"SourceKind": "local", "Sources": [{"Name": "test-repo"}], "Architectures": ["i386", "amd64"], "Distribution": "bookworm"}' http://localhost:8080/api/publish/:. -v

* Connected to localhost (127.0.0.1) port 8080
> POST /api/publish/:. HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.8.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 123
> 
* upload completely sent off: 123 bytes
< HTTP/1.1 202 Accepted
< Content-Type: application/json; charset=utf-8
< Date: Mon, 15 Jul 2024 12:16:54 GMT
< Content-Length: 52
< 
* Connection #0 to host localhost left intact
{"Name":"Publish local: test-repo","ID":4,"State":0}

aptly logs

[GIN] 2024/07/15 - 12:16:54 | 202 |    7.281485ms |      172.17.0.1 | POST     "/api/publish/:."
2024/07/15 12:16:54 Executing task asynchronously
Signing file 'Release' with gpg, please enter your passphrase when prompted:
gpg: signing failed: No such file or directory
gpg: signing failed: No such file or directory

@neolynx
Copy link
Member

neolynx commented Jul 15, 2024

Could you try adding the Signing parameters (Batch, GpgKey and PassphraseFile) ?
that usually works:

curl -X POST -H 'Content-Type: application/json' --data '{"SourceKind": "local", "Sources": [{"Name": "test-repo"}], "Architectures": ["i386", "amd64"], "Distribution": "bookworm", "Signing":{"Batch":true,"GpgKey":"signing@key", "PassphraseFile": "/path/to/gpg-passphrase-file"}}' http://localhost:8080/api/publish/:. -v

@mkasimd
Copy link
Author

mkasimd commented Jul 16, 2024

What I meant with this issue is: the HTTP 202 Accepted is kinda misleading. Is it possible to return a different status code (e.g. 400 Bad Request) if the request is faulty? That way, one can work on the returned status code to determine whether the action was successful or not.

As seen in issue #1266, it works with the signing options set just fine now. But the returned status code is kind of not helpful. I'd technically have to check the list of published repos to ensure whether it was successful or not.

In the best case, it'd be great to be able to distinguish between various errors using the HTTP status codes (missing Signing options, bad/wrong passphrase, etc.), but just being able to distinguish between "successful" and "didn't work" would be a great improvement as well

@neolynx
Copy link
Member

neolynx commented Aug 12, 2024

Thanks for the clarifications !

I tried to reproduce with latest CI build (from master):

$ curl -X POST -H 'Content-Type: application/json' --data '{"SourceKind": "local", "Sources": [{"Name": "copied"}], "Architectures": ["i386", "amd64"], "Distribution": "bookworm"}' http://localhost:3142/api/publish/pub-test -v
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 127.0.0.1:3142...
* Connected to localhost (127.0.0.1) port 3142 (#0)
> POST /api/publish/pub-test HTTP/1.1
> Host: localhost:3142
> User-Agent: curl/7.88.1
> Accept: */*
> Content-Type: application/json
> Content-Length: 120
> 
< HTTP/1.1 500 Internal Server Error
< Content-Type: application/json; charset=utf-8
< Date: Mon, 12 Aug 2024 10:51:12 GMT
< Content-Length: 74
< 
* Connection #0 to host localhost left intact
{"error":"unable to publish: unable to detached sign file: exit status 2"}

while the aptly logs show:

molior-aptly | 2024-08-12T10:52:13Z DBG Executing task synchronously
molior-aptly | Signing file 'Release' with gpg, please enter your passphrase when prompted:
molior-aptly | gpg: Sorry, we are in batchmode - can't get input
molior-aptly | [GIN] 2024/08/12 - 10:52:13 | 500 |  112.632145ms |      172.19.0.1 | POST     "/api/publish/pub-test"
molior-aptly | Error #01: unable to publish: unable to detached sign file: exit status 2

it returns a 500 Internal Server Error, which is not a good choice, but I could not reproduce the 202 you are seeing.

Could you maybe try again with latest aptly ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants
@neolynx @mkasimd and others