the image may has the same blobs as the references, which causes the artifact & blobs
can not be inserted by unique constraint

Signed-off-by: wang yan <wangyan@vmware.com>
This commit is contained in:
wang yan 2019-08-29 19:33:34 +08:00
parent e2a19d8ab9
commit dd9f028fe0
2 changed files with 53 additions and 20 deletions

View File

@ -91,13 +91,13 @@ func doDeleteManifestRequest(projectID int64, projectName, name, dgt string, nex
return rr.Code
}
func doPutManifestRequest(projectID int64, projectName, name, tag, dgt string, next ...http.HandlerFunc) int {
func doPutManifestRequest(projectID int64, projectName, name, tag, dgt string, withDupBlob bool, next ...http.HandlerFunc) int {
repository := fmt.Sprintf("%s/%s", projectName, name)
url := fmt.Sprintf("/v2/%s/manifests/%s", repository, tag)
req, _ := http.NewRequest("PUT", url, nil)
ctx := util.NewManifestInfoContext(req.Context(), &util.ManifestInfo{
mfInfo := &util.ManifestInfo{
ProjectID: projectID,
Repository: repository,
Tag: tag,
@ -106,7 +106,14 @@ func doPutManifestRequest(projectID int64, projectName, name, tag, dgt string, n
{Digest: digest.FromString(randomString(15))},
{Digest: digest.FromString(randomString(15))},
},
})
}
ctx := util.NewManifestInfoContext(req.Context(), mfInfo)
if withDupBlob {
dupDigest := digest.FromString(randomString(15))
mfInfo.References = append(mfInfo.References, distribution.Descriptor{Digest: dupDigest})
mfInfo.References = append(mfInfo.References, distribution.Descriptor{Digest: dupDigest})
}
rr := httptest.NewRecorder()
@ -165,7 +172,7 @@ func (suite *HandlerSuite) TestPutManifestCreated() {
}()
dgt := digest.FromString(randomString(15)).String()
code := doPutManifestRequest(projectID, projectName, "photon", "latest", dgt)
code := doPutManifestRequest(projectID, projectName, "photon", "latest", dgt, false)
suite.Equal(http.StatusCreated, code)
suite.checkCountUsage(1, projectID)
@ -174,7 +181,7 @@ func (suite *HandlerSuite) TestPutManifestCreated() {
suite.Equal(int64(1), total, "Artifact should be created")
// Push the photon:latest with photon:dev
code = doPutManifestRequest(projectID, projectName, "photon", "dev", dgt)
code = doPutManifestRequest(projectID, projectName, "photon", "dev", dgt, false)
suite.Equal(http.StatusCreated, code)
suite.checkCountUsage(2, projectID)
@ -184,7 +191,7 @@ func (suite *HandlerSuite) TestPutManifestCreated() {
// Push the photon:latest with new image
newDgt := digest.FromString(randomString(15)).String()
code = doPutManifestRequest(projectID, projectName, "photon", "latest", newDgt)
code = doPutManifestRequest(projectID, projectName, "photon", "latest", newDgt, false)
suite.Equal(http.StatusCreated, code)
suite.checkCountUsage(2, projectID)
@ -193,6 +200,26 @@ func (suite *HandlerSuite) TestPutManifestCreated() {
suite.Equal(int64(1), total, "Artifact should be updated")
}
func (suite *HandlerSuite) TestPutManifestCreatedDupBlobs() {
projectName := randomString(5)
projectID := suite.addProject(projectName)
defer func() {
dao.DeleteProject(projectID)
}()
dgt := digest.FromString(randomString(15)).String()
code := doPutManifestRequest(projectID, projectName, "photon", "latest", dgt, true)
suite.Equal(http.StatusCreated, code)
suite.checkCountUsage(1, projectID)
var count int64
err := dao.GetOrmer().Raw("select count(*) from artifact_blob where digest_af = ?", dgt).QueryRow(&count)
suite.Nil(err)
// 4 = self + 3 distinct blobs
suite.Equal(int64(4), count)
}
func (suite *HandlerSuite) TestPutManifestFailed() {
projectName := randomString(5)
@ -206,7 +233,7 @@ func (suite *HandlerSuite) TestPutManifestFailed() {
}
dgt := digest.FromString(randomString(15)).String()
code := doPutManifestRequest(projectID, projectName, "photon", "latest", dgt, next)
code := doPutManifestRequest(projectID, projectName, "photon", "latest", dgt, false, next)
suite.Equal(http.StatusForbidden, code)
suite.checkCountUsage(0, projectID)
@ -224,7 +251,7 @@ func (suite *HandlerSuite) TestDeleteManifestAccepted() {
}()
dgt := digest.FromString(randomString(15)).String()
code := doPutManifestRequest(projectID, projectName, "photon", "latest", dgt)
code := doPutManifestRequest(projectID, projectName, "photon", "latest", dgt, false)
suite.Equal(http.StatusCreated, code)
suite.checkCountUsage(1, projectID)
@ -242,7 +269,7 @@ func (suite *HandlerSuite) TestDeleteManifestFailed() {
}()
dgt := digest.FromString(randomString(15)).String()
code := doPutManifestRequest(projectID, projectName, "photon", "latest", dgt)
code := doPutManifestRequest(projectID, projectName, "photon", "latest", dgt, false)
suite.Equal(http.StatusCreated, code)
suite.checkCountUsage(1, projectID)
@ -264,7 +291,7 @@ func (suite *HandlerSuite) TestDeleteManifestInMultiProjects() {
}()
dgt := digest.FromString(randomString(15)).String()
code := doPutManifestRequest(projectID, projectName, "photon", "latest", dgt)
code := doPutManifestRequest(projectID, projectName, "photon", "latest", dgt, false)
suite.Equal(http.StatusCreated, code)
suite.checkCountUsage(1, projectID)
@ -276,7 +303,7 @@ func (suite *HandlerSuite) TestDeleteManifestInMultiProjects() {
dao.DeleteProject(projectID)
}()
code := doPutManifestRequest(projectID, projectName, "photon", "latest", dgt)
code := doPutManifestRequest(projectID, projectName, "photon", "latest", dgt, false)
suite.Equal(http.StatusCreated, code)
suite.checkCountUsage(1, projectID)

View File

@ -89,20 +89,26 @@ func afterManifestCreated(w http.ResponseWriter, req *http.Request) error {
// attachBlobsToArtifact attach the blobs which from manifest to artifact
func attachBlobsToArtifact(info *util.ManifestInfo) error {
self := &models.ArtifactAndBlob{
temp := make(map[string]interface{})
artifactBlobs := []*models.ArtifactAndBlob{}
temp[info.Digest] = nil
// self
artifactBlobs = append(artifactBlobs, &models.ArtifactAndBlob{
DigestAF: info.Digest,
DigestBlob: info.Digest,
}
artifactBlobs := append([]*models.ArtifactAndBlob{}, self)
})
// avoid the duplicate layers.
for _, reference := range info.References {
artifactBlob := &models.ArtifactAndBlob{
DigestAF: info.Digest,
DigestBlob: reference.Digest.String(),
_, exist := temp[reference.Digest.String()]
if !exist {
temp[reference.Digest.String()] = nil
artifactBlobs = append(artifactBlobs, &models.ArtifactAndBlob{
DigestAF: info.Digest,
DigestBlob: reference.Digest.String(),
})
}
artifactBlobs = append(artifactBlobs, artifactBlob)
}
if err := dao.AddArtifactNBlobs(artifactBlobs); err != nil {