devopshq / artifactory

dohq-artifactory: a Python client for Artifactory
https://devopshq.github.io/artifactory/
MIT License
269 stars 137 forks source link

path.stat() doesn't handle ArtifactoryPath() properly #417

Closed usinelogicielle closed 4 months ago

usinelogicielle commented 1 year ago

Hi,

Here is my environment:

python 3.8.4
dohq-artifactory 0.8.4

I want to get the stats of 2 files. I have a piece of code looking like this:

from artifactory import ArtifactoryPath

path1 = ArtifactoryPath(
    "https://artifactory.domain.com/artifactory/repo-docker-local/rdl/rd-image/0.2.0/manifest.json", apikey=token
)

path2 = ArtifactoryPath(
    "https://artifactory.domain.com/artifactory/repo-docker-local/rdl/artifactory.domain.com/repo-docker/rd/rd-image/0.2.0/manifest.json", apikey=token
)

# Get FileStat
stat1 = path1.stat()    # works
print(stat1)
stat2 = path2.stat()    # error
print(stat2)

As you can see the path in path2 is containing 2 times the artifactory host artifactory.domain.com. In the error message below I can see it tries to fetch the file but only using half the real path: it crops everything before the second artifactory.domain.com.

$ python tests.py --token=****

ArtifactoryFileStat(ctime='[...]', mtime='[...]', created_by='[...]', modified_by='[...]') # print(stat1), shorted for libility

Traceback (most recent call last):
  File "[...]/.env/lib/python3.8/site-packages/dohq_artifactory/exception.py", line 20, in raise_for_status
    response.raise_for_status()
  File "[...]/.env/lib/python3.8/site-packages/requests/models.py", line 1021, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://artifactory.domain.com/repo-docker/rd/rd-image/0.2.0/manifest.json

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "tests.py", line 35, in <module>
    stats2 = path2.stat()
  File "[...]/.env/lib/python3.8/site-packages/artifactory.py", line 1610, in stat
    return self._accessor.stat(pathobj=pathobj)
  File "[...]/.env/lib/python3.8/site-packages/artifactory.py", line 878, in stat
    jsn = self.get_stat_json(pathobj)
  File "[...]/.env/lib/python3.8/site-packages/artifactory.py", line 869, in get_stat_json
    raise_for_status(response)
  File "[...]/.env/lib/python3.8/site-packages/dohq_artifactory/exception.py", line 28, in raise_for_status
    raise ArtifactoryException(str(exception)) from exception
dohq_artifactory.exception.ArtifactoryException: 404 Client Error: Not Found for url: https://artifactory.domain.com/repo-docker/rd/rd-image/0.2.0/manifest.json

I cannot change the files names. It is not in my perimeter.

To identify where the problem comes from I tried the same thing but using JFrog Web API and it works:

$ curl -u user:passwd https://artifactory.domain.com/artifactory/api/storage/repo-docker-local/rdl/artifactory.domain.com/repo-docker/rdl/rd-image/0.2.0 -v
* About to connect() to artifactory.domain.com port <port> (#0)
*   Trying <ip>...
* Connected to artifactory.domain.com (<ip>) port <port> (#0)
* [...]
> GET /artifactory/api/storage/repo-docker-local/rdl/artifactory.domain.com/repo-docker/rdl/rd-image/0.2.0 HTTP/1.1
> Authorization: Basic xxxx
> User-Agent: <user_agent>
> Host: artifactory.domain.com
> Accept: */*
>
< HTTP/1.1 200
< Date: Wed, 17 May 2023 11:45:28 GMT
< Content-Type: application/vnd.org.jfrog.artifactory.storage.FolderInfo+json
< Transfer-Encoding: chunked
< Connection: keep-alive
< X-JFrog-Version: <jfrog_version>
< X-Artifactory-Id: <artifactory_id>
< X-Artifactory-Node-Id: <artifactory_node_id>
< Cache-Control: no-store
< Set-Cookie: <cookie>
<
{
  "repo" : "repo-docker-local",
  "path" : "/rdl/artifactory.domain.com/repo-docker/rdl/rd-image/0.2.0",
  "created" : "<created>",
  "createdBy" : "<createdBy>",
  "lastModified" : "<lastModified>",
  "modifiedBy" : "<modifiedBy>",
  "lastUpdated" : "<lastUpdated>",
  "children" : [{
    "uri" : "/manifest.json",
    "folder" : false,
    [...]
  }],
  "uri" : "https://artifactory.domain.com:<port>/artifactory/api/storage/repo-docker-local/rdl/artifactory.domain.com/repo-docker/rdl/rd-image/0.2.0"
}
* Connection #0 to host artifactory.domain.com left intact

For me the problem is from how the stat() method parses an ArtifactoryPath.

Do you have any solutions ?

264768502 commented 12 months ago

issue caused by https://github.com/devopshq/artifactory/blob/c0531a52f579703b3f0a397deed7987e0ad126d4/artifactory.py#L401 change url.rpartition to url.partition, issue can be fixed

allburov commented 12 months ago

Hi there, please feel free to create a PR with changes that can fix the issue!