github.com/tsuna/docker@v1.7.0-rc3/daemon/delete.go (about)

     1  package daemon
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path"
     7  
     8  	"github.com/Sirupsen/logrus"
     9  )
    10  
    11  type ContainerRmConfig struct {
    12  	ForceRemove, RemoveVolume, RemoveLink bool
    13  }
    14  
    15  func (daemon *Daemon) ContainerRm(name string, config *ContainerRmConfig) error {
    16  	container, err := daemon.Get(name)
    17  	if err != nil {
    18  		return err
    19  	}
    20  
    21  	if config.RemoveLink {
    22  		name, err := GetFullContainerName(name)
    23  		if err != nil {
    24  			return err
    25  		}
    26  		parent, n := path.Split(name)
    27  		if parent == "/" {
    28  			return fmt.Errorf("Conflict, cannot remove the default name of the container")
    29  		}
    30  		pe := daemon.ContainerGraph().Get(parent)
    31  		if pe == nil {
    32  			return fmt.Errorf("Cannot get parent %s for name %s", parent, name)
    33  		}
    34  		parentContainer, _ := daemon.Get(pe.ID())
    35  
    36  		if err := daemon.ContainerGraph().Delete(name); err != nil {
    37  			return err
    38  		}
    39  
    40  		if parentContainer != nil {
    41  			parentContainer.DisableLink(n)
    42  		}
    43  
    44  		return nil
    45  	}
    46  
    47  	if err := daemon.rm(container, config.ForceRemove); err != nil {
    48  		return fmt.Errorf("Cannot destroy container %s: %v", name, err)
    49  	}
    50  
    51  	container.LogEvent("destroy")
    52  
    53  	if config.RemoveVolume {
    54  		container.removeMountPoints()
    55  	}
    56  	return nil
    57  }
    58  
    59  // Destroy unregisters a container from the daemon and cleanly removes its contents from the filesystem.
    60  func (daemon *Daemon) rm(container *Container, forceRemove bool) (err error) {
    61  	if container.IsRunning() {
    62  		if !forceRemove {
    63  			return fmt.Errorf("Conflict, You cannot remove a running container. Stop the container before attempting removal or use -f")
    64  		}
    65  		if err := container.Kill(); err != nil {
    66  			return fmt.Errorf("Could not kill running container, cannot remove - %v", err)
    67  		}
    68  	}
    69  
    70  	// stop collection of stats for the container regardless
    71  	// if stats are currently getting collected.
    72  	daemon.statsCollector.stopCollection(container)
    73  
    74  	element := daemon.containers.Get(container.ID)
    75  	if element == nil {
    76  		return fmt.Errorf("Container %v not found - maybe it was already destroyed?", container.ID)
    77  	}
    78  
    79  	// Container state RemovalInProgress should be used to avoid races.
    80  	if err = container.SetRemovalInProgress(); err != nil {
    81  		return fmt.Errorf("Failed to set container state to RemovalInProgress: %s", err)
    82  	}
    83  
    84  	defer container.ResetRemovalInProgress()
    85  
    86  	if err = container.Stop(3); err != nil {
    87  		return err
    88  	}
    89  
    90  	// Mark container dead. We don't want anybody to be restarting it.
    91  	container.SetDead()
    92  
    93  	// Save container state to disk. So that if error happens before
    94  	// container meta file got removed from disk, then a restart of
    95  	// docker should not make a dead container alive.
    96  	container.ToDisk()
    97  
    98  	// If force removal is required, delete container from various
    99  	// indexes even if removal failed.
   100  	defer func() {
   101  		if err != nil && forceRemove {
   102  			daemon.idIndex.Delete(container.ID)
   103  			daemon.containers.Delete(container.ID)
   104  			os.RemoveAll(container.root)
   105  		}
   106  	}()
   107  
   108  	if _, err := daemon.containerGraph.Purge(container.ID); err != nil {
   109  		logrus.Debugf("Unable to remove container from link graph: %s", err)
   110  	}
   111  
   112  	if err = daemon.driver.Remove(container.ID); err != nil {
   113  		return fmt.Errorf("Driver %s failed to remove root filesystem %s: %s", daemon.driver, container.ID, err)
   114  	}
   115  
   116  	initID := fmt.Sprintf("%s-init", container.ID)
   117  	if err := daemon.driver.Remove(initID); err != nil {
   118  		return fmt.Errorf("Driver %s failed to remove init filesystem %s: %s", daemon.driver, initID, err)
   119  	}
   120  
   121  	if err = os.RemoveAll(container.root); err != nil {
   122  		return fmt.Errorf("Unable to remove filesystem for %v: %v", container.ID, err)
   123  	}
   124  
   125  	if err = daemon.execDriver.Clean(container.ID); err != nil {
   126  		return fmt.Errorf("Unable to remove execdriver data for %s: %s", container.ID, err)
   127  	}
   128  
   129  	selinuxFreeLxcContexts(container.ProcessLabel)
   130  	daemon.idIndex.Delete(container.ID)
   131  	daemon.containers.Delete(container.ID)
   132  
   133  	return nil
   134  }
   135  
   136  func (daemon *Daemon) DeleteVolumes(c *Container) error {
   137  	return c.removeMountPoints()
   138  }