Bundle removal now requires removing both workdir and path locations on delete in shim. Signed-off-by: Phil Estes <estesp@linux.vnet.ibm.com>
		
			
				
	
	
		
			133 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// +build linux
 | 
						|
 | 
						|
package linux
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"context"
 | 
						|
	"io"
 | 
						|
	"os"
 | 
						|
	"path/filepath"
 | 
						|
 | 
						|
	"github.com/containerd/containerd/events"
 | 
						|
	"github.com/containerd/containerd/linux/runcopts"
 | 
						|
	client "github.com/containerd/containerd/linux/shim"
 | 
						|
	"github.com/containerd/containerd/runtime"
 | 
						|
	"github.com/containerd/containerd/typeurl"
 | 
						|
	"github.com/pkg/errors"
 | 
						|
)
 | 
						|
 | 
						|
func loadBundle(path, workdir, namespace string, events *events.Exchange) *bundle {
 | 
						|
	return &bundle{
 | 
						|
		path:      path,
 | 
						|
		namespace: namespace,
 | 
						|
		events:    events,
 | 
						|
		workDir:   workdir,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// newBundle creates a new bundle on disk at the provided path for the given id
 | 
						|
func newBundle(path, namespace, workDir, id string, spec []byte, events *events.Exchange) (b *bundle, err error) {
 | 
						|
	if err := os.MkdirAll(path, 0711); err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	path = filepath.Join(path, id)
 | 
						|
	defer func() {
 | 
						|
		if err != nil {
 | 
						|
			os.RemoveAll(path)
 | 
						|
		}
 | 
						|
	}()
 | 
						|
	workDir = filepath.Join(workDir, id)
 | 
						|
	if err := os.MkdirAll(workDir, 0711); err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	defer func() {
 | 
						|
		if err != nil {
 | 
						|
			os.RemoveAll(workDir)
 | 
						|
		}
 | 
						|
	}()
 | 
						|
 | 
						|
	if err := os.Mkdir(path, 0711); err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	if err := os.Mkdir(filepath.Join(path, "rootfs"), 0711); err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	f, err := os.Create(filepath.Join(path, configFilename))
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
	defer f.Close()
 | 
						|
	_, err = io.Copy(f, bytes.NewReader(spec))
 | 
						|
	return &bundle{
 | 
						|
		id:        id,
 | 
						|
		path:      path,
 | 
						|
		workDir:   workDir,
 | 
						|
		namespace: namespace,
 | 
						|
		events:    events,
 | 
						|
	}, err
 | 
						|
}
 | 
						|
 | 
						|
type bundle struct {
 | 
						|
	id        string
 | 
						|
	path      string
 | 
						|
	workDir   string
 | 
						|
	namespace string
 | 
						|
	events    *events.Exchange
 | 
						|
}
 | 
						|
 | 
						|
// NewShim connects to the shim managing the bundle and tasks
 | 
						|
func (b *bundle) NewShim(ctx context.Context, binary, grpcAddress string, remote, debug bool, createOpts runtime.CreateOpts) (*client.Client, error) {
 | 
						|
	opt := client.WithStart(binary, grpcAddress, debug)
 | 
						|
	if !remote {
 | 
						|
		opt = client.WithLocal(b.events)
 | 
						|
	}
 | 
						|
	var options runcopts.CreateOptions
 | 
						|
	if createOpts.Options != nil {
 | 
						|
		v, err := typeurl.UnmarshalAny(createOpts.Options)
 | 
						|
		if err != nil {
 | 
						|
			return nil, err
 | 
						|
		}
 | 
						|
		options = *v.(*runcopts.CreateOptions)
 | 
						|
	}
 | 
						|
	return client.New(ctx, client.Config{
 | 
						|
		Address:    b.shimAddress(),
 | 
						|
		Path:       b.path,
 | 
						|
		Namespace:  b.namespace,
 | 
						|
		CgroupPath: options.ShimCgroup,
 | 
						|
		WorkDir:    b.workDir,
 | 
						|
	}, opt)
 | 
						|
}
 | 
						|
 | 
						|
// Connect reconnects to an existing shim
 | 
						|
func (b *bundle) Connect(ctx context.Context, remote bool) (*client.Client, error) {
 | 
						|
	opt := client.WithConnect
 | 
						|
	if !remote {
 | 
						|
		opt = client.WithLocal(b.events)
 | 
						|
	}
 | 
						|
	return client.New(ctx, client.Config{
 | 
						|
		Address:   b.shimAddress(),
 | 
						|
		Path:      b.path,
 | 
						|
		Namespace: b.namespace,
 | 
						|
	}, opt)
 | 
						|
}
 | 
						|
 | 
						|
// Delete deletes the bundle from disk
 | 
						|
func (b *bundle) Delete() error {
 | 
						|
	err := os.RemoveAll(b.path)
 | 
						|
	if err == nil {
 | 
						|
		return os.RemoveAll(b.workDir)
 | 
						|
	}
 | 
						|
	// error removing the bundle path; still attempt removing work dir
 | 
						|
	err2 := os.RemoveAll(b.workDir)
 | 
						|
	if err2 == nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	return errors.Wrapf(err, "Failed to remove both bundle and workdir locations: %v", err2)
 | 
						|
}
 | 
						|
 | 
						|
func (b *bundle) shimAddress() string {
 | 
						|
	return filepath.Join(string(filepath.Separator), "containerd-shim", b.namespace, b.id, "shim.sock")
 | 
						|
 | 
						|
}
 |