container.go 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230
  1. package daemon
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "os"
  9. "path/filepath"
  10. "strings"
  11. "sync"
  12. "syscall"
  13. "time"
  14. "github.com/opencontainers/runc/libcontainer/label"
  15. "github.com/Sirupsen/logrus"
  16. "github.com/docker/docker/daemon/execdriver"
  17. "github.com/docker/docker/daemon/logger"
  18. "github.com/docker/docker/daemon/logger/jsonfilelog"
  19. "github.com/docker/docker/daemon/network"
  20. derr "github.com/docker/docker/errors"
  21. "github.com/docker/docker/image"
  22. "github.com/docker/docker/pkg/archive"
  23. "github.com/docker/docker/pkg/broadcaster"
  24. "github.com/docker/docker/pkg/fileutils"
  25. "github.com/docker/docker/pkg/ioutils"
  26. "github.com/docker/docker/pkg/mount"
  27. "github.com/docker/docker/pkg/nat"
  28. "github.com/docker/docker/pkg/promise"
  29. "github.com/docker/docker/pkg/signal"
  30. "github.com/docker/docker/pkg/symlink"
  31. "github.com/docker/docker/pkg/system"
  32. "github.com/docker/docker/runconfig"
  33. "github.com/docker/docker/volume"
  34. "github.com/docker/docker/volume/store"
  35. )
  36. var (
  37. // ErrRootFSReadOnly is returned when a container
  38. // rootfs is marked readonly.
  39. ErrRootFSReadOnly = errors.New("container rootfs is marked read-only")
  40. )
  41. type streamConfig struct {
  42. stdout *broadcaster.Unbuffered
  43. stderr *broadcaster.Unbuffered
  44. stdin io.ReadCloser
  45. stdinPipe io.WriteCloser
  46. }
  47. // CommonContainer holds the fields for a container which are
  48. // applicable across all platforms supported by the daemon.
  49. type CommonContainer struct {
  50. streamConfig
  51. // embed for Container to support states directly.
  52. *State `json:"State"` // Needed for remote api version <= 1.11
  53. root string // Path to the "home" of the container, including metadata.
  54. basefs string // Path to the graphdriver mountpoint
  55. ID string
  56. Created time.Time
  57. Path string
  58. Args []string
  59. Config *runconfig.Config
  60. ImageID string `json:"Image"`
  61. NetworkSettings *network.Settings
  62. LogPath string
  63. Name string
  64. Driver string
  65. ExecDriver string
  66. // MountLabel contains the options for the 'mount' command
  67. MountLabel string
  68. ProcessLabel string
  69. RestartCount int
  70. HasBeenStartedBefore bool
  71. HasBeenManuallyStopped bool // used for unless-stopped restart policy
  72. MountPoints map[string]*volume.MountPoint
  73. hostConfig *runconfig.HostConfig
  74. command *execdriver.Command
  75. monitor *containerMonitor
  76. execCommands *execStore
  77. daemon *Daemon
  78. // logDriver for closing
  79. logDriver logger.Logger
  80. logCopier *logger.Copier
  81. }
  82. func (container *Container) fromDisk() error {
  83. pth, err := container.jsonPath()
  84. if err != nil {
  85. return err
  86. }
  87. jsonSource, err := os.Open(pth)
  88. if err != nil {
  89. return err
  90. }
  91. defer jsonSource.Close()
  92. dec := json.NewDecoder(jsonSource)
  93. // Load container settings
  94. if err := dec.Decode(container); err != nil {
  95. return err
  96. }
  97. if err := label.ReserveLabel(container.ProcessLabel); err != nil {
  98. return err
  99. }
  100. return container.readHostConfig()
  101. }
  102. func (container *Container) toDisk() error {
  103. data, err := json.Marshal(container)
  104. if err != nil {
  105. return err
  106. }
  107. pth, err := container.jsonPath()
  108. if err != nil {
  109. return err
  110. }
  111. if err := ioutil.WriteFile(pth, data, 0666); err != nil {
  112. return err
  113. }
  114. return container.writeHostConfig()
  115. }
  116. func (container *Container) toDiskLocking() error {
  117. container.Lock()
  118. err := container.toDisk()
  119. container.Unlock()
  120. return err
  121. }
  122. func (container *Container) readHostConfig() error {
  123. container.hostConfig = &runconfig.HostConfig{}
  124. // If the hostconfig file does not exist, do not read it.
  125. // (We still have to initialize container.hostConfig,
  126. // but that's OK, since we just did that above.)
  127. pth, err := container.hostConfigPath()
  128. if err != nil {
  129. return err
  130. }
  131. _, err = os.Stat(pth)
  132. if os.IsNotExist(err) {
  133. return nil
  134. }
  135. f, err := os.Open(pth)
  136. if err != nil {
  137. return err
  138. }
  139. defer f.Close()
  140. return json.NewDecoder(f).Decode(&container.hostConfig)
  141. }
  142. func (container *Container) writeHostConfig() error {
  143. data, err := json.Marshal(container.hostConfig)
  144. if err != nil {
  145. return err
  146. }
  147. pth, err := container.hostConfigPath()
  148. if err != nil {
  149. return err
  150. }
  151. return ioutil.WriteFile(pth, data, 0666)
  152. }
  153. func (container *Container) logEvent(action string) {
  154. d := container.daemon
  155. d.EventsService.Log(
  156. action,
  157. container.ID,
  158. container.Config.Image,
  159. )
  160. }
  161. // GetResourcePath evaluates `path` in the scope of the container's basefs, with proper path
  162. // sanitisation. Symlinks are all scoped to the basefs of the container, as
  163. // though the container's basefs was `/`.
  164. //
  165. // The basefs of a container is the host-facing path which is bind-mounted as
  166. // `/` inside the container. This method is essentially used to access a
  167. // particular path inside the container as though you were a process in that
  168. // container.
  169. //
  170. // NOTE: The returned path is *only* safely scoped inside the container's basefs
  171. // if no component of the returned path changes (such as a component
  172. // symlinking to a different path) between using this method and using the
  173. // path. See symlink.FollowSymlinkInScope for more details.
  174. func (container *Container) GetResourcePath(path string) (string, error) {
  175. // IMPORTANT - These are paths on the OS where the daemon is running, hence
  176. // any filepath operations must be done in an OS agnostic way.
  177. cleanPath := filepath.Join(string(os.PathSeparator), path)
  178. r, e := symlink.FollowSymlinkInScope(filepath.Join(container.basefs, cleanPath), container.basefs)
  179. return r, e
  180. }
  181. // Evaluates `path` in the scope of the container's root, with proper path
  182. // sanitisation. Symlinks are all scoped to the root of the container, as
  183. // though the container's root was `/`.
  184. //
  185. // The root of a container is the host-facing configuration metadata directory.
  186. // Only use this method to safely access the container's `container.json` or
  187. // other metadata files. If in doubt, use container.GetResourcePath.
  188. //
  189. // NOTE: The returned path is *only* safely scoped inside the container's root
  190. // if no component of the returned path changes (such as a component
  191. // symlinking to a different path) between using this method and using the
  192. // path. See symlink.FollowSymlinkInScope for more details.
  193. func (container *Container) getRootResourcePath(path string) (string, error) {
  194. // IMPORTANT - These are paths on the OS where the daemon is running, hence
  195. // any filepath operations must be done in an OS agnostic way.
  196. cleanPath := filepath.Join(string(os.PathSeparator), path)
  197. return symlink.FollowSymlinkInScope(filepath.Join(container.root, cleanPath), container.root)
  198. }
  199. func (container *Container) exportContainerRw() (archive.Archive, error) {
  200. if container.daemon == nil {
  201. return nil, derr.ErrorCodeUnregisteredContainer.WithArgs(container.ID)
  202. }
  203. archive, err := container.daemon.diff(container)
  204. if err != nil {
  205. return nil, err
  206. }
  207. return ioutils.NewReadCloserWrapper(archive, func() error {
  208. err := archive.Close()
  209. return err
  210. }),
  211. nil
  212. }
  213. // Start prepares the container to run by setting up everything the
  214. // container needs, such as storage and networking, as well as links
  215. // between containers. The container is left waiting for a signal to
  216. // begin running.
  217. func (container *Container) Start() (err error) {
  218. container.Lock()
  219. defer container.Unlock()
  220. if container.Running {
  221. return nil
  222. }
  223. if container.removalInProgress || container.Dead {
  224. return derr.ErrorCodeContainerBeingRemoved
  225. }
  226. // if we encounter an error during start we need to ensure that any other
  227. // setup has been cleaned up properly
  228. defer func() {
  229. if err != nil {
  230. container.setError(err)
  231. // if no one else has set it, make sure we don't leave it at zero
  232. if container.ExitCode == 0 {
  233. container.ExitCode = 128
  234. }
  235. container.toDisk()
  236. container.cleanup()
  237. container.logEvent("die")
  238. }
  239. }()
  240. if err := container.Mount(); err != nil {
  241. return err
  242. }
  243. // Make sure NetworkMode has an acceptable value. We do this to ensure
  244. // backwards API compatibility.
  245. container.hostConfig = runconfig.SetDefaultNetModeIfBlank(container.hostConfig)
  246. if err := container.initializeNetworking(); err != nil {
  247. return err
  248. }
  249. linkedEnv, err := container.setupLinkedContainers()
  250. if err != nil {
  251. return err
  252. }
  253. if err := container.setupWorkingDirectory(); err != nil {
  254. return err
  255. }
  256. env := container.createDaemonEnvironment(linkedEnv)
  257. if err := populateCommand(container, env); err != nil {
  258. return err
  259. }
  260. if !container.hostConfig.IpcMode.IsContainer() && !container.hostConfig.IpcMode.IsHost() {
  261. if err := container.setupIpcDirs(); err != nil {
  262. return err
  263. }
  264. }
  265. mounts, err := container.setupMounts()
  266. if err != nil {
  267. return err
  268. }
  269. mounts = append(mounts, container.ipcMounts()...)
  270. container.command.Mounts = mounts
  271. return container.waitForStart()
  272. }
  273. // streamConfig.StdinPipe returns a WriteCloser which can be used to feed data
  274. // to the standard input of the container's active process.
  275. // Container.StdoutPipe and Container.StderrPipe each return a ReadCloser
  276. // which can be used to retrieve the standard output (and error) generated
  277. // by the container's active process. The output (and error) are actually
  278. // copied and delivered to all StdoutPipe and StderrPipe consumers, using
  279. // a kind of "broadcaster".
  280. func (streamConfig *streamConfig) StdinPipe() io.WriteCloser {
  281. return streamConfig.stdinPipe
  282. }
  283. func (streamConfig *streamConfig) StdoutPipe() io.ReadCloser {
  284. reader, writer := io.Pipe()
  285. streamConfig.stdout.Add(writer)
  286. return ioutils.NewBufReader(reader)
  287. }
  288. func (streamConfig *streamConfig) StderrPipe() io.ReadCloser {
  289. reader, writer := io.Pipe()
  290. streamConfig.stderr.Add(writer)
  291. return ioutils.NewBufReader(reader)
  292. }
  293. func (container *Container) isNetworkAllocated() bool {
  294. return container.NetworkSettings.IPAddress != ""
  295. }
  296. // cleanup releases any network resources allocated to the container along with any rules
  297. // around how containers are linked together. It also unmounts the container's root filesystem.
  298. func (container *Container) cleanup() {
  299. container.releaseNetwork()
  300. if err := container.unmountIpcMounts(); err != nil {
  301. logrus.Errorf("%s: Failed to umount ipc filesystems: %v", container.ID, err)
  302. }
  303. if err := container.Unmount(); err != nil {
  304. logrus.Errorf("%s: Failed to umount filesystem: %v", container.ID, err)
  305. }
  306. for _, eConfig := range container.execCommands.s {
  307. container.daemon.unregisterExecCommand(eConfig)
  308. }
  309. container.unmountVolumes(false)
  310. }
  311. // killSig sends the container the given signal. This wrapper for the
  312. // host specific kill command prepares the container before attempting
  313. // to send the signal. An error is returned if the container is paused
  314. // or not running, or if there is a problem returned from the
  315. // underlying kill command.
  316. func (container *Container) killSig(sig int) error {
  317. logrus.Debugf("Sending %d to %s", sig, container.ID)
  318. container.Lock()
  319. defer container.Unlock()
  320. // We could unpause the container for them rather than returning this error
  321. if container.Paused {
  322. return derr.ErrorCodeUnpauseContainer.WithArgs(container.ID)
  323. }
  324. if !container.Running {
  325. return derr.ErrorCodeNotRunning.WithArgs(container.ID)
  326. }
  327. // signal to the monitor that it should not restart the container
  328. // after we send the kill signal
  329. container.monitor.ExitOnNext()
  330. // if the container is currently restarting we do not need to send the signal
  331. // to the process. Telling the monitor that it should exit on it's next event
  332. // loop is enough
  333. if container.Restarting {
  334. return nil
  335. }
  336. if err := container.daemon.kill(container, sig); err != nil {
  337. return err
  338. }
  339. container.logEvent("kill")
  340. return nil
  341. }
  342. // Wrapper aroung killSig() suppressing "no such process" error.
  343. func (container *Container) killPossiblyDeadProcess(sig int) error {
  344. err := container.killSig(sig)
  345. if err == syscall.ESRCH {
  346. logrus.Debugf("Cannot kill process (pid=%d) with signal %d: no such process.", container.getPID(), sig)
  347. return nil
  348. }
  349. return err
  350. }
  351. func (container *Container) pause() error {
  352. container.Lock()
  353. defer container.Unlock()
  354. // We cannot Pause the container which is not running
  355. if !container.Running {
  356. return derr.ErrorCodeNotRunning.WithArgs(container.ID)
  357. }
  358. // We cannot Pause the container which is already paused
  359. if container.Paused {
  360. return derr.ErrorCodeAlreadyPaused.WithArgs(container.ID)
  361. }
  362. if err := container.daemon.execDriver.Pause(container.command); err != nil {
  363. return err
  364. }
  365. container.Paused = true
  366. container.logEvent("pause")
  367. return nil
  368. }
  369. func (container *Container) unpause() error {
  370. container.Lock()
  371. defer container.Unlock()
  372. // We cannot unpause the container which is not running
  373. if !container.Running {
  374. return derr.ErrorCodeNotRunning.WithArgs(container.ID)
  375. }
  376. // We cannot unpause the container which is not paused
  377. if !container.Paused {
  378. return derr.ErrorCodeNotPaused.WithArgs(container.ID)
  379. }
  380. if err := container.daemon.execDriver.Unpause(container.command); err != nil {
  381. return err
  382. }
  383. container.Paused = false
  384. container.logEvent("unpause")
  385. return nil
  386. }
  387. // Kill forcefully terminates a container.
  388. func (container *Container) Kill() error {
  389. if !container.IsRunning() {
  390. return derr.ErrorCodeNotRunning.WithArgs(container.ID)
  391. }
  392. // 1. Send SIGKILL
  393. if err := container.killPossiblyDeadProcess(int(syscall.SIGKILL)); err != nil {
  394. // While normally we might "return err" here we're not going to
  395. // because if we can't stop the container by this point then
  396. // its probably because its already stopped. Meaning, between
  397. // the time of the IsRunning() call above and now it stopped.
  398. // Also, since the err return will be exec driver specific we can't
  399. // look for any particular (common) error that would indicate
  400. // that the process is already dead vs something else going wrong.
  401. // So, instead we'll give it up to 2 more seconds to complete and if
  402. // by that time the container is still running, then the error
  403. // we got is probably valid and so we return it to the caller.
  404. if container.IsRunning() {
  405. container.WaitStop(2 * time.Second)
  406. if container.IsRunning() {
  407. return err
  408. }
  409. }
  410. }
  411. // 2. Wait for the process to die, in last resort, try to kill the process directly
  412. if err := killProcessDirectly(container); err != nil {
  413. return err
  414. }
  415. container.WaitStop(-1 * time.Second)
  416. return nil
  417. }
  418. // Stop halts a container by sending a stop signal, waiting for the given
  419. // duration in seconds, and then calling SIGKILL and waiting for the
  420. // process to exit. If a negative duration is given, Stop will wait
  421. // for the initial signal forever. If the container is not running Stop returns
  422. // immediately.
  423. func (container *Container) Stop(seconds int) error {
  424. if !container.IsRunning() {
  425. return nil
  426. }
  427. // 1. Send a SIGTERM
  428. if err := container.killPossiblyDeadProcess(container.stopSignal()); err != nil {
  429. logrus.Infof("Failed to send SIGTERM to the process, force killing")
  430. if err := container.killPossiblyDeadProcess(9); err != nil {
  431. return err
  432. }
  433. }
  434. // 2. Wait for the process to exit on its own
  435. if _, err := container.WaitStop(time.Duration(seconds) * time.Second); err != nil {
  436. logrus.Infof("Container %v failed to exit within %d seconds of SIGTERM - using the force", container.ID, seconds)
  437. // 3. If it doesn't, then send SIGKILL
  438. if err := container.Kill(); err != nil {
  439. container.WaitStop(-1 * time.Second)
  440. return err
  441. }
  442. }
  443. container.logEvent("stop")
  444. return nil
  445. }
  446. // Restart attempts to gracefully stop and then start the
  447. // container. When stopping, wait for the given duration in seconds to
  448. // gracefully stop, before forcefully terminating the container. If
  449. // given a negative duration, wait forever for a graceful stop.
  450. func (container *Container) Restart(seconds int) error {
  451. // Avoid unnecessarily unmounting and then directly mounting
  452. // the container when the container stops and then starts
  453. // again
  454. if err := container.Mount(); err == nil {
  455. defer container.Unmount()
  456. }
  457. if err := container.Stop(seconds); err != nil {
  458. return err
  459. }
  460. if err := container.Start(); err != nil {
  461. return err
  462. }
  463. container.logEvent("restart")
  464. return nil
  465. }
  466. // Resize changes the TTY of the process running inside the container
  467. // to the given height and width. The container must be running.
  468. func (container *Container) Resize(h, w int) error {
  469. if !container.IsRunning() {
  470. return derr.ErrorCodeNotRunning.WithArgs(container.ID)
  471. }
  472. if err := container.command.ProcessConfig.Terminal.Resize(h, w); err != nil {
  473. return err
  474. }
  475. container.logEvent("resize")
  476. return nil
  477. }
  478. func (container *Container) export() (archive.Archive, error) {
  479. if err := container.Mount(); err != nil {
  480. return nil, err
  481. }
  482. uidMaps, gidMaps := container.daemon.GetUIDGIDMaps()
  483. archive, err := archive.TarWithOptions(container.basefs, &archive.TarOptions{
  484. Compression: archive.Uncompressed,
  485. UIDMaps: uidMaps,
  486. GIDMaps: gidMaps,
  487. })
  488. if err != nil {
  489. container.Unmount()
  490. return nil, err
  491. }
  492. arch := ioutils.NewReadCloserWrapper(archive, func() error {
  493. err := archive.Close()
  494. container.Unmount()
  495. return err
  496. })
  497. container.logEvent("export")
  498. return arch, err
  499. }
  500. // Mount sets container.basefs
  501. func (container *Container) Mount() error {
  502. return container.daemon.Mount(container)
  503. }
  504. func (container *Container) changes() ([]archive.Change, error) {
  505. container.Lock()
  506. defer container.Unlock()
  507. return container.daemon.changes(container)
  508. }
  509. func (container *Container) getImage() (*image.Image, error) {
  510. if container.daemon == nil {
  511. return nil, derr.ErrorCodeImageUnregContainer
  512. }
  513. return container.daemon.graph.Get(container.ImageID)
  514. }
  515. // Unmount asks the daemon to release the layered filesystems that are
  516. // mounted by the container.
  517. func (container *Container) Unmount() error {
  518. return container.daemon.unmount(container)
  519. }
  520. func (container *Container) hostConfigPath() (string, error) {
  521. return container.getRootResourcePath("hostconfig.json")
  522. }
  523. func (container *Container) jsonPath() (string, error) {
  524. return container.getRootResourcePath("config.json")
  525. }
  526. // This method must be exported to be used from the lxc template
  527. // This directory is only usable when the container is running
  528. func (container *Container) rootfsPath() string {
  529. return container.basefs
  530. }
  531. func validateID(id string) error {
  532. if id == "" {
  533. return derr.ErrorCodeEmptyID
  534. }
  535. return nil
  536. }
  537. func (container *Container) copy(resource string) (rc io.ReadCloser, err error) {
  538. container.Lock()
  539. defer func() {
  540. if err != nil {
  541. // Wait to unlock the container until the archive is fully read
  542. // (see the ReadCloseWrapper func below) or if there is an error
  543. // before that occurs.
  544. container.Unlock()
  545. }
  546. }()
  547. if err := container.Mount(); err != nil {
  548. return nil, err
  549. }
  550. defer func() {
  551. if err != nil {
  552. // unmount any volumes
  553. container.unmountVolumes(true)
  554. // unmount the container's rootfs
  555. container.Unmount()
  556. }
  557. }()
  558. if err := container.mountVolumes(); err != nil {
  559. return nil, err
  560. }
  561. basePath, err := container.GetResourcePath(resource)
  562. if err != nil {
  563. return nil, err
  564. }
  565. stat, err := os.Stat(basePath)
  566. if err != nil {
  567. return nil, err
  568. }
  569. var filter []string
  570. if !stat.IsDir() {
  571. d, f := filepath.Split(basePath)
  572. basePath = d
  573. filter = []string{f}
  574. } else {
  575. filter = []string{filepath.Base(basePath)}
  576. basePath = filepath.Dir(basePath)
  577. }
  578. archive, err := archive.TarWithOptions(basePath, &archive.TarOptions{
  579. Compression: archive.Uncompressed,
  580. IncludeFiles: filter,
  581. })
  582. if err != nil {
  583. return nil, err
  584. }
  585. reader := ioutils.NewReadCloserWrapper(archive, func() error {
  586. err := archive.Close()
  587. container.unmountVolumes(true)
  588. container.Unmount()
  589. container.Unlock()
  590. return err
  591. })
  592. container.logEvent("copy")
  593. return reader, nil
  594. }
  595. // Returns true if the container exposes a certain port
  596. func (container *Container) exposes(p nat.Port) bool {
  597. _, exists := container.Config.ExposedPorts[p]
  598. return exists
  599. }
  600. func (container *Container) getLogConfig() runconfig.LogConfig {
  601. cfg := container.hostConfig.LogConfig
  602. if cfg.Type != "" || len(cfg.Config) > 0 { // container has log driver configured
  603. if cfg.Type == "" {
  604. cfg.Type = jsonfilelog.Name
  605. }
  606. return cfg
  607. }
  608. // Use daemon's default log config for containers
  609. return container.daemon.defaultLogConfig
  610. }
  611. func (container *Container) getLogger() (logger.Logger, error) {
  612. if container.logDriver != nil && container.IsRunning() {
  613. return container.logDriver, nil
  614. }
  615. cfg := container.getLogConfig()
  616. if err := logger.ValidateLogOpts(cfg.Type, cfg.Config); err != nil {
  617. return nil, err
  618. }
  619. c, err := logger.GetLogDriver(cfg.Type)
  620. if err != nil {
  621. return nil, derr.ErrorCodeLoggingFactory.WithArgs(err)
  622. }
  623. ctx := logger.Context{
  624. Config: cfg.Config,
  625. ContainerID: container.ID,
  626. ContainerName: container.Name,
  627. ContainerEntrypoint: container.Path,
  628. ContainerArgs: container.Args,
  629. ContainerImageID: container.ImageID,
  630. ContainerImageName: container.Config.Image,
  631. ContainerCreated: container.Created,
  632. ContainerEnv: container.Config.Env,
  633. ContainerLabels: container.Config.Labels,
  634. }
  635. // Set logging file for "json-logger"
  636. if cfg.Type == jsonfilelog.Name {
  637. ctx.LogPath, err = container.getRootResourcePath(fmt.Sprintf("%s-json.log", container.ID))
  638. if err != nil {
  639. return nil, err
  640. }
  641. }
  642. return c(ctx)
  643. }
  644. func (container *Container) startLogging() error {
  645. cfg := container.getLogConfig()
  646. if cfg.Type == "none" {
  647. return nil // do not start logging routines
  648. }
  649. l, err := container.getLogger()
  650. if err != nil {
  651. return derr.ErrorCodeInitLogger.WithArgs(err)
  652. }
  653. copier := logger.NewCopier(container.ID, map[string]io.Reader{"stdout": container.StdoutPipe(), "stderr": container.StderrPipe()}, l)
  654. container.logCopier = copier
  655. copier.Run()
  656. container.logDriver = l
  657. // set LogPath field only for json-file logdriver
  658. if jl, ok := l.(*jsonfilelog.JSONFileLogger); ok {
  659. container.LogPath = jl.LogPath()
  660. }
  661. return nil
  662. }
  663. func (container *Container) waitForStart() error {
  664. container.monitor = newContainerMonitor(container, container.hostConfig.RestartPolicy)
  665. // block until we either receive an error from the initial start of the container's
  666. // process or until the process is running in the container
  667. select {
  668. case <-container.monitor.startSignal:
  669. case err := <-promise.Go(container.monitor.Start):
  670. return err
  671. }
  672. return nil
  673. }
  674. func (container *Container) getProcessLabel() string {
  675. // even if we have a process label return "" if we are running
  676. // in privileged mode
  677. if container.hostConfig.Privileged {
  678. return ""
  679. }
  680. return container.ProcessLabel
  681. }
  682. func (container *Container) getMountLabel() string {
  683. if container.hostConfig.Privileged {
  684. return ""
  685. }
  686. return container.MountLabel
  687. }
  688. func (container *Container) stats() (*execdriver.ResourceStats, error) {
  689. return container.daemon.stats(container)
  690. }
  691. func (container *Container) getExecIDs() []string {
  692. return container.execCommands.List()
  693. }
  694. func (container *Container) exec(ec *ExecConfig) error {
  695. container.Lock()
  696. defer container.Unlock()
  697. callback := func(processConfig *execdriver.ProcessConfig, pid int, chOOM <-chan struct{}) error {
  698. if processConfig.Tty {
  699. // The callback is called after the process Start()
  700. // so we are in the parent process. In TTY mode, stdin/out/err is the PtySlave
  701. // which we close here.
  702. if c, ok := processConfig.Stdout.(io.Closer); ok {
  703. c.Close()
  704. }
  705. }
  706. close(ec.waitStart)
  707. return nil
  708. }
  709. // We use a callback here instead of a goroutine and an chan for
  710. // synchronization purposes
  711. cErr := promise.Go(func() error { return container.monitorExec(ec, callback) })
  712. // Exec should not return until the process is actually running
  713. select {
  714. case <-ec.waitStart:
  715. case err := <-cErr:
  716. return err
  717. }
  718. return nil
  719. }
  720. func (container *Container) monitorExec(ExecConfig *ExecConfig, callback execdriver.DriverCallback) error {
  721. var (
  722. err error
  723. exitCode int
  724. )
  725. pipes := execdriver.NewPipes(ExecConfig.streamConfig.stdin, ExecConfig.streamConfig.stdout, ExecConfig.streamConfig.stderr, ExecConfig.OpenStdin)
  726. exitCode, err = container.daemon.Exec(container, ExecConfig, pipes, callback)
  727. if err != nil {
  728. logrus.Errorf("Error running command in existing container %s: %s", container.ID, err)
  729. }
  730. logrus.Debugf("Exec task in container %s exited with code %d", container.ID, exitCode)
  731. if ExecConfig.OpenStdin {
  732. if err := ExecConfig.streamConfig.stdin.Close(); err != nil {
  733. logrus.Errorf("Error closing stdin while running in %s: %s", container.ID, err)
  734. }
  735. }
  736. if err := ExecConfig.streamConfig.stdout.Clean(); err != nil {
  737. logrus.Errorf("Error closing stdout while running in %s: %s", container.ID, err)
  738. }
  739. if err := ExecConfig.streamConfig.stderr.Clean(); err != nil {
  740. logrus.Errorf("Error closing stderr while running in %s: %s", container.ID, err)
  741. }
  742. if ExecConfig.ProcessConfig.Terminal != nil {
  743. if err := ExecConfig.ProcessConfig.Terminal.Close(); err != nil {
  744. logrus.Errorf("Error closing terminal while running in container %s: %s", container.ID, err)
  745. }
  746. }
  747. // remove the exec command from the container's store only and not the
  748. // daemon's store so that the exec command can be inspected.
  749. container.execCommands.Delete(ExecConfig.ID)
  750. return err
  751. }
  752. // Attach connects to the container's TTY, delegating to standard
  753. // streams or websockets depending on the configuration.
  754. func (container *Container) Attach(stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) chan error {
  755. return attach(&container.streamConfig, container.Config.OpenStdin, container.Config.StdinOnce, container.Config.Tty, stdin, stdout, stderr)
  756. }
  757. func (container *Container) attachWithLogs(stdin io.ReadCloser, stdout, stderr io.Writer, logs, stream bool) error {
  758. if logs {
  759. logDriver, err := container.getLogger()
  760. if err != nil {
  761. return err
  762. }
  763. cLog, ok := logDriver.(logger.LogReader)
  764. if !ok {
  765. return logger.ErrReadLogsNotSupported
  766. }
  767. logs := cLog.ReadLogs(logger.ReadConfig{Tail: -1})
  768. LogLoop:
  769. for {
  770. select {
  771. case msg, ok := <-logs.Msg:
  772. if !ok {
  773. break LogLoop
  774. }
  775. if msg.Source == "stdout" && stdout != nil {
  776. stdout.Write(msg.Line)
  777. }
  778. if msg.Source == "stderr" && stderr != nil {
  779. stderr.Write(msg.Line)
  780. }
  781. case err := <-logs.Err:
  782. logrus.Errorf("Error streaming logs: %v", err)
  783. break LogLoop
  784. }
  785. }
  786. }
  787. container.logEvent("attach")
  788. //stream
  789. if stream {
  790. var stdinPipe io.ReadCloser
  791. if stdin != nil {
  792. r, w := io.Pipe()
  793. go func() {
  794. defer w.Close()
  795. defer logrus.Debugf("Closing buffered stdin pipe")
  796. io.Copy(w, stdin)
  797. }()
  798. stdinPipe = r
  799. }
  800. <-container.Attach(stdinPipe, stdout, stderr)
  801. // If we are in stdinonce mode, wait for the process to end
  802. // otherwise, simply return
  803. if container.Config.StdinOnce && !container.Config.Tty {
  804. container.WaitStop(-1 * time.Second)
  805. }
  806. }
  807. return nil
  808. }
  809. func attach(streamConfig *streamConfig, openStdin, stdinOnce, tty bool, stdin io.ReadCloser, stdout io.Writer, stderr io.Writer) chan error {
  810. var (
  811. cStdout, cStderr io.ReadCloser
  812. cStdin io.WriteCloser
  813. wg sync.WaitGroup
  814. errors = make(chan error, 3)
  815. )
  816. if stdin != nil && openStdin {
  817. cStdin = streamConfig.StdinPipe()
  818. wg.Add(1)
  819. }
  820. if stdout != nil {
  821. cStdout = streamConfig.StdoutPipe()
  822. wg.Add(1)
  823. }
  824. if stderr != nil {
  825. cStderr = streamConfig.StderrPipe()
  826. wg.Add(1)
  827. }
  828. // Connect stdin of container to the http conn.
  829. go func() {
  830. if stdin == nil || !openStdin {
  831. return
  832. }
  833. logrus.Debugf("attach: stdin: begin")
  834. defer func() {
  835. if stdinOnce && !tty {
  836. cStdin.Close()
  837. } else {
  838. // No matter what, when stdin is closed (io.Copy unblock), close stdout and stderr
  839. if cStdout != nil {
  840. cStdout.Close()
  841. }
  842. if cStderr != nil {
  843. cStderr.Close()
  844. }
  845. }
  846. wg.Done()
  847. logrus.Debugf("attach: stdin: end")
  848. }()
  849. var err error
  850. if tty {
  851. _, err = copyEscapable(cStdin, stdin)
  852. } else {
  853. _, err = io.Copy(cStdin, stdin)
  854. }
  855. if err == io.ErrClosedPipe {
  856. err = nil
  857. }
  858. if err != nil {
  859. logrus.Errorf("attach: stdin: %s", err)
  860. errors <- err
  861. return
  862. }
  863. }()
  864. attachStream := func(name string, stream io.Writer, streamPipe io.ReadCloser) {
  865. if stream == nil {
  866. return
  867. }
  868. defer func() {
  869. // Make sure stdin gets closed
  870. if stdin != nil {
  871. stdin.Close()
  872. }
  873. streamPipe.Close()
  874. wg.Done()
  875. logrus.Debugf("attach: %s: end", name)
  876. }()
  877. logrus.Debugf("attach: %s: begin", name)
  878. _, err := io.Copy(stream, streamPipe)
  879. if err == io.ErrClosedPipe {
  880. err = nil
  881. }
  882. if err != nil {
  883. logrus.Errorf("attach: %s: %v", name, err)
  884. errors <- err
  885. }
  886. }
  887. go attachStream("stdout", stdout, cStdout)
  888. go attachStream("stderr", stderr, cStderr)
  889. return promise.Go(func() error {
  890. wg.Wait()
  891. close(errors)
  892. for err := range errors {
  893. if err != nil {
  894. return err
  895. }
  896. }
  897. return nil
  898. })
  899. }
  900. // Code c/c from io.Copy() modified to handle escape sequence
  901. func copyEscapable(dst io.Writer, src io.ReadCloser) (written int64, err error) {
  902. buf := make([]byte, 32*1024)
  903. for {
  904. nr, er := src.Read(buf)
  905. if nr > 0 {
  906. // ---- Docker addition
  907. // char 16 is C-p
  908. if nr == 1 && buf[0] == 16 {
  909. nr, er = src.Read(buf)
  910. // char 17 is C-q
  911. if nr == 1 && buf[0] == 17 {
  912. if err := src.Close(); err != nil {
  913. return 0, err
  914. }
  915. return 0, nil
  916. }
  917. }
  918. // ---- End of docker
  919. nw, ew := dst.Write(buf[0:nr])
  920. if nw > 0 {
  921. written += int64(nw)
  922. }
  923. if ew != nil {
  924. err = ew
  925. break
  926. }
  927. if nr != nw {
  928. err = io.ErrShortWrite
  929. break
  930. }
  931. }
  932. if er == io.EOF {
  933. break
  934. }
  935. if er != nil {
  936. err = er
  937. break
  938. }
  939. }
  940. return written, err
  941. }
  942. func (container *Container) shouldRestart() bool {
  943. return container.hostConfig.RestartPolicy.Name == "always" ||
  944. (container.hostConfig.RestartPolicy.Name == "unless-stopped" && !container.HasBeenManuallyStopped) ||
  945. (container.hostConfig.RestartPolicy.Name == "on-failure" && container.ExitCode != 0)
  946. }
  947. func (container *Container) mountVolumes() error {
  948. mounts, err := container.setupMounts()
  949. if err != nil {
  950. return err
  951. }
  952. for _, m := range mounts {
  953. dest, err := container.GetResourcePath(m.Destination)
  954. if err != nil {
  955. return err
  956. }
  957. var stat os.FileInfo
  958. stat, err = os.Stat(m.Source)
  959. if err != nil {
  960. return err
  961. }
  962. if err = fileutils.CreateIfNotExists(dest, stat.IsDir()); err != nil {
  963. return err
  964. }
  965. opts := "rbind,ro"
  966. if m.Writable {
  967. opts = "rbind,rw"
  968. }
  969. if err := mount.Mount(m.Source, dest, "bind", opts); err != nil {
  970. return err
  971. }
  972. }
  973. return nil
  974. }
  975. func (container *Container) prepareMountPoints() error {
  976. for _, config := range container.MountPoints {
  977. if len(config.Driver) > 0 {
  978. v, err := container.daemon.createVolume(config.Name, config.Driver, nil)
  979. if err != nil {
  980. return err
  981. }
  982. config.Volume = v
  983. }
  984. }
  985. return nil
  986. }
  987. func (container *Container) removeMountPoints(rm bool) error {
  988. var rmErrors []string
  989. for _, m := range container.MountPoints {
  990. if m.Volume == nil {
  991. continue
  992. }
  993. container.daemon.volumes.Decrement(m.Volume)
  994. if rm {
  995. err := container.daemon.volumes.Remove(m.Volume)
  996. // ErrVolumeInUse is ignored because having this
  997. // volume being referenced by other container is
  998. // not an error, but an implementation detail.
  999. // This prevents docker from logging "ERROR: Volume in use"
  1000. // where there is another container using the volume.
  1001. if err != nil && err != store.ErrVolumeInUse {
  1002. rmErrors = append(rmErrors, err.Error())
  1003. }
  1004. }
  1005. }
  1006. if len(rmErrors) > 0 {
  1007. return derr.ErrorCodeRemovingVolume.WithArgs(strings.Join(rmErrors, "\n"))
  1008. }
  1009. return nil
  1010. }
  1011. func (container *Container) unmountVolumes(forceSyscall bool) error {
  1012. var (
  1013. volumeMounts []volume.MountPoint
  1014. err error
  1015. )
  1016. for _, mntPoint := range container.MountPoints {
  1017. dest, err := container.GetResourcePath(mntPoint.Destination)
  1018. if err != nil {
  1019. return err
  1020. }
  1021. volumeMounts = append(volumeMounts, volume.MountPoint{Destination: dest, Volume: mntPoint.Volume})
  1022. }
  1023. // Append any network mounts to the list (this is a no-op on Windows)
  1024. if volumeMounts, err = appendNetworkMounts(container, volumeMounts); err != nil {
  1025. return err
  1026. }
  1027. for _, volumeMount := range volumeMounts {
  1028. if forceSyscall {
  1029. system.UnmountWithSyscall(volumeMount.Destination)
  1030. }
  1031. if volumeMount.Volume != nil {
  1032. if err := volumeMount.Volume.Unmount(); err != nil {
  1033. return err
  1034. }
  1035. }
  1036. }
  1037. return nil
  1038. }
  1039. func (container *Container) addBindMountPoint(name, source, destination string, rw bool) {
  1040. container.MountPoints[destination] = &volume.MountPoint{
  1041. Name: name,
  1042. Source: source,
  1043. Destination: destination,
  1044. RW: rw,
  1045. }
  1046. }
  1047. func (container *Container) addLocalMountPoint(name, destination string, rw bool) {
  1048. container.MountPoints[destination] = &volume.MountPoint{
  1049. Name: name,
  1050. Driver: volume.DefaultDriverName,
  1051. Destination: destination,
  1052. RW: rw,
  1053. }
  1054. }
  1055. func (container *Container) addMountPointWithVolume(destination string, vol volume.Volume, rw bool) {
  1056. container.MountPoints[destination] = &volume.MountPoint{
  1057. Name: vol.Name(),
  1058. Driver: vol.DriverName(),
  1059. Destination: destination,
  1060. RW: rw,
  1061. Volume: vol,
  1062. }
  1063. }
  1064. func (container *Container) isDestinationMounted(destination string) bool {
  1065. return container.MountPoints[destination] != nil
  1066. }
  1067. func (container *Container) stopSignal() int {
  1068. var stopSignal syscall.Signal
  1069. if container.Config.StopSignal != "" {
  1070. stopSignal, _ = signal.ParseSignal(container.Config.StopSignal)
  1071. }
  1072. if int(stopSignal) == 0 {
  1073. stopSignal, _ = signal.ParseSignal(signal.DefaultStopSignal)
  1074. }
  1075. return int(stopSignal)
  1076. }