-
Type:
Bug
-
Status: Closed
-
Resolution: Deferred
-
Affects Version/s: 6.23.25, 7.25.7
-
Fix Version/s: None
-
Component/s: Docker, User Plugins
-
Labels:None
-
Location:External
Problem description:
When pushing an image to a Docker repository and one of the layers already exists in another repository we have read access to, Artifactory copies that layer and returns "Layer already exists" to the Docker client. If the layer in Artifactory has a restricted property set on it, for example, a property that only Admin users can delete, and a deployer is not an Admin user, the docker push will fail.
Steps to reproduce:
- Create two docker repositories, say docker1 and docker2
- Deploy sample user plugin (attached below) that allows only Admin users to delete a property called only.admin.can.delete
- $docker push artifactory.local/docker1/nginx:latest
- Recursively set the property on the docker1 repository: only.admin.can.delete:1
- Create/use a user that has Read permissions for docker1 and Deploy permissions for docker2 repositories
- $docker push artifactory.local/docker2/nginx:latest
What is the observed behavior?
Docker push fails with the following error:
$docker push artifactory.local/docker2/nginx
Using default tag: latest
The push refers to repository [artifactory.local/docker2/nginx]
fac15b2caa0c: Layer already exists
f8bf5746ac5a: Layer already exists
d11eedadbd34: Layer already exists
797e583d8c50: Layer already exists
bf9ce92e8516: Layer already exists
d000633a5681: Layer already exists
manifest invalid: manifest invalid
artifactory-service.log shows:
2021-09-20T08:29:32.655Z [jfrt ] [INFO ] [6a888840560aef30] [h.DockerManifestPutHandler:103] [http-nio-8081-exec-1] - Deploying docker manifest for image 'nginx' and tag 'latest' in repo 'docker2' 2021-09-20T08:29:32.673Z [jfrt ] [ERROR] [6a888840560aef30] [.s.StorageInterceptorsImpl:165] [http-nio-8081-exec-1] - Property delete rejected: Not authorized to delete this property.: Not authorized to delete this property. 2021-09-20T08:29:32.673Z [jfrt ] [WARN ] [6a888840560aef30] [o.a.s.f.l.SessionLockEntry:134] [http-nio-8081-exec-1] - Mutable item 'docker2:nginx/latest/sha256__ad4c705f24d392b982b2f0747704b1c5162e45674294d5640cca7076eba2865d' has local modifications that will be discarded. 2021-09-20T08:29:32.674Z [jfrt ] [WARN ] [6a888840560aef30] [o.a.s.f.l.SessionLockEntry:134] [http-nio-8081-exec-1] - Mutable item 'docker2:nginx' has local modifications that will be discarded. 2021-09-20T08:29:32.675Z [jfrt ] [WARN ] [6a888840560aef30] [o.a.s.f.l.SessionLockEntry:134] [http-nio-8081-exec-1] - Mutable item 'docker2:nginx/latest' has local modifications that will be discarded. 2021-09-20T08:29:32.675Z [jfrt ] [ERROR] [6a888840560aef30] [r.DockerPackageWorkContext:414] [http-nio-8081-exec-1] - Error copying blob docker1/nginx/latest/sha256__ad4c705f24d392b982b2f0747704b1c5162e45674294d5640cca7076eba2865d to path docker2/nginx/latest/sha256__ad4c705f24d392b982b2f0747704b1c5162e45674294d5640cca7076eba2865d : Not authorized to delete this property.
What is the expected behavior?
$docker push should succeed
Sample user plugin:
import groovy.json.JsonBuilder import org.artifactory.repo.RepoPathFactory import org.artifactory.exception.CancelException storage { /** * Handle before property delete events. * * Closure parameters: * item (org.artifactory.fs.ItemInfo) - the item from which the property is being deleted. * name (java.lang.String) - the name of the property being deleted. */ beforePropertyDelete { item, name -> if (name == "only.admin.can.delete" && !security.isAdmin()) { throw new CancelException("Not authorized to delete this property.", 401) } } }
Workaround:
1) Do not set restricted properties on Docker layers
2) Modify the user-plugin to skip validation on Docker layers (sha256__* files)