mirror of
https://github.com/containers/skopeo.git
synced 2025-04-27 11:01:18 +00:00
Card container_security_113 - Delete image support
Add support to mark images for deletion from repository Requires: * V2 API and schema * registry configured to allow deletes * run registry garbage collection to free up disk space Signed-off-by: Jhon Honce <jhonce@redhat.com>
This commit is contained in:
parent
0ff261802b
commit
f3efa063e3
27
cmd/skopeo/delete.go
Normal file
27
cmd/skopeo/delete.go
Normal file
@ -0,0 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/codegangsta/cli"
|
||||
)
|
||||
|
||||
func deleteHandler(context *cli.Context) {
|
||||
if len(context.Args()) != 1 {
|
||||
logrus.Fatal("Usage: delete imageReference")
|
||||
}
|
||||
|
||||
image, err := parseImageSource(context, context.Args()[0])
|
||||
if err != nil {
|
||||
logrus.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if err := image.Delete(); err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
var deleteCmd = cli.Command{
|
||||
Name: "delete",
|
||||
Usage: "Delete given image",
|
||||
Action: deleteHandler,
|
||||
}
|
@ -63,6 +63,7 @@ func main() {
|
||||
copyCmd,
|
||||
inspectCmd,
|
||||
layersCmd,
|
||||
deleteCmd,
|
||||
standaloneSignCmd,
|
||||
standaloneVerifyCmd,
|
||||
}
|
||||
|
@ -111,3 +111,7 @@ func (s *dirImageSource) GetSignatures() ([][]byte, error) {
|
||||
}
|
||||
return signatures, nil
|
||||
}
|
||||
|
||||
func (s *dirImageSource) Delete() error {
|
||||
return fmt.Errorf("directory#dirImageSource.Delete() not implmented")
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/projectatomic/skopeo/docker/utils"
|
||||
"github.com/projectatomic/skopeo/reference"
|
||||
"github.com/projectatomic/skopeo/types"
|
||||
)
|
||||
@ -94,3 +95,51 @@ func (s *dockerImageSource) GetLayer(digest string) (io.ReadCloser, error) {
|
||||
func (s *dockerImageSource) GetSignatures() ([][]byte, error) {
|
||||
return [][]byte{}, nil
|
||||
}
|
||||
|
||||
func (s *dockerImageSource) Delete() error {
|
||||
var body []byte
|
||||
|
||||
// When retrieving the digest from a registry >= 2.3 use the following header:
|
||||
// "Accept": "application/vnd.docker.distribution.manifest.v2+json"
|
||||
headers := make(map[string][]string)
|
||||
headers["Accept"] = []string{utils.DockerV2Schema2MIMEType}
|
||||
|
||||
getURL := fmt.Sprintf(manifestURL, s.ref.RemoteName(), s.tag)
|
||||
get, err := s.c.makeRequest("GET", getURL, headers, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer get.Body.Close()
|
||||
body, err = ioutil.ReadAll(get.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch get.StatusCode {
|
||||
case http.StatusOK:
|
||||
case http.StatusNotFound:
|
||||
return fmt.Errorf("Unable to delete %v. Image may not exist or is not stored with a v2 Schema in a v2 registry.", s.ref)
|
||||
default:
|
||||
return fmt.Errorf("Failed to delete %v: %v (%v)", s.ref, body, get.Status)
|
||||
}
|
||||
|
||||
digest := get.Header.Get("Docker-Content-Digest")
|
||||
deleteURL := fmt.Sprintf(manifestURL, s.ref.RemoteName(), digest)
|
||||
|
||||
// When retrieving the digest from a registry >= 2.3 use the following header:
|
||||
// "Accept": "application/vnd.docker.distribution.manifest.v2+json"
|
||||
delete, err := s.c.makeRequest("DELETE", deleteURL, headers, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer delete.Body.Close()
|
||||
|
||||
body, err = ioutil.ReadAll(delete.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if delete.StatusCode != http.StatusAccepted {
|
||||
return fmt.Errorf("Failed to delete %v: %v (%v)", deleteURL, body, delete.Status)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ skopeo \(em Inspect Docker images and repositories on registries
|
||||
.SH SYNOPSIS
|
||||
\fBskopeo copy\fR [\fB--sign-by=\fRkey-ID] source-location destination-location
|
||||
.PP
|
||||
\fBskopeo delete\fR source-location
|
||||
.PP
|
||||
\fBskopeo inspect\fR image-name [\fB--raw\fR]
|
||||
.PP
|
||||
\fBskopeo layers\fR image-name
|
||||
@ -54,12 +56,22 @@ Copy an image (manifest, filesystem layers, signatures) from one location to ano
|
||||
.B source-location
|
||||
and
|
||||
.B destination-location
|
||||
can be \fBdocker://\fRdocker-reference, \fBdir:\fRlocal-path, or \fBatomic:\fRimagestream-name\fB:\fRtag .
|
||||
can be \fB\%docker://\fRdocker-reference, \fBdir:\fRlocal-path, or \fBatomic:\fRimagestream-name\fB:\fRtag .
|
||||
.sp
|
||||
\fB\-\-sign\-by=\fRkey-id
|
||||
Add a signature by the specified key ID for image name corresponding to \fBdestination-location\fR.
|
||||
Existing signatures, if any, are preserved as well.
|
||||
.TP
|
||||
.B delete
|
||||
Mark an image for deletion. You must then run docker registry garabage collection to recover the disk space. E.g.,
|
||||
.sp
|
||||
\fBdocker exec -it registry bin/registry \\
|
||||
.br
|
||||
garbage-collect /etc/docker/registry/config.yml\fR
|
||||
.sp 2
|
||||
Additionally, the registry must allow deletions by setting \fB\%REGISTRY_STORAGE_DELETE_ENABLED=true\fR
|
||||
for the registry daemon.
|
||||
.TP
|
||||
.B inspect
|
||||
Return low-level information on images in a registry
|
||||
.sp
|
||||
|
@ -396,3 +396,7 @@ type status struct {
|
||||
// Details *StatusDetails `json:"details,omitempty"`
|
||||
Code int32 `json:"code,omitempty"`
|
||||
}
|
||||
|
||||
func (s *openshiftImageSource) Delete() error {
|
||||
return fmt.Errorf("openshift#openshiftImageSource.Delete() not implmented")
|
||||
}
|
||||
|
@ -33,6 +33,8 @@ type ImageSource interface {
|
||||
GetLayer(digest string) (io.ReadCloser, error)
|
||||
// GetSignatures returns the image's signatures. It may use a remote (= slow) service.
|
||||
GetSignatures() ([][]byte, error)
|
||||
// Delete image from registry, if operation is supported
|
||||
Delete() error
|
||||
}
|
||||
|
||||
// ImageDestination is a service, possibly remote (= slow), to store components of a single image.
|
||||
|
Loading…
Reference in New Issue
Block a user