Description: fix tarmeta 
 docker-ce (5:20.10.3-14) buster; urgency=low
 .
   * Version: 20.10.3-14
   * fix tarmeta 
Author: wanghuaiqing <wanghuaiqing@loongson.com>

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: 2022-05-10

--- lcf-utils-1.0.1/src/loongker-ce-20.10.3.orig/sources/engine/api/server/router/image/backend.go
+++ lcf-utils-1.0.1/src/loongker-ce-20.10.3/sources/engine/api/server/router/image/backend.go
@@ -27,7 +27,7 @@ type imageBackend interface {
 	LookupImage(name string) (*types.ImageInspect, error)
 	TagImage(imageName, repository, tag string) (string, error)
 	ImagesPrune(ctx context.Context, pruneFilters filters.Args) (*types.ImagesPruneReport, error)
-	ImageGenApplayer(imageRef string, appname string) (*types.ImageGenApplayerBody, error)
+	ImageGenApplayer(imageRef string, appname string, outStream io.Writer) (*types.ImageGenApplayerBody, error)
 	ApplayerDelete(idorName string) (*types.AppLayerDeleteResponse, error)
 	Appcompose() error
 }
--- lcf-utils-1.0.1/src/loongker-ce-20.10.3.orig/sources/engine/api/server/router/image/image_routes.go
+++ lcf-utils-1.0.1/src/loongker-ce-20.10.3/sources/engine/api/server/router/image/image_routes.go
@@ -323,6 +323,9 @@ func (s *imageRouter) genApplayer(ctx co
 	if err := httputils.ParseForm(r); err != nil {
 		return err
 	}
+	w.Header().Set("Content-Type", "application/json")
+	output := ioutils.NewWriteFlusher(w)
+	defer output.Close()
 
 	applayername := r.Form.Get("applayername")
 	name := vars["name"]
@@ -331,7 +334,7 @@ func (s *imageRouter) genApplayer(ctx co
 		return missingImageError{}
 	}
 
-	response, err := s.backend.ImageGenApplayer(name, applayername)
+	response, err := s.backend.ImageGenApplayer(name, applayername, output)
 	if err != nil {
 		return err
 	}
--- lcf-utils-1.0.1/src/loongker-ce-20.10.3.orig/sources/engine/daemon/images/image_genapplayer.go
+++ lcf-utils-1.0.1/src/loongker-ce-20.10.3/sources/engine/daemon/images/image_genapplayer.go
@@ -1,18 +1,25 @@
 package images // import "github.com/docker/docker/daemon/images"
 
 import (
+	"io"
 	"runtime"
 	"encoding/json"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/layer"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/pkg/system"
+	"github.com/docker/docker/pkg/progress"
+	"github.com/docker/docker/pkg/streamformatter"
 	"github.com/docker/docker/image/appcompose"
 	"github.com/pkg/errors"
 	digest "github.com/opencontainers/go-digest"
 )
 
-func (i *ImageService) ImageGenApplayer(imageRef string, appname string) (*types.ImageGenApplayerBody, error) {
+func (i *ImageService) ImageGenApplayer(imageRef string, appname string, outStream io.Writer) (*types.ImageGenApplayerBody, error) {
+
+	var progressOutput progress.Output
+	progressOutput = streamformatter.NewJSONProgressOutput(outStream, false)
+	outStream = streamformatter.NewStdoutWriter(outStream)
 
 	id, err := i.applayerStore.GetByName(appname)
 	if err == nil {
@@ -60,12 +67,20 @@ func (i *ImageService) ImageGenApplayer(
 	}
 	defer tar.Close()
 
-	id, err = i.applayerStore.Create(tar, appname, config)
+	var r io.Reader
+	if progressOutput != nil {
+		diffsize, _ := newLayer.DiffSize()
+		r = progress.NewProgressReader(tar, progressOutput, diffsize, string(appname), "Making applayer")
+	} else {
+		r = tar
+	}
+
+	id, err = i.applayerStore.Create(r, appname, config)
 	if err != nil {
 		return nil, err
 	}
 	ac := appcompose.NewAppComposer(i.imageStore, i.layerStores, i.referenceStore, i.applayerStore, i)
-	ac.GenImgByApplayerID(id)
+	err = ac.GenImgByApplayerID(id)
 	resp.ID = id.String()
 	return &resp, nil
 }
--- lcf-utils-1.0.1/src/loongker-ce-20.10.3.orig/sources/engine/image/appcompose/appcompose.go
+++ lcf-utils-1.0.1/src/loongker-ce-20.10.3/sources/engine/image/appcompose/appcompose.go
@@ -82,9 +82,14 @@ func (ac *appcomposer) appcompose(imgid
 		}
 	}
 	chainid := baseimg.RootFS.ChainID()
+	tarMeta, err := ac.as.TarSplitReader(al.AppLayerID())
+	if err != nil {
+		return
+	}
+	defer tarMeta.Close()
 	datadir := ac.as.GetAppLayerDataDir(al.AppLayerID())
 	os := baseimg.OperatingSystem()
-	newlayer, err := ac.lss[os].RegisterDir(datadir, al.DiffID(), al.Size(), chainid)
+	newlayer, err := ac.lss[os].RegisterDir(datadir, tarMeta, al.DiffID(), al.Size(), chainid)
 	if err != nil {
 		return
 	}
--- lcf-utils-1.0.1/src/loongker-ce-20.10.3.orig/sources/engine/image/applayer.go
+++ lcf-utils-1.0.1/src/loongker-ce-20.10.3/sources/engine/image/applayer.go
@@ -20,6 +20,7 @@ type AppLayer interface {
 	RefsCount() int
 	AddRefImage(id ID) error
 	DelRefImage(id ID) error
+	GetRefImage(id ID) bool
 }
 /*
 The content of the appLayer contains two parts.
@@ -110,3 +111,10 @@ func (al *appLayer) DelRefImage(id ID) e
 	return nil
 }
 
+func (al *appLayer) GetRefImage(id ID) bool {
+	_, ok := al.refImages[id]
+	if !ok {
+		return false
+	}
+	return true
+}
--- lcf-utils-1.0.1/src/loongker-ce-20.10.3.orig/sources/engine/image/applayer_store.go
+++ lcf-utils-1.0.1/src/loongker-ce-20.10.3/sources/engine/image/applayer_store.go
@@ -36,6 +36,7 @@ const (
 
 // Store is an interface for creating and accessing images
 type ApplayerStore interface {
+	TarSplitReader(id ID) (io.ReadCloser, error)
 	SaveAppLayer(id ID, outDir string) error
 	GetAppLayerDataDir(id ID) string
 	AppendImgID(applayerid ID, imageID ID) error
@@ -187,7 +188,6 @@ func (as *applayerstore) GetAppLayerData
 	return as.fs.LayerContentDir(id.Digest())
 }
 
-
 func (as *applayerstore) AppendImgID(applayerid ID, imageID ID) error {
 	as.Lock()
 	defer as.Unlock()
@@ -206,11 +206,14 @@ func (as *applayerstore) DeleteImgID(app
 	if nil == al {
 		return fmt.Errorf("func DeleteImgID failed to get applayer: %v", applayerid)
 	}
+	flag := al.GetRefImage(imageID)
+	if false == flag {
+		return nil
+	}
 	al.DelRefImage(imageID)
 	return as.fs.RemoveImageID(applayerid.Digest(), imageID)
 }
 
-
 func (as *applayerstore) Create(ts io.Reader, name string, config []byte) (ID, error) {
 	var appimg Image
 	err := json.Unmarshal(config, &appimg)
@@ -347,6 +350,10 @@ func (as *applayerstore) Get(id ID) (App
 	return al.copyAppLayer(), nil
 }
 
+func (as *applayerstore) TarSplitReader(id ID) (io.ReadCloser, error) {
+	return as.fs.TarSplitReader(id.Digest())
+}
+
 func (as *applayerstore) SaveAppLayer(id ID, outDir string) error {
 	as.LockId(id.String())
 	defer as.UnlockId(id.String())
--- lcf-utils-1.0.1/src/loongker-ce-20.10.3.orig/sources/engine/image/image.go
+++ lcf-utils-1.0.1/src/loongker-ce-20.10.3/sources/engine/image/image.go
@@ -412,7 +412,8 @@ func NewApplayerImage(img *Image) *Image
 			//Container:       img.Container,
 			//ContainerConfig: *copyRunConfig(img.RunContainerConfig()),
 			Author:          img.Author,
-			Created:         time.Now().UTC(),
+			//avoid to produce the different applayerid to the same image
+			//Created:         time.Now().UTC(),
 		},
 		RootFS:     rootFS,
 		History:    nil,
--- lcf-utils-1.0.1/src/loongker-ce-20.10.3.orig/sources/engine/layer/layer.go
+++ lcf-utils-1.0.1/src/loongker-ce-20.10.3/sources/engine/layer/layer.go
@@ -183,7 +183,7 @@ type CreateRWLayerOpts struct {
 // Store represents a backend for managing both
 // read-only and read-write layers.
 type Store interface {
-	RegisterDir(dir string, diffID DiffID, size int64, parent ChainID) (Layer, error)
+	RegisterDir(dir string, tarMeta io.Reader, diffID DiffID, size int64, parent ChainID) (Layer, error)
 	Register(io.Reader, ChainID) (Layer, error)
 	Get(ChainID) (Layer, error)
 	Map() map[ChainID]Layer
--- lcf-utils-1.0.1/src/loongker-ce-20.10.3.orig/sources/engine/layer/layer_store.go
+++ lcf-utils-1.0.1/src/loongker-ce-20.10.3/sources/engine/layer/layer_store.go
@@ -299,7 +299,7 @@ func (ls *layerStore) Register(ts io.Rea
 	return ls.registerWithDescriptor(ts, parent, distribution.Descriptor{})
 }
 
-func (ls *layerStore) RegisterDir(dir string, diffID DiffID, size int64, parent ChainID) (Layer, error) {
+func (ls *layerStore) RegisterDir(dir string, tarMeta io.Reader, diffID DiffID, size int64, parent ChainID) (Layer, error) {
 	// err is used to hold the error which will always trigger
 	// cleanup of creates sources but may not be an error returned
 	// to the caller (already exists).
@@ -380,7 +380,12 @@ func (ls *layerStore) RegisterDir(dir st
 	if err = storeLayer(tx, layer); err != nil {
 		return nil, err
 	}
-
+	wtarMeta, err := tx.TarSplitWriter(false)
+	if err != nil {
+		return nil, err
+	}
+	defer wtarMeta.Close()
+	io.Copy(wtarMeta, tarMeta)
 	ls.layerL.Lock()
 	defer ls.layerL.Unlock()
 
