github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/libpod/diff.go (about)

     1  package libpod
     2  
     3  import (
     4  	"io"
     5  
     6  	"github.com/containers/libpod/libpod/layers"
     7  	"github.com/containers/storage/pkg/archive"
     8  	"github.com/pkg/errors"
     9  )
    10  
    11  var containerMounts = map[string]bool{
    12  	"/dev":               true,
    13  	"/etc/hostname":      true,
    14  	"/etc/hosts":         true,
    15  	"/etc/resolv.conf":   true,
    16  	"/proc":              true,
    17  	"/run":               true,
    18  	"/run/.containerenv": true,
    19  	"/run/secrets":       true,
    20  	"/sys":               true,
    21  }
    22  
    23  // GetDiff returns the differences between the two images, layers, or containers
    24  func (r *Runtime) GetDiff(from, to string) ([]archive.Change, error) {
    25  	toLayer, err := r.getLayerID(to)
    26  	if err != nil {
    27  		return nil, err
    28  	}
    29  	fromLayer := ""
    30  	if from != "" {
    31  		fromLayer, err = r.getLayerID(from)
    32  		if err != nil {
    33  			return nil, err
    34  		}
    35  	}
    36  	var rchanges []archive.Change
    37  	changes, err := r.store.Changes(fromLayer, toLayer)
    38  	if err == nil {
    39  		for _, c := range changes {
    40  			if containerMounts[c.Path] {
    41  				continue
    42  			}
    43  			rchanges = append(rchanges, c)
    44  		}
    45  	}
    46  	return rchanges, err
    47  }
    48  
    49  // ApplyDiffTarStream applies the changes stored in 'diff' to the layer 'to'
    50  func (r *Runtime) ApplyDiffTarStream(to string, diff io.Reader) error {
    51  	toLayer, err := r.getLayerID(to)
    52  	if err != nil {
    53  		return err
    54  	}
    55  	_, err = r.store.ApplyDiff(toLayer, diff)
    56  	return err
    57  }
    58  
    59  // GetLayerID gets a full layer id given a full or partial id
    60  // If the id matches a container or image, the id of the top layer is returned
    61  // If the id matches a layer, the top layer id is returned
    62  func (r *Runtime) getLayerID(id string) (string, error) {
    63  	var toLayer string
    64  	toImage, err := r.imageRuntime.NewFromLocal(id)
    65  	if err != nil {
    66  		toCtr, err := r.store.Container(id)
    67  		if err != nil {
    68  			toLayer, err = layers.FullID(r.store, id)
    69  			if err != nil {
    70  				return "", errors.Errorf("layer, image, or container %s does not exist", id)
    71  			}
    72  		} else {
    73  			toLayer = toCtr.LayerID
    74  		}
    75  	} else {
    76  		toLayer = toImage.TopLayer()
    77  	}
    78  	return toLayer, nil
    79  }