daemon.go 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043
  1. package daemon
  2. import (
  3. "errors"
  4. "fmt"
  5. "io"
  6. "io/ioutil"
  7. "os"
  8. "path/filepath"
  9. "regexp"
  10. "runtime"
  11. "strings"
  12. "sync"
  13. "time"
  14. "github.com/Sirupsen/logrus"
  15. "github.com/docker/docker/api"
  16. "github.com/docker/docker/daemon/events"
  17. "github.com/docker/docker/daemon/execdriver"
  18. "github.com/docker/docker/daemon/execdriver/execdrivers"
  19. "github.com/docker/docker/daemon/graphdriver"
  20. _ "github.com/docker/docker/daemon/graphdriver/vfs"
  21. "github.com/docker/docker/daemon/logger"
  22. "github.com/docker/docker/daemon/network"
  23. "github.com/docker/docker/graph"
  24. "github.com/docker/docker/image"
  25. "github.com/docker/docker/pkg/archive"
  26. "github.com/docker/docker/pkg/broadcastwriter"
  27. "github.com/docker/docker/pkg/fileutils"
  28. "github.com/docker/docker/pkg/graphdb"
  29. "github.com/docker/docker/pkg/ioutils"
  30. "github.com/docker/docker/pkg/namesgenerator"
  31. "github.com/docker/docker/pkg/nat"
  32. "github.com/docker/docker/pkg/stringid"
  33. "github.com/docker/docker/pkg/sysinfo"
  34. "github.com/docker/docker/pkg/system"
  35. "github.com/docker/docker/pkg/truncindex"
  36. "github.com/docker/docker/registry"
  37. "github.com/docker/docker/runconfig"
  38. "github.com/docker/docker/trust"
  39. "github.com/docker/libnetwork"
  40. "github.com/opencontainers/runc/libcontainer/netlink"
  41. )
  42. var (
  43. validContainerNameChars = `[a-zA-Z0-9][a-zA-Z0-9_.-]`
  44. validContainerNamePattern = regexp.MustCompile(`^/?` + validContainerNameChars + `+$`)
  45. ErrSystemNotSupported = errors.New("The Docker daemon is not supported on this platform.")
  46. )
  47. type contStore struct {
  48. s map[string]*Container
  49. sync.Mutex
  50. }
  51. func (c *contStore) Add(id string, cont *Container) {
  52. c.Lock()
  53. c.s[id] = cont
  54. c.Unlock()
  55. }
  56. func (c *contStore) Get(id string) *Container {
  57. c.Lock()
  58. res := c.s[id]
  59. c.Unlock()
  60. return res
  61. }
  62. func (c *contStore) Delete(id string) {
  63. c.Lock()
  64. delete(c.s, id)
  65. c.Unlock()
  66. }
  67. func (c *contStore) List() []*Container {
  68. containers := new(History)
  69. c.Lock()
  70. for _, cont := range c.s {
  71. containers.Add(cont)
  72. }
  73. c.Unlock()
  74. containers.Sort()
  75. return *containers
  76. }
  77. type Daemon struct {
  78. ID string
  79. repository string
  80. sysInitPath string
  81. containers *contStore
  82. execCommands *execStore
  83. graph *graph.Graph
  84. repositories *graph.TagStore
  85. idIndex *truncindex.TruncIndex
  86. config *Config
  87. containerGraph *graphdb.Database
  88. driver graphdriver.Driver
  89. execDriver execdriver.Driver
  90. statsCollector *statsCollector
  91. defaultLogConfig runconfig.LogConfig
  92. RegistryService *registry.Service
  93. EventsService *events.Events
  94. netController libnetwork.NetworkController
  95. root string
  96. }
  97. // Get looks for a container using the provided information, which could be
  98. // one of the following inputs from the caller:
  99. // - A full container ID, which will exact match a container in daemon's list
  100. // - A container name, which will only exact match via the GetByName() function
  101. // - A partial container ID prefix (e.g. short ID) of any length that is
  102. // unique enough to only return a single container object
  103. // If none of these searches succeed, an error is returned
  104. func (daemon *Daemon) Get(prefixOrName string) (*Container, error) {
  105. if containerByID := daemon.containers.Get(prefixOrName); containerByID != nil {
  106. // prefix is an exact match to a full container ID
  107. return containerByID, nil
  108. }
  109. // GetByName will match only an exact name provided; we ignore errors
  110. if containerByName, _ := daemon.GetByName(prefixOrName); containerByName != nil {
  111. // prefix is an exact match to a full container Name
  112. return containerByName, nil
  113. }
  114. containerId, indexError := daemon.idIndex.Get(prefixOrName)
  115. if indexError != nil {
  116. return nil, indexError
  117. }
  118. return daemon.containers.Get(containerId), nil
  119. }
  120. // Exists returns a true if a container of the specified ID or name exists,
  121. // false otherwise.
  122. func (daemon *Daemon) Exists(id string) bool {
  123. c, _ := daemon.Get(id)
  124. return c != nil
  125. }
  126. func (daemon *Daemon) containerRoot(id string) string {
  127. return filepath.Join(daemon.repository, id)
  128. }
  129. // Load reads the contents of a container from disk
  130. // This is typically done at startup.
  131. func (daemon *Daemon) load(id string) (*Container, error) {
  132. container := daemon.newBaseContainer(id)
  133. if err := container.FromDisk(); err != nil {
  134. return nil, err
  135. }
  136. if container.ID != id {
  137. return &container, fmt.Errorf("Container %s is stored at %s", container.ID, id)
  138. }
  139. return &container, nil
  140. }
  141. // Register makes a container object usable by the daemon as <container.ID>
  142. // This is a wrapper for register
  143. func (daemon *Daemon) Register(container *Container) error {
  144. return daemon.register(container, true)
  145. }
  146. // register makes a container object usable by the daemon as <container.ID>
  147. func (daemon *Daemon) register(container *Container, updateSuffixarray bool) error {
  148. if container.daemon != nil || daemon.Exists(container.ID) {
  149. return fmt.Errorf("Container is already loaded")
  150. }
  151. if err := validateID(container.ID); err != nil {
  152. return err
  153. }
  154. if err := daemon.ensureName(container); err != nil {
  155. return err
  156. }
  157. container.daemon = daemon
  158. // Attach to stdout and stderr
  159. container.stderr = broadcastwriter.New()
  160. container.stdout = broadcastwriter.New()
  161. // Attach to stdin
  162. if container.Config.OpenStdin {
  163. container.stdin, container.stdinPipe = io.Pipe()
  164. } else {
  165. container.stdinPipe = ioutils.NopWriteCloser(ioutil.Discard) // Silently drop stdin
  166. }
  167. // done
  168. daemon.containers.Add(container.ID, container)
  169. // don't update the Suffixarray if we're starting up
  170. // we'll waste time if we update it for every container
  171. daemon.idIndex.Add(container.ID)
  172. if container.IsRunning() {
  173. logrus.Debugf("killing old running container %s", container.ID)
  174. // Set exit code to 128 + SIGKILL (9) to properly represent unsuccessful exit
  175. container.SetStopped(&execdriver.ExitStatus{ExitCode: 137})
  176. // use the current driver and ensure that the container is dead x.x
  177. cmd := &execdriver.Command{
  178. ID: container.ID,
  179. }
  180. daemon.execDriver.Terminate(cmd)
  181. if err := container.Unmount(); err != nil {
  182. logrus.Debugf("unmount error %s", err)
  183. }
  184. if err := container.ToDisk(); err != nil {
  185. logrus.Errorf("Error saving stopped state to disk: %v", err)
  186. }
  187. }
  188. if err := daemon.verifyVolumesInfo(container); err != nil {
  189. return err
  190. }
  191. if err := container.prepareMountPoints(); err != nil {
  192. return err
  193. }
  194. return nil
  195. }
  196. func (daemon *Daemon) ensureName(container *Container) error {
  197. if container.Name == "" {
  198. name, err := daemon.generateNewName(container.ID)
  199. if err != nil {
  200. return err
  201. }
  202. container.Name = name
  203. if err := container.ToDisk(); err != nil {
  204. logrus.Errorf("Error saving container name to disk: %v", err)
  205. }
  206. }
  207. return nil
  208. }
  209. func (daemon *Daemon) restore() error {
  210. type cr struct {
  211. container *Container
  212. registered bool
  213. }
  214. var (
  215. debug = os.Getenv("DEBUG") != ""
  216. currentDriver = daemon.driver.String()
  217. containers = make(map[string]*cr)
  218. )
  219. if !debug {
  220. logrus.Info("Loading containers: start.")
  221. }
  222. dir, err := ioutil.ReadDir(daemon.repository)
  223. if err != nil {
  224. return err
  225. }
  226. for _, v := range dir {
  227. id := v.Name()
  228. container, err := daemon.load(id)
  229. if !debug && logrus.GetLevel() == logrus.InfoLevel {
  230. fmt.Print(".")
  231. }
  232. if err != nil {
  233. logrus.Errorf("Failed to load container %v: %v", id, err)
  234. continue
  235. }
  236. // Ignore the container if it does not support the current driver being used by the graph
  237. if (container.Driver == "" && currentDriver == "aufs") || container.Driver == currentDriver {
  238. logrus.Debugf("Loaded container %v", container.ID)
  239. containers[container.ID] = &cr{container: container}
  240. } else {
  241. logrus.Debugf("Cannot load container %s because it was created with another graph driver.", container.ID)
  242. }
  243. }
  244. if entities := daemon.containerGraph.List("/", -1); entities != nil {
  245. for _, p := range entities.Paths() {
  246. if !debug && logrus.GetLevel() == logrus.InfoLevel {
  247. fmt.Print(".")
  248. }
  249. e := entities[p]
  250. if c, ok := containers[e.ID()]; ok {
  251. c.registered = true
  252. }
  253. }
  254. }
  255. group := sync.WaitGroup{}
  256. for _, c := range containers {
  257. group.Add(1)
  258. go func(container *Container, registered bool) {
  259. defer group.Done()
  260. if !registered {
  261. // Try to set the default name for a container if it exists prior to links
  262. container.Name, err = daemon.generateNewName(container.ID)
  263. if err != nil {
  264. logrus.Debugf("Setting default id - %s", err)
  265. }
  266. }
  267. if err := daemon.register(container, false); err != nil {
  268. logrus.Debugf("Failed to register container %s: %s", container.ID, err)
  269. }
  270. // check the restart policy on the containers and restart any container with
  271. // the restart policy of "always"
  272. if daemon.config.AutoRestart && container.shouldRestart() {
  273. logrus.Debugf("Starting container %s", container.ID)
  274. if err := container.Start(); err != nil {
  275. logrus.Debugf("Failed to start container %s: %s", container.ID, err)
  276. }
  277. }
  278. }(c.container, c.registered)
  279. }
  280. group.Wait()
  281. if !debug {
  282. if logrus.GetLevel() == logrus.InfoLevel {
  283. fmt.Println()
  284. }
  285. logrus.Info("Loading containers: done.")
  286. }
  287. return nil
  288. }
  289. func (daemon *Daemon) mergeAndVerifyConfig(config *runconfig.Config, img *image.Image) error {
  290. if img != nil && img.Config != nil {
  291. if err := runconfig.Merge(config, img.Config); err != nil {
  292. return err
  293. }
  294. }
  295. if config.Entrypoint.Len() == 0 && config.Cmd.Len() == 0 {
  296. return fmt.Errorf("No command specified")
  297. }
  298. return nil
  299. }
  300. func (daemon *Daemon) generateIdAndName(name string) (string, string, error) {
  301. var (
  302. err error
  303. id = stringid.GenerateNonCryptoID()
  304. )
  305. if name == "" {
  306. if name, err = daemon.generateNewName(id); err != nil {
  307. return "", "", err
  308. }
  309. return id, name, nil
  310. }
  311. if name, err = daemon.reserveName(id, name); err != nil {
  312. return "", "", err
  313. }
  314. return id, name, nil
  315. }
  316. func (daemon *Daemon) reserveName(id, name string) (string, error) {
  317. if !validContainerNamePattern.MatchString(name) {
  318. return "", fmt.Errorf("Invalid container name (%s), only %s are allowed", name, validContainerNameChars)
  319. }
  320. if name[0] != '/' {
  321. name = "/" + name
  322. }
  323. if _, err := daemon.containerGraph.Set(name, id); err != nil {
  324. if !graphdb.IsNonUniqueNameError(err) {
  325. return "", err
  326. }
  327. conflictingContainer, err := daemon.GetByName(name)
  328. if err != nil {
  329. if strings.Contains(err.Error(), "Could not find entity") {
  330. return "", err
  331. }
  332. // Remove name and continue starting the container
  333. if err := daemon.containerGraph.Delete(name); err != nil {
  334. return "", err
  335. }
  336. } else {
  337. nameAsKnownByUser := strings.TrimPrefix(name, "/")
  338. return "", fmt.Errorf(
  339. "Conflict. The name %q is already in use by container %s. You have to remove (or rename) that container to be able to reuse that name.", nameAsKnownByUser,
  340. stringid.TruncateID(conflictingContainer.ID))
  341. }
  342. }
  343. return name, nil
  344. }
  345. func (daemon *Daemon) generateNewName(id string) (string, error) {
  346. var name string
  347. for i := 0; i < 6; i++ {
  348. name = namesgenerator.GetRandomName(i)
  349. if name[0] != '/' {
  350. name = "/" + name
  351. }
  352. if _, err := daemon.containerGraph.Set(name, id); err != nil {
  353. if !graphdb.IsNonUniqueNameError(err) {
  354. return "", err
  355. }
  356. continue
  357. }
  358. return name, nil
  359. }
  360. name = "/" + stringid.TruncateID(id)
  361. if _, err := daemon.containerGraph.Set(name, id); err != nil {
  362. return "", err
  363. }
  364. return name, nil
  365. }
  366. func (daemon *Daemon) generateHostname(id string, config *runconfig.Config) {
  367. // Generate default hostname
  368. // FIXME: the lxc template no longer needs to set a default hostname
  369. if config.Hostname == "" {
  370. config.Hostname = id[:12]
  371. }
  372. }
  373. func (daemon *Daemon) getEntrypointAndArgs(configEntrypoint *runconfig.Entrypoint, configCmd *runconfig.Command) (string, []string) {
  374. var (
  375. entrypoint string
  376. args []string
  377. )
  378. cmdSlice := configCmd.Slice()
  379. if configEntrypoint.Len() != 0 {
  380. eSlice := configEntrypoint.Slice()
  381. entrypoint = eSlice[0]
  382. args = append(eSlice[1:], cmdSlice...)
  383. } else {
  384. entrypoint = cmdSlice[0]
  385. args = cmdSlice[1:]
  386. }
  387. return entrypoint, args
  388. }
  389. func (daemon *Daemon) newContainer(name string, config *runconfig.Config, imgID string) (*Container, error) {
  390. var (
  391. id string
  392. err error
  393. )
  394. id, name, err = daemon.generateIdAndName(name)
  395. if err != nil {
  396. return nil, err
  397. }
  398. daemon.generateHostname(id, config)
  399. entrypoint, args := daemon.getEntrypointAndArgs(config.Entrypoint, config.Cmd)
  400. base := daemon.newBaseContainer(id)
  401. base.Created = time.Now().UTC()
  402. base.Path = entrypoint
  403. base.Args = args //FIXME: de-duplicate from config
  404. base.Config = config
  405. base.hostConfig = &runconfig.HostConfig{}
  406. base.ImageID = imgID
  407. base.NetworkSettings = &network.Settings{}
  408. base.Name = name
  409. base.Driver = daemon.driver.String()
  410. base.ExecDriver = daemon.execDriver.Name()
  411. return &base, err
  412. }
  413. func GetFullContainerName(name string) (string, error) {
  414. if name == "" {
  415. return "", fmt.Errorf("Container name cannot be empty")
  416. }
  417. if name[0] != '/' {
  418. name = "/" + name
  419. }
  420. return name, nil
  421. }
  422. func (daemon *Daemon) GetByName(name string) (*Container, error) {
  423. fullName, err := GetFullContainerName(name)
  424. if err != nil {
  425. return nil, err
  426. }
  427. entity := daemon.containerGraph.Get(fullName)
  428. if entity == nil {
  429. return nil, fmt.Errorf("Could not find entity for %s", name)
  430. }
  431. e := daemon.containers.Get(entity.ID())
  432. if e == nil {
  433. return nil, fmt.Errorf("Could not find container for entity id %s", entity.ID())
  434. }
  435. return e, nil
  436. }
  437. func (daemon *Daemon) Children(name string) (map[string]*Container, error) {
  438. name, err := GetFullContainerName(name)
  439. if err != nil {
  440. return nil, err
  441. }
  442. children := make(map[string]*Container)
  443. err = daemon.containerGraph.Walk(name, func(p string, e *graphdb.Entity) error {
  444. c, err := daemon.Get(e.ID())
  445. if err != nil {
  446. return err
  447. }
  448. children[p] = c
  449. return nil
  450. }, 0)
  451. if err != nil {
  452. return nil, err
  453. }
  454. return children, nil
  455. }
  456. func (daemon *Daemon) Parents(name string) ([]string, error) {
  457. name, err := GetFullContainerName(name)
  458. if err != nil {
  459. return nil, err
  460. }
  461. return daemon.containerGraph.Parents(name)
  462. }
  463. func (daemon *Daemon) RegisterLink(parent, child *Container, alias string) error {
  464. fullName := filepath.Join(parent.Name, alias)
  465. if !daemon.containerGraph.Exists(fullName) {
  466. _, err := daemon.containerGraph.Set(fullName, child.ID)
  467. return err
  468. }
  469. return nil
  470. }
  471. func NewDaemon(config *Config, registryService *registry.Service) (daemon *Daemon, err error) {
  472. setDefaultMtu(config)
  473. // Ensure we have compatible configuration options
  474. if err := checkConfigOptions(config); err != nil {
  475. return nil, err
  476. }
  477. // Do we have a disabled network?
  478. config.DisableBridge = isBridgeNetworkDisabled(config)
  479. // Verify the platform is supported as a daemon
  480. if !platformSupported {
  481. return nil, ErrSystemNotSupported
  482. }
  483. // Validate platform-specific requirements
  484. if err := checkSystem(); err != nil {
  485. return nil, err
  486. }
  487. // set up SIGUSR1 handler on Unix-like systems, or a Win32 global event
  488. // on Windows to dump Go routine stacks
  489. setupDumpStackTrap()
  490. // get the canonical path to the Docker root directory
  491. var realRoot string
  492. if _, err := os.Stat(config.Root); err != nil && os.IsNotExist(err) {
  493. realRoot = config.Root
  494. } else {
  495. realRoot, err = fileutils.ReadSymlinkedDirectory(config.Root)
  496. if err != nil {
  497. return nil, fmt.Errorf("Unable to get the full path to root (%s): %s", config.Root, err)
  498. }
  499. }
  500. config.Root = realRoot
  501. // Create the root directory if it doesn't exists
  502. if err := system.MkdirAll(config.Root, 0700); err != nil {
  503. return nil, err
  504. }
  505. // set up the tmpDir to use a canonical path
  506. tmp, err := tempDir(config.Root)
  507. if err != nil {
  508. return nil, fmt.Errorf("Unable to get the TempDir under %s: %s", config.Root, err)
  509. }
  510. realTmp, err := fileutils.ReadSymlinkedDirectory(tmp)
  511. if err != nil {
  512. return nil, fmt.Errorf("Unable to get the full path to the TempDir (%s): %s", tmp, err)
  513. }
  514. os.Setenv("TMPDIR", realTmp)
  515. // Set the default driver
  516. graphdriver.DefaultDriver = config.GraphDriver
  517. // Load storage driver
  518. driver, err := graphdriver.New(config.Root, config.GraphOptions)
  519. if err != nil {
  520. return nil, fmt.Errorf("error initializing graphdriver: %v", err)
  521. }
  522. logrus.Debugf("Using graph driver %s", driver)
  523. d := &Daemon{}
  524. d.driver = driver
  525. // Ensure the graph driver is shutdown at a later point
  526. defer func() {
  527. if err != nil {
  528. if err := d.Shutdown(); err != nil {
  529. logrus.Error(err)
  530. }
  531. }
  532. }()
  533. // Verify logging driver type
  534. if config.LogConfig.Type != "none" {
  535. if _, err := logger.GetLogDriver(config.LogConfig.Type); err != nil {
  536. return nil, fmt.Errorf("error finding the logging driver: %v", err)
  537. }
  538. }
  539. logrus.Debugf("Using default logging driver %s", config.LogConfig.Type)
  540. // Configure and validate the kernels security support
  541. if err := configureKernelSecuritySupport(config, d.driver.String()); err != nil {
  542. return nil, err
  543. }
  544. daemonRepo := filepath.Join(config.Root, "containers")
  545. if err := system.MkdirAll(daemonRepo, 0700); err != nil {
  546. return nil, err
  547. }
  548. // Migrate the container if it is aufs and aufs is enabled
  549. if err := migrateIfDownlevel(d.driver, config.Root); err != nil {
  550. return nil, err
  551. }
  552. logrus.Debug("Creating images graph")
  553. g, err := graph.NewGraph(filepath.Join(config.Root, "graph"), d.driver)
  554. if err != nil {
  555. return nil, err
  556. }
  557. // Configure the volumes driver
  558. if err := configureVolumes(config); err != nil {
  559. return nil, err
  560. }
  561. trustKey, err := api.LoadOrCreateTrustKey(config.TrustKeyPath)
  562. if err != nil {
  563. return nil, err
  564. }
  565. trustDir := filepath.Join(config.Root, "trust")
  566. if err := system.MkdirAll(trustDir, 0700); err != nil {
  567. return nil, err
  568. }
  569. trustService, err := trust.NewTrustStore(trustDir)
  570. if err != nil {
  571. return nil, fmt.Errorf("could not create trust store: %s", err)
  572. }
  573. eventsService := events.New()
  574. logrus.Debug("Creating repository list")
  575. tagCfg := &graph.TagStoreConfig{
  576. Graph: g,
  577. Key: trustKey,
  578. Registry: registryService,
  579. Events: eventsService,
  580. Trust: trustService,
  581. }
  582. repositories, err := graph.NewTagStore(filepath.Join(config.Root, "repositories-"+d.driver.String()), tagCfg)
  583. if err != nil {
  584. return nil, fmt.Errorf("Couldn't create Tag store repositories-%s: %s", d.driver.String(), err)
  585. }
  586. if restorer, ok := d.driver.(graphdriver.ImageRestorer); ok {
  587. if _, err := restorer.RestoreCustomImages(repositories, g); err != nil {
  588. return nil, fmt.Errorf("Couldn't restore custom images: %s", err)
  589. }
  590. }
  591. d.netController, err = initNetworkController(config)
  592. if err != nil {
  593. return nil, fmt.Errorf("Error initializing network controller: %v", err)
  594. }
  595. graphdbPath := filepath.Join(config.Root, "linkgraph.db")
  596. graph, err := graphdb.NewSqliteConn(graphdbPath)
  597. if err != nil {
  598. return nil, err
  599. }
  600. d.containerGraph = graph
  601. var sysInitPath string
  602. if config.ExecDriver == "lxc" {
  603. initPath, err := configureSysInit(config)
  604. if err != nil {
  605. return nil, err
  606. }
  607. sysInitPath = initPath
  608. }
  609. sysInfo := sysinfo.New(false)
  610. // Check if Devices cgroup is mounted, it is hard requirement for container security,
  611. // on Linux/FreeBSD.
  612. if runtime.GOOS != "windows" && !sysInfo.CgroupDevicesEnabled {
  613. return nil, fmt.Errorf("Devices cgroup isn't mounted")
  614. }
  615. ed, err := execdrivers.NewDriver(config.ExecDriver, config.ExecOptions, config.ExecRoot, config.Root, sysInitPath, sysInfo)
  616. if err != nil {
  617. return nil, err
  618. }
  619. d.ID = trustKey.PublicKey().KeyID()
  620. d.repository = daemonRepo
  621. d.containers = &contStore{s: make(map[string]*Container)}
  622. d.execCommands = newExecStore()
  623. d.graph = g
  624. d.repositories = repositories
  625. d.idIndex = truncindex.NewTruncIndex([]string{})
  626. d.config = config
  627. d.sysInitPath = sysInitPath
  628. d.execDriver = ed
  629. d.statsCollector = newStatsCollector(1 * time.Second)
  630. d.defaultLogConfig = config.LogConfig
  631. d.RegistryService = registryService
  632. d.EventsService = eventsService
  633. d.root = config.Root
  634. go d.execCommandGC()
  635. if err := d.restore(); err != nil {
  636. return nil, err
  637. }
  638. return d, nil
  639. }
  640. func (daemon *Daemon) Shutdown() error {
  641. if daemon.containers != nil {
  642. group := sync.WaitGroup{}
  643. logrus.Debug("starting clean shutdown of all containers...")
  644. for _, container := range daemon.List() {
  645. c := container
  646. if c.IsRunning() {
  647. logrus.Debugf("stopping %s", c.ID)
  648. group.Add(1)
  649. go func() {
  650. defer group.Done()
  651. // If container failed to exit in 10 seconds of SIGTERM, then using the force
  652. if err := c.Stop(10); err != nil {
  653. logrus.Errorf("Stop container %s with error: %v", c.ID, err)
  654. }
  655. c.WaitStop(-1 * time.Second)
  656. logrus.Debugf("container stopped %s", c.ID)
  657. }()
  658. }
  659. }
  660. group.Wait()
  661. // trigger libnetwork GC only if it's initialized
  662. if daemon.netController != nil {
  663. daemon.netController.GC()
  664. }
  665. }
  666. if daemon.containerGraph != nil {
  667. if err := daemon.containerGraph.Close(); err != nil {
  668. logrus.Errorf("Error during container graph.Close(): %v", err)
  669. }
  670. }
  671. if daemon.driver != nil {
  672. if err := daemon.driver.Cleanup(); err != nil {
  673. logrus.Errorf("Error during graph storage driver.Cleanup(): %v", err)
  674. }
  675. }
  676. return nil
  677. }
  678. func (daemon *Daemon) Mount(container *Container) error {
  679. dir, err := daemon.driver.Get(container.ID, container.GetMountLabel())
  680. if err != nil {
  681. return fmt.Errorf("Error getting container %s from driver %s: %s", container.ID, daemon.driver, err)
  682. }
  683. if container.basefs != dir {
  684. // The mount path reported by the graph driver should always be trusted on Windows, since the
  685. // volume path for a given mounted layer may change over time. This should only be an error
  686. // on non-Windows operating systems.
  687. if container.basefs != "" && runtime.GOOS != "windows" {
  688. daemon.driver.Put(container.ID)
  689. return fmt.Errorf("Error: driver %s is returning inconsistent paths for container %s ('%s' then '%s')",
  690. daemon.driver, container.ID, container.basefs, dir)
  691. }
  692. }
  693. container.basefs = dir
  694. return nil
  695. }
  696. func (daemon *Daemon) Unmount(container *Container) error {
  697. daemon.driver.Put(container.ID)
  698. return nil
  699. }
  700. func (daemon *Daemon) Run(c *Container, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (execdriver.ExitStatus, error) {
  701. return daemon.execDriver.Run(c.command, pipes, startCallback)
  702. }
  703. func (daemon *Daemon) Kill(c *Container, sig int) error {
  704. return daemon.execDriver.Kill(c.command, sig)
  705. }
  706. func (daemon *Daemon) Stats(c *Container) (*execdriver.ResourceStats, error) {
  707. return daemon.execDriver.Stats(c.ID)
  708. }
  709. func (daemon *Daemon) SubscribeToContainerStats(name string) (chan interface{}, error) {
  710. c, err := daemon.Get(name)
  711. if err != nil {
  712. return nil, err
  713. }
  714. ch := daemon.statsCollector.collect(c)
  715. return ch, nil
  716. }
  717. func (daemon *Daemon) UnsubscribeToContainerStats(name string, ch chan interface{}) error {
  718. c, err := daemon.Get(name)
  719. if err != nil {
  720. return err
  721. }
  722. daemon.statsCollector.unsubscribe(c, ch)
  723. return nil
  724. }
  725. func (daemon *Daemon) Changes(container *Container) ([]archive.Change, error) {
  726. initID := fmt.Sprintf("%s-init", container.ID)
  727. return daemon.driver.Changes(container.ID, initID)
  728. }
  729. func (daemon *Daemon) Diff(container *Container) (archive.Archive, error) {
  730. initID := fmt.Sprintf("%s-init", container.ID)
  731. return daemon.driver.Diff(container.ID, initID)
  732. }
  733. func (daemon *Daemon) createRootfs(container *Container) error {
  734. // Step 1: create the container directory.
  735. // This doubles as a barrier to avoid race conditions.
  736. if err := os.Mkdir(container.root, 0700); err != nil {
  737. return err
  738. }
  739. initID := fmt.Sprintf("%s-init", container.ID)
  740. if err := daemon.driver.Create(initID, container.ImageID); err != nil {
  741. return err
  742. }
  743. initPath, err := daemon.driver.Get(initID, "")
  744. if err != nil {
  745. return err
  746. }
  747. if err := setupInitLayer(initPath); err != nil {
  748. daemon.driver.Put(initID)
  749. return err
  750. }
  751. // We want to unmount init layer before we take snapshot of it
  752. // for the actual container.
  753. daemon.driver.Put(initID)
  754. if err := daemon.driver.Create(container.ID, initID); err != nil {
  755. return err
  756. }
  757. return nil
  758. }
  759. // FIXME: this is a convenience function for integration tests
  760. // which need direct access to daemon.graph.
  761. // Once the tests switch to using engine and jobs, this method
  762. // can go away.
  763. func (daemon *Daemon) Graph() *graph.Graph {
  764. return daemon.graph
  765. }
  766. func (daemon *Daemon) Repositories() *graph.TagStore {
  767. return daemon.repositories
  768. }
  769. func (daemon *Daemon) Config() *Config {
  770. return daemon.config
  771. }
  772. func (daemon *Daemon) SystemInitPath() string {
  773. return daemon.sysInitPath
  774. }
  775. func (daemon *Daemon) GraphDriver() graphdriver.Driver {
  776. return daemon.driver
  777. }
  778. func (daemon *Daemon) ExecutionDriver() execdriver.Driver {
  779. return daemon.execDriver
  780. }
  781. func (daemon *Daemon) ContainerGraph() *graphdb.Database {
  782. return daemon.containerGraph
  783. }
  784. func (daemon *Daemon) ImageGetCached(imgID string, config *runconfig.Config) (*image.Image, error) {
  785. // Retrieve all images
  786. images := daemon.Graph().Map()
  787. // Store the tree in a map of map (map[parentId][childId])
  788. imageMap := make(map[string]map[string]struct{})
  789. for _, img := range images {
  790. if _, exists := imageMap[img.Parent]; !exists {
  791. imageMap[img.Parent] = make(map[string]struct{})
  792. }
  793. imageMap[img.Parent][img.ID] = struct{}{}
  794. }
  795. // Loop on the children of the given image and check the config
  796. var match *image.Image
  797. for elem := range imageMap[imgID] {
  798. img, ok := images[elem]
  799. if !ok {
  800. return nil, fmt.Errorf("unable to find image %q", elem)
  801. }
  802. if runconfig.Compare(&img.ContainerConfig, config) {
  803. if match == nil || match.Created.Before(img.Created) {
  804. match = img
  805. }
  806. }
  807. }
  808. return match, nil
  809. }
  810. // tempDir returns the default directory to use for temporary files.
  811. func tempDir(rootDir string) (string, error) {
  812. var tmpDir string
  813. if tmpDir = os.Getenv("DOCKER_TMPDIR"); tmpDir == "" {
  814. tmpDir = filepath.Join(rootDir, "tmp")
  815. }
  816. return tmpDir, system.MkdirAll(tmpDir, 0700)
  817. }
  818. func (daemon *Daemon) setHostConfig(container *Container, hostConfig *runconfig.HostConfig) error {
  819. container.Lock()
  820. if err := parseSecurityOpt(container, hostConfig); err != nil {
  821. container.Unlock()
  822. return err
  823. }
  824. container.Unlock()
  825. // Do not lock while creating volumes since this could be calling out to external plugins
  826. // Don't want to block other actions, like `docker ps` because we're waiting on an external plugin
  827. if err := daemon.registerMountPoints(container, hostConfig); err != nil {
  828. return err
  829. }
  830. container.Lock()
  831. defer container.Unlock()
  832. // Register any links from the host config before starting the container
  833. if err := daemon.RegisterLinks(container, hostConfig); err != nil {
  834. return err
  835. }
  836. container.hostConfig = hostConfig
  837. container.toDisk()
  838. return nil
  839. }
  840. func setDefaultMtu(config *Config) {
  841. // do nothing if the config does not have the default 0 value.
  842. if config.Mtu != 0 {
  843. return
  844. }
  845. config.Mtu = defaultNetworkMtu
  846. if routeMtu, err := getDefaultRouteMtu(); err == nil {
  847. config.Mtu = routeMtu
  848. }
  849. }
  850. var errNoDefaultRoute = errors.New("no default route was found")
  851. // getDefaultRouteMtu returns the MTU for the default route's interface.
  852. func getDefaultRouteMtu() (int, error) {
  853. routes, err := netlink.NetworkGetRoutes()
  854. if err != nil {
  855. return 0, err
  856. }
  857. for _, r := range routes {
  858. if r.Default && r.Iface != nil {
  859. return r.Iface.MTU, nil
  860. }
  861. }
  862. return 0, errNoDefaultRoute
  863. }
  864. // verifyContainerSettings performs validation of the hostconfig and config
  865. // structures.
  866. func (daemon *Daemon) verifyContainerSettings(hostConfig *runconfig.HostConfig, config *runconfig.Config) ([]string, error) {
  867. // First perform verification of settings common across all platforms.
  868. if config != nil {
  869. if config.WorkingDir != "" && !filepath.IsAbs(config.WorkingDir) {
  870. return nil, fmt.Errorf("The working directory '%s' is invalid. It needs to be an absolute path.", config.WorkingDir)
  871. }
  872. }
  873. if hostConfig == nil {
  874. return nil, nil
  875. }
  876. for port := range hostConfig.PortBindings {
  877. _, portStr := nat.SplitProtoPort(string(port))
  878. if _, err := nat.ParsePort(portStr); err != nil {
  879. return nil, fmt.Errorf("Invalid port specification: %q", portStr)
  880. }
  881. for _, pb := range hostConfig.PortBindings[port] {
  882. _, err := nat.NewPort(nat.SplitProtoPort(pb.HostPort))
  883. if err != nil {
  884. return nil, fmt.Errorf("Invalid port specification: %q", pb.HostPort)
  885. }
  886. }
  887. }
  888. // Now do platform-specific verification
  889. return verifyPlatformContainerSettings(daemon, hostConfig, config)
  890. }