server.go 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043
  1. package docker
  2. import (
  3. "bufio"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "github.com/dotcloud/docker/archive"
  8. "github.com/dotcloud/docker/auth"
  9. "github.com/dotcloud/docker/engine"
  10. "github.com/dotcloud/docker/graphdb"
  11. "github.com/dotcloud/docker/registry"
  12. "github.com/dotcloud/docker/utils"
  13. "io"
  14. "io/ioutil"
  15. "log"
  16. "net/http"
  17. "net/url"
  18. "os"
  19. "os/exec"
  20. "os/signal"
  21. "path"
  22. "path/filepath"
  23. "runtime"
  24. "strconv"
  25. "strings"
  26. "sync"
  27. "syscall"
  28. "time"
  29. )
  30. func (srv *Server) Close() error {
  31. return srv.runtime.Close()
  32. }
  33. func init() {
  34. engine.Register("initapi", jobInitApi)
  35. }
  36. // jobInitApi runs the remote api server `srv` as a daemon,
  37. // Only one api server can run at the same time - this is enforced by a pidfile.
  38. // The signals SIGINT, SIGQUIT and SIGTERM are intercepted for cleanup.
  39. func jobInitApi(job *engine.Job) engine.Status {
  40. job.Logf("Creating server")
  41. // FIXME: ImportEnv deprecates ConfigFromJob
  42. srv, err := NewServer(job.Eng, ConfigFromJob(job))
  43. if err != nil {
  44. job.Error(err)
  45. return engine.StatusErr
  46. }
  47. if srv.runtime.config.Pidfile != "" {
  48. job.Logf("Creating pidfile")
  49. if err := utils.CreatePidFile(srv.runtime.config.Pidfile); err != nil {
  50. // FIXME: do we need fatal here instead of returning a job error?
  51. log.Fatal(err)
  52. }
  53. }
  54. job.Logf("Setting up signal traps")
  55. c := make(chan os.Signal, 1)
  56. signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
  57. go func() {
  58. sig := <-c
  59. log.Printf("Received signal '%v', exiting\n", sig)
  60. utils.RemovePidFile(srv.runtime.config.Pidfile)
  61. srv.Close()
  62. os.Exit(0)
  63. }()
  64. job.Eng.Hack_SetGlobalVar("httpapi.server", srv)
  65. job.Eng.Hack_SetGlobalVar("httpapi.runtime", srv.runtime)
  66. // https://github.com/dotcloud/docker/issues/2768
  67. if srv.runtime.networkManager.bridgeNetwork != nil {
  68. job.Eng.Hack_SetGlobalVar("httpapi.bridgeIP", srv.runtime.networkManager.bridgeNetwork.IP)
  69. }
  70. if err := job.Eng.Register("export", srv.ContainerExport); err != nil {
  71. job.Error(err)
  72. return engine.StatusErr
  73. }
  74. if err := job.Eng.Register("create", srv.ContainerCreate); err != nil {
  75. job.Error(err)
  76. return engine.StatusErr
  77. }
  78. if err := job.Eng.Register("stop", srv.ContainerStop); err != nil {
  79. job.Error(err)
  80. return engine.StatusErr
  81. }
  82. if err := job.Eng.Register("start", srv.ContainerStart); err != nil {
  83. job.Error(err)
  84. return engine.StatusErr
  85. }
  86. if err := job.Eng.Register("kill", srv.ContainerKill); err != nil {
  87. job.Error(err)
  88. return engine.StatusErr
  89. }
  90. if err := job.Eng.Register("serveapi", srv.ListenAndServe); err != nil {
  91. job.Error(err)
  92. return engine.StatusErr
  93. }
  94. if err := job.Eng.Register("wait", srv.ContainerWait); err != nil {
  95. job.Error(err)
  96. return engine.StatusErr
  97. }
  98. if err := job.Eng.Register("tag", srv.ImageTag); err != nil {
  99. job.Error(err)
  100. return engine.StatusErr
  101. }
  102. if err := job.Eng.Register("resize", srv.ContainerResize); err != nil {
  103. job.Error(err)
  104. return engine.StatusErr
  105. }
  106. if err := job.Eng.Register("commit", srv.ContainerCommit); err != nil {
  107. job.Error(err)
  108. return engine.StatusErr
  109. }
  110. if err := job.Eng.Register("info", srv.DockerInfo); err != nil {
  111. job.Error(err)
  112. return engine.StatusErr
  113. }
  114. return engine.StatusOK
  115. }
  116. func (srv *Server) ListenAndServe(job *engine.Job) engine.Status {
  117. protoAddrs := job.Args
  118. chErrors := make(chan error, len(protoAddrs))
  119. for _, protoAddr := range protoAddrs {
  120. protoAddrParts := strings.SplitN(protoAddr, "://", 2)
  121. switch protoAddrParts[0] {
  122. case "unix":
  123. if err := syscall.Unlink(protoAddrParts[1]); err != nil && !os.IsNotExist(err) {
  124. log.Fatal(err)
  125. }
  126. case "tcp":
  127. if !strings.HasPrefix(protoAddrParts[1], "127.0.0.1") {
  128. log.Println("/!\\ DON'T BIND ON ANOTHER IP ADDRESS THAN 127.0.0.1 IF YOU DON'T KNOW WHAT YOU'RE DOING /!\\")
  129. }
  130. default:
  131. job.Errorf("Invalid protocol format.")
  132. return engine.StatusErr
  133. }
  134. go func() {
  135. // FIXME: merge Server.ListenAndServe with ListenAndServe
  136. chErrors <- ListenAndServe(protoAddrParts[0], protoAddrParts[1], srv, job.GetenvBool("Logging"))
  137. }()
  138. }
  139. for i := 0; i < len(protoAddrs); i += 1 {
  140. err := <-chErrors
  141. if err != nil {
  142. job.Error(err)
  143. return engine.StatusErr
  144. }
  145. }
  146. return engine.StatusOK
  147. }
  148. // simpleVersionInfo is a simple implementation of
  149. // the interface VersionInfo, which is used
  150. // to provide version information for some product,
  151. // component, etc. It stores the product name and the version
  152. // in string and returns them on calls to Name() and Version().
  153. type simpleVersionInfo struct {
  154. name string
  155. version string
  156. }
  157. func (v *simpleVersionInfo) Name() string {
  158. return v.name
  159. }
  160. func (v *simpleVersionInfo) Version() string {
  161. return v.version
  162. }
  163. // ContainerKill send signal to the container
  164. // If no signal is given (sig 0), then Kill with SIGKILL and wait
  165. // for the container to exit.
  166. // If a signal is given, then just send it to the container and return.
  167. func (srv *Server) ContainerKill(job *engine.Job) engine.Status {
  168. if n := len(job.Args); n < 1 || n > 2 {
  169. job.Errorf("Usage: %s CONTAINER [SIGNAL]", job.Name)
  170. return engine.StatusErr
  171. }
  172. name := job.Args[0]
  173. var sig uint64
  174. if len(job.Args) == 2 && job.Args[1] != "" {
  175. var err error
  176. // The largest legal signal is 31, so let's parse on 5 bits
  177. sig, err = strconv.ParseUint(job.Args[1], 10, 5)
  178. if err != nil {
  179. job.Errorf("Invalid signal: %s", job.Args[1])
  180. return engine.StatusErr
  181. }
  182. }
  183. if container := srv.runtime.Get(name); container != nil {
  184. // If no signal is passed, perform regular Kill (SIGKILL + wait())
  185. if sig == 0 {
  186. if err := container.Kill(); err != nil {
  187. job.Errorf("Cannot kill container %s: %s", name, err)
  188. return engine.StatusErr
  189. }
  190. srv.LogEvent("kill", container.ID, srv.runtime.repositories.ImageName(container.Image))
  191. } else {
  192. // Otherwise, just send the requested signal
  193. if err := container.kill(int(sig)); err != nil {
  194. job.Errorf("Cannot kill container %s: %s", name, err)
  195. return engine.StatusErr
  196. }
  197. // FIXME: Add event for signals
  198. }
  199. } else {
  200. job.Errorf("No such container: %s", name)
  201. return engine.StatusErr
  202. }
  203. return engine.StatusOK
  204. }
  205. func (srv *Server) ContainerExport(job *engine.Job) engine.Status {
  206. if len(job.Args) != 1 {
  207. job.Errorf("Usage: %s container_id", job.Name)
  208. return engine.StatusErr
  209. }
  210. name := job.Args[0]
  211. if container := srv.runtime.Get(name); container != nil {
  212. data, err := container.Export()
  213. if err != nil {
  214. job.Errorf("%s: %s", name, err)
  215. return engine.StatusErr
  216. }
  217. // Stream the entire contents of the container (basically a volatile snapshot)
  218. if _, err := io.Copy(job.Stdout, data); err != nil {
  219. job.Errorf("%s: %s", name, err)
  220. return engine.StatusErr
  221. }
  222. // FIXME: factor job-specific LogEvent to engine.Job.Run()
  223. srv.LogEvent("export", container.ID, srv.runtime.repositories.ImageName(container.Image))
  224. return engine.StatusOK
  225. }
  226. job.Errorf("No such container: %s", name)
  227. return engine.StatusErr
  228. }
  229. // ImageExport exports all images with the given tag. All versions
  230. // containing the same tag are exported. The resulting output is an
  231. // uncompressed tar ball.
  232. // name is the set of tags to export.
  233. // out is the writer where the images are written to.
  234. func (srv *Server) ImageExport(name string, out io.Writer) error {
  235. // get image json
  236. tempdir, err := ioutil.TempDir("", "docker-export-")
  237. if err != nil {
  238. return err
  239. }
  240. defer os.RemoveAll(tempdir)
  241. utils.Debugf("Serializing %s", name)
  242. rootRepo, err := srv.runtime.repositories.Get(name)
  243. if err != nil {
  244. return err
  245. }
  246. if rootRepo != nil {
  247. for _, id := range rootRepo {
  248. image, err := srv.ImageInspect(id)
  249. if err != nil {
  250. return err
  251. }
  252. if err := srv.exportImage(image, tempdir); err != nil {
  253. return err
  254. }
  255. }
  256. // write repositories
  257. rootRepoMap := map[string]Repository{}
  258. rootRepoMap[name] = rootRepo
  259. rootRepoJson, _ := json.Marshal(rootRepoMap)
  260. if err := ioutil.WriteFile(path.Join(tempdir, "repositories"), rootRepoJson, os.ModeAppend); err != nil {
  261. return err
  262. }
  263. } else {
  264. image, err := srv.ImageInspect(name)
  265. if err != nil {
  266. return err
  267. }
  268. if err := srv.exportImage(image, tempdir); err != nil {
  269. return err
  270. }
  271. }
  272. fs, err := archive.Tar(tempdir, archive.Uncompressed)
  273. if err != nil {
  274. return err
  275. }
  276. if _, err := io.Copy(out, fs); err != nil {
  277. return err
  278. }
  279. return nil
  280. }
  281. func (srv *Server) exportImage(image *Image, tempdir string) error {
  282. for i := image; i != nil; {
  283. // temporary directory
  284. tmpImageDir := path.Join(tempdir, i.ID)
  285. if err := os.Mkdir(tmpImageDir, os.ModeDir); err != nil {
  286. if os.IsExist(err) {
  287. return nil
  288. }
  289. return err
  290. }
  291. var version = "1.0"
  292. var versionBuf = []byte(version)
  293. if err := ioutil.WriteFile(path.Join(tmpImageDir, "VERSION"), versionBuf, os.ModeAppend); err != nil {
  294. return err
  295. }
  296. // serialize json
  297. b, err := json.Marshal(i)
  298. if err != nil {
  299. return err
  300. }
  301. if err := ioutil.WriteFile(path.Join(tmpImageDir, "json"), b, os.ModeAppend); err != nil {
  302. return err
  303. }
  304. // serialize filesystem
  305. fs, err := i.TarLayer()
  306. if err != nil {
  307. return err
  308. }
  309. fsTar, err := os.Create(path.Join(tmpImageDir, "layer.tar"))
  310. if err != nil {
  311. return err
  312. }
  313. if _, err = io.Copy(fsTar, fs); err != nil {
  314. return err
  315. }
  316. fsTar.Close()
  317. // find parent
  318. if i.Parent != "" {
  319. i, err = srv.ImageInspect(i.Parent)
  320. if err != nil {
  321. return err
  322. }
  323. } else {
  324. i = nil
  325. }
  326. }
  327. return nil
  328. }
  329. // Loads a set of images into the repository. This is the complementary of ImageExport.
  330. // The input stream is an uncompressed tar ball containing images and metadata.
  331. func (srv *Server) ImageLoad(in io.Reader) error {
  332. tmpImageDir, err := ioutil.TempDir("", "docker-import-")
  333. if err != nil {
  334. return err
  335. }
  336. defer os.RemoveAll(tmpImageDir)
  337. var (
  338. repoTarFile = path.Join(tmpImageDir, "repo.tar")
  339. repoDir = path.Join(tmpImageDir, "repo")
  340. )
  341. tarFile, err := os.Create(repoTarFile)
  342. if err != nil {
  343. return err
  344. }
  345. if _, err := io.Copy(tarFile, in); err != nil {
  346. return err
  347. }
  348. tarFile.Close()
  349. repoFile, err := os.Open(repoTarFile)
  350. if err != nil {
  351. return err
  352. }
  353. if err := os.Mkdir(repoDir, os.ModeDir); err != nil {
  354. return err
  355. }
  356. if err := archive.Untar(repoFile, repoDir, nil); err != nil {
  357. return err
  358. }
  359. dirs, err := ioutil.ReadDir(repoDir)
  360. if err != nil {
  361. return err
  362. }
  363. for _, d := range dirs {
  364. if d.IsDir() {
  365. if err := srv.recursiveLoad(d.Name(), tmpImageDir); err != nil {
  366. return err
  367. }
  368. }
  369. }
  370. repositoriesJson, err := ioutil.ReadFile(path.Join(tmpImageDir, "repo", "repositories"))
  371. if err == nil {
  372. repositories := map[string]Repository{}
  373. if err := json.Unmarshal(repositoriesJson, &repositories); err != nil {
  374. return err
  375. }
  376. for imageName, tagMap := range repositories {
  377. for tag, address := range tagMap {
  378. if err := srv.runtime.repositories.Set(imageName, tag, address, true); err != nil {
  379. return err
  380. }
  381. }
  382. }
  383. } else if !os.IsNotExist(err) {
  384. return err
  385. }
  386. return nil
  387. }
  388. func (srv *Server) recursiveLoad(address, tmpImageDir string) error {
  389. if _, err := srv.ImageInspect(address); err != nil {
  390. utils.Debugf("Loading %s", address)
  391. imageJson, err := ioutil.ReadFile(path.Join(tmpImageDir, "repo", address, "json"))
  392. if err != nil {
  393. utils.Debugf("Error reading json", err)
  394. return err
  395. }
  396. layer, err := os.Open(path.Join(tmpImageDir, "repo", address, "layer.tar"))
  397. if err != nil {
  398. utils.Debugf("Error reading embedded tar", err)
  399. return err
  400. }
  401. img, err := NewImgJSON(imageJson)
  402. if err != nil {
  403. utils.Debugf("Error unmarshalling json", err)
  404. return err
  405. }
  406. if img.Parent != "" {
  407. if !srv.runtime.graph.Exists(img.Parent) {
  408. if err := srv.recursiveLoad(img.Parent, tmpImageDir); err != nil {
  409. return err
  410. }
  411. }
  412. }
  413. if err := srv.runtime.graph.Register(imageJson, layer, img); err != nil {
  414. return err
  415. }
  416. }
  417. utils.Debugf("Completed processing %s", address)
  418. return nil
  419. }
  420. func (srv *Server) ImagesSearch(term string) ([]registry.SearchResult, error) {
  421. r, err := registry.NewRegistry(nil, srv.HTTPRequestFactory(nil), auth.IndexServerAddress())
  422. if err != nil {
  423. return nil, err
  424. }
  425. results, err := r.SearchRepositories(term)
  426. if err != nil {
  427. return nil, err
  428. }
  429. return results.Results, nil
  430. }
  431. func (srv *Server) ImageInsert(name, url, path string, out io.Writer, sf *utils.StreamFormatter) error {
  432. out = utils.NewWriteFlusher(out)
  433. img, err := srv.runtime.repositories.LookupImage(name)
  434. if err != nil {
  435. return err
  436. }
  437. file, err := utils.Download(url)
  438. if err != nil {
  439. return err
  440. }
  441. defer file.Body.Close()
  442. config, _, _, err := ParseRun([]string{img.ID, "echo", "insert", url, path}, srv.runtime.capabilities)
  443. if err != nil {
  444. return err
  445. }
  446. c, _, err := srv.runtime.Create(config, "")
  447. if err != nil {
  448. return err
  449. }
  450. if err := c.Inject(utils.ProgressReader(file.Body, int(file.ContentLength), out, sf, false, "", "Downloading"), path); err != nil {
  451. return err
  452. }
  453. // FIXME: Handle custom repo, tag comment, author
  454. img, err = srv.runtime.Commit(c, "", "", img.Comment, img.Author, nil)
  455. if err != nil {
  456. return err
  457. }
  458. out.Write(sf.FormatStatus(img.ID, ""))
  459. return nil
  460. }
  461. func (srv *Server) ImagesViz(out io.Writer) error {
  462. images, _ := srv.runtime.graph.Map()
  463. if images == nil {
  464. return nil
  465. }
  466. out.Write([]byte("digraph docker {\n"))
  467. var (
  468. parentImage *Image
  469. err error
  470. )
  471. for _, image := range images {
  472. parentImage, err = image.GetParent()
  473. if err != nil {
  474. return fmt.Errorf("Error while getting parent image: %v", err)
  475. }
  476. if parentImage != nil {
  477. out.Write([]byte(" \"" + parentImage.ID + "\" -> \"" + image.ID + "\"\n"))
  478. } else {
  479. out.Write([]byte(" base -> \"" + image.ID + "\" [style=invis]\n"))
  480. }
  481. }
  482. reporefs := make(map[string][]string)
  483. for name, repository := range srv.runtime.repositories.Repositories {
  484. for tag, id := range repository {
  485. reporefs[utils.TruncateID(id)] = append(reporefs[utils.TruncateID(id)], fmt.Sprintf("%s:%s", name, tag))
  486. }
  487. }
  488. for id, repos := range reporefs {
  489. out.Write([]byte(" \"" + id + "\" [label=\"" + id + "\\n" + strings.Join(repos, "\\n") + "\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n"))
  490. }
  491. out.Write([]byte(" base [style=invisible]\n}\n"))
  492. return nil
  493. }
  494. func (srv *Server) Images(all bool, filter string) ([]APIImages, error) {
  495. var (
  496. allImages map[string]*Image
  497. err error
  498. )
  499. if all {
  500. allImages, err = srv.runtime.graph.Map()
  501. } else {
  502. allImages, err = srv.runtime.graph.Heads()
  503. }
  504. if err != nil {
  505. return nil, err
  506. }
  507. lookup := make(map[string]APIImages)
  508. for name, repository := range srv.runtime.repositories.Repositories {
  509. if filter != "" {
  510. if match, _ := path.Match(filter, name); !match {
  511. continue
  512. }
  513. }
  514. for tag, id := range repository {
  515. image, err := srv.runtime.graph.Get(id)
  516. if err != nil {
  517. log.Printf("Warning: couldn't load %s from %s/%s: %s", id, name, tag, err)
  518. continue
  519. }
  520. if out, exists := lookup[id]; exists {
  521. out.RepoTags = append(out.RepoTags, fmt.Sprintf("%s:%s", name, tag))
  522. lookup[id] = out
  523. } else {
  524. var out APIImages
  525. delete(allImages, id)
  526. out.ParentId = image.Parent
  527. out.RepoTags = []string{fmt.Sprintf("%s:%s", name, tag)}
  528. out.ID = image.ID
  529. out.Created = image.Created.Unix()
  530. out.Size = image.Size
  531. out.VirtualSize = image.getParentsSize(0) + image.Size
  532. lookup[id] = out
  533. }
  534. }
  535. }
  536. outs := make([]APIImages, 0, len(lookup))
  537. for _, value := range lookup {
  538. outs = append(outs, value)
  539. }
  540. // Display images which aren't part of a repository/tag
  541. if filter == "" {
  542. for _, image := range allImages {
  543. var out APIImages
  544. out.ID = image.ID
  545. out.ParentId = image.Parent
  546. out.RepoTags = []string{"<none>:<none>"}
  547. out.Created = image.Created.Unix()
  548. out.Size = image.Size
  549. out.VirtualSize = image.getParentsSize(0) + image.Size
  550. outs = append(outs, out)
  551. }
  552. }
  553. sortImagesByCreationAndTag(outs)
  554. return outs, nil
  555. }
  556. func (srv *Server) DockerInfo(job *engine.Job) engine.Status {
  557. images, _ := srv.runtime.graph.Map()
  558. var imgcount int
  559. if images == nil {
  560. imgcount = 0
  561. } else {
  562. imgcount = len(images)
  563. }
  564. lxcVersion := ""
  565. if output, err := exec.Command("lxc-version").CombinedOutput(); err == nil {
  566. outputStr := string(output)
  567. if len(strings.SplitN(outputStr, ":", 2)) == 2 {
  568. lxcVersion = strings.TrimSpace(strings.SplitN(string(output), ":", 2)[1])
  569. }
  570. }
  571. kernelVersion := "<unknown>"
  572. if kv, err := utils.GetKernelVersion(); err == nil {
  573. kernelVersion = kv.String()
  574. }
  575. // if we still have the original dockerinit binary from before we copied it locally, let's return the path to that, since that's more intuitive (the copied path is trivial to derive by hand given VERSION)
  576. initPath := utils.DockerInitPath("")
  577. if initPath == "" {
  578. // if that fails, we'll just return the path from the runtime
  579. initPath = srv.runtime.sysInitPath
  580. }
  581. v := &engine.Env{}
  582. v.SetInt("Containers", len(srv.runtime.List()))
  583. v.SetInt("Images", imgcount)
  584. v.Set("Driver", srv.runtime.driver.String())
  585. v.SetJson("DriverStatus", srv.runtime.driver.Status())
  586. v.SetBool("MemoryLimit", srv.runtime.capabilities.MemoryLimit)
  587. v.SetBool("SwapLimit", srv.runtime.capabilities.SwapLimit)
  588. v.SetBool("IPv4Forwarding", !srv.runtime.capabilities.IPv4ForwardingDisabled)
  589. v.SetBool("Debug", os.Getenv("DEBUG") != "")
  590. v.SetInt("NFd", utils.GetTotalUsedFds())
  591. v.SetInt("NGoroutines", runtime.NumGoroutine())
  592. v.Set("LXCVersion", lxcVersion)
  593. v.SetInt("NEventsListener", len(srv.events))
  594. v.Set("KernelVersion", kernelVersion)
  595. v.Set("IndexServerAddress", auth.IndexServerAddress())
  596. v.Set("InitSha1", utils.INITSHA1)
  597. v.Set("InitPath", initPath)
  598. if _, err := v.WriteTo(job.Stdout); err != nil {
  599. job.Error(err)
  600. return engine.StatusErr
  601. }
  602. return engine.StatusOK
  603. }
  604. func (srv *Server) ImageHistory(name string) ([]APIHistory, error) {
  605. image, err := srv.runtime.repositories.LookupImage(name)
  606. if err != nil {
  607. return nil, err
  608. }
  609. lookupMap := make(map[string][]string)
  610. for name, repository := range srv.runtime.repositories.Repositories {
  611. for tag, id := range repository {
  612. // If the ID already has a reverse lookup, do not update it unless for "latest"
  613. if _, exists := lookupMap[id]; !exists {
  614. lookupMap[id] = []string{}
  615. }
  616. lookupMap[id] = append(lookupMap[id], name+":"+tag)
  617. }
  618. }
  619. outs := []APIHistory{} //produce [] when empty instead of 'null'
  620. err = image.WalkHistory(func(img *Image) error {
  621. var out APIHistory
  622. out.ID = img.ID
  623. out.Created = img.Created.Unix()
  624. out.CreatedBy = strings.Join(img.ContainerConfig.Cmd, " ")
  625. out.Tags = lookupMap[img.ID]
  626. out.Size = img.Size
  627. outs = append(outs, out)
  628. return nil
  629. })
  630. return outs, nil
  631. }
  632. func (srv *Server) ContainerTop(name, psArgs string) (*APITop, error) {
  633. if container := srv.runtime.Get(name); container != nil {
  634. output, err := exec.Command("lxc-ps", "--name", container.ID, "--", psArgs).CombinedOutput()
  635. if err != nil {
  636. return nil, fmt.Errorf("lxc-ps: %s (%s)", err, output)
  637. }
  638. procs := APITop{}
  639. for i, line := range strings.Split(string(output), "\n") {
  640. if len(line) == 0 {
  641. continue
  642. }
  643. words := []string{}
  644. scanner := bufio.NewScanner(strings.NewReader(line))
  645. scanner.Split(bufio.ScanWords)
  646. if !scanner.Scan() {
  647. return nil, fmt.Errorf("Wrong output using lxc-ps")
  648. }
  649. // no scanner.Text because we skip container id
  650. for scanner.Scan() {
  651. if i != 0 && len(words) == len(procs.Titles) {
  652. words[len(words)-1] = fmt.Sprintf("%s %s", words[len(words)-1], scanner.Text())
  653. } else {
  654. words = append(words, scanner.Text())
  655. }
  656. }
  657. if i == 0 {
  658. procs.Titles = words
  659. } else {
  660. procs.Processes = append(procs.Processes, words)
  661. }
  662. }
  663. return &procs, nil
  664. }
  665. return nil, fmt.Errorf("No such container: %s", name)
  666. }
  667. func (srv *Server) ContainerChanges(name string) ([]archive.Change, error) {
  668. if container := srv.runtime.Get(name); container != nil {
  669. return container.Changes()
  670. }
  671. return nil, fmt.Errorf("No such container: %s", name)
  672. }
  673. func (srv *Server) Containers(all, size bool, n int, since, before string) []APIContainers {
  674. var foundBefore bool
  675. var displayed int
  676. out := []APIContainers{}
  677. names := map[string][]string{}
  678. srv.runtime.containerGraph.Walk("/", func(p string, e *graphdb.Entity) error {
  679. names[e.ID()] = append(names[e.ID()], p)
  680. return nil
  681. }, -1)
  682. for _, container := range srv.runtime.List() {
  683. if !container.State.IsRunning() && !all && n == -1 && since == "" && before == "" {
  684. continue
  685. }
  686. if before != "" && !foundBefore {
  687. if container.ID == before || utils.TruncateID(container.ID) == before {
  688. foundBefore = true
  689. }
  690. continue
  691. }
  692. if displayed == n {
  693. break
  694. }
  695. if container.ID == since || utils.TruncateID(container.ID) == since {
  696. break
  697. }
  698. displayed++
  699. c := createAPIContainer(names[container.ID], container, size, srv.runtime)
  700. out = append(out, c)
  701. }
  702. return out
  703. }
  704. func createAPIContainer(names []string, container *Container, size bool, runtime *Runtime) APIContainers {
  705. c := APIContainers{
  706. ID: container.ID,
  707. }
  708. c.Names = names
  709. c.Image = runtime.repositories.ImageName(container.Image)
  710. c.Command = fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " "))
  711. c.Created = container.Created.Unix()
  712. c.Status = container.State.String()
  713. c.Ports = container.NetworkSettings.PortMappingAPI()
  714. if size {
  715. c.SizeRw, c.SizeRootFs = container.GetSize()
  716. }
  717. return c
  718. }
  719. func (srv *Server) ContainerCommit(job *engine.Job) engine.Status {
  720. if len(job.Args) != 1 {
  721. job.Errorf("Not enough arguments. Usage: %s CONTAINER\n", job.Name)
  722. return engine.StatusErr
  723. }
  724. name := job.Args[0]
  725. container := srv.runtime.Get(name)
  726. if container == nil {
  727. job.Errorf("No such container: %s", name)
  728. return engine.StatusErr
  729. }
  730. var config Config
  731. if err := job.GetenvJson("config", &config); err != nil {
  732. job.Error(err)
  733. return engine.StatusErr
  734. }
  735. img, err := srv.runtime.Commit(container, job.Getenv("repo"), job.Getenv("tag"), job.Getenv("comment"), job.Getenv("author"), &config)
  736. if err != nil {
  737. job.Error(err)
  738. return engine.StatusErr
  739. }
  740. job.Printf("%s\n", img.ID)
  741. return engine.StatusOK
  742. }
  743. func (srv *Server) ImageTag(job *engine.Job) engine.Status {
  744. if len(job.Args) != 2 && len(job.Args) != 3 {
  745. job.Errorf("Usage: %s IMAGE REPOSITORY [TAG]\n", job.Name)
  746. return engine.StatusErr
  747. }
  748. var tag string
  749. if len(job.Args) == 3 {
  750. tag = job.Args[2]
  751. }
  752. if err := srv.runtime.repositories.Set(job.Args[1], tag, job.Args[0], job.GetenvBool("force")); err != nil {
  753. job.Error(err)
  754. return engine.StatusErr
  755. }
  756. return engine.StatusOK
  757. }
  758. func (srv *Server) pullImage(r *registry.Registry, out io.Writer, imgID, endpoint string, token []string, sf *utils.StreamFormatter) error {
  759. history, err := r.GetRemoteHistory(imgID, endpoint, token)
  760. if err != nil {
  761. return err
  762. }
  763. out.Write(sf.FormatProgress(utils.TruncateID(imgID), "Pulling dependent layers", nil))
  764. // FIXME: Try to stream the images?
  765. // FIXME: Launch the getRemoteImage() in goroutines
  766. for i := len(history) - 1; i >= 0; i-- {
  767. id := history[i]
  768. // ensure no two downloads of the same layer happen at the same time
  769. if c, err := srv.poolAdd("pull", "layer:"+id); err != nil {
  770. utils.Errorf("Image (id: %s) pull is already running, skipping: %v", id, err)
  771. <-c
  772. }
  773. defer srv.poolRemove("pull", "layer:"+id)
  774. if !srv.runtime.graph.Exists(id) {
  775. out.Write(sf.FormatProgress(utils.TruncateID(id), "Pulling metadata", nil))
  776. imgJSON, imgSize, err := r.GetRemoteImageJSON(id, endpoint, token)
  777. if err != nil {
  778. out.Write(sf.FormatProgress(utils.TruncateID(id), "Error pulling dependent layers", nil))
  779. // FIXME: Keep going in case of error?
  780. return err
  781. }
  782. img, err := NewImgJSON(imgJSON)
  783. if err != nil {
  784. out.Write(sf.FormatProgress(utils.TruncateID(id), "Error pulling dependent layers", nil))
  785. return fmt.Errorf("Failed to parse json: %s", err)
  786. }
  787. // Get the layer
  788. out.Write(sf.FormatProgress(utils.TruncateID(id), "Pulling fs layer", nil))
  789. layer, err := r.GetRemoteImageLayer(img.ID, endpoint, token)
  790. if err != nil {
  791. out.Write(sf.FormatProgress(utils.TruncateID(id), "Error pulling dependent layers", nil))
  792. return err
  793. }
  794. defer layer.Close()
  795. if err := srv.runtime.graph.Register(imgJSON, utils.ProgressReader(layer, imgSize, out, sf, false, utils.TruncateID(id), "Downloading"), img); err != nil {
  796. out.Write(sf.FormatProgress(utils.TruncateID(id), "Error downloading dependent layers", nil))
  797. return err
  798. }
  799. }
  800. out.Write(sf.FormatProgress(utils.TruncateID(id), "Download complete", nil))
  801. }
  802. return nil
  803. }
  804. func (srv *Server) pullRepository(r *registry.Registry, out io.Writer, localName, remoteName, askedTag string, sf *utils.StreamFormatter, parallel bool) error {
  805. out.Write(sf.FormatStatus("", "Pulling repository %s", localName))
  806. repoData, err := r.GetRepositoryData(remoteName)
  807. if err != nil {
  808. return err
  809. }
  810. utils.Debugf("Retrieving the tag list")
  811. tagsList, err := r.GetRemoteTags(repoData.Endpoints, remoteName, repoData.Tokens)
  812. if err != nil {
  813. utils.Errorf("%v", err)
  814. return err
  815. }
  816. for tag, id := range tagsList {
  817. repoData.ImgList[id] = &registry.ImgData{
  818. ID: id,
  819. Tag: tag,
  820. Checksum: "",
  821. }
  822. }
  823. utils.Debugf("Registering tags")
  824. // If no tag has been specified, pull them all
  825. if askedTag == "" {
  826. for tag, id := range tagsList {
  827. repoData.ImgList[id].Tag = tag
  828. }
  829. } else {
  830. // Otherwise, check that the tag exists and use only that one
  831. id, exists := tagsList[askedTag]
  832. if !exists {
  833. return fmt.Errorf("Tag %s not found in repository %s", askedTag, localName)
  834. }
  835. repoData.ImgList[id].Tag = askedTag
  836. }
  837. errors := make(chan error)
  838. for _, image := range repoData.ImgList {
  839. downloadImage := func(img *registry.ImgData) {
  840. if askedTag != "" && img.Tag != askedTag {
  841. utils.Debugf("(%s) does not match %s (id: %s), skipping", img.Tag, askedTag, img.ID)
  842. if parallel {
  843. errors <- nil
  844. }
  845. return
  846. }
  847. if img.Tag == "" {
  848. utils.Debugf("Image (id: %s) present in this repository but untagged, skipping", img.ID)
  849. if parallel {
  850. errors <- nil
  851. }
  852. return
  853. }
  854. // ensure no two downloads of the same image happen at the same time
  855. if c, err := srv.poolAdd("pull", "img:"+img.ID); err != nil {
  856. if c != nil {
  857. out.Write(sf.FormatProgress(utils.TruncateID(img.ID), "Layer already being pulled by another client. Waiting.", nil))
  858. <-c
  859. out.Write(sf.FormatProgress(utils.TruncateID(img.ID), "Download complete", nil))
  860. } else {
  861. utils.Errorf("Image (id: %s) pull is already running, skipping: %v", img.ID, err)
  862. }
  863. if parallel {
  864. errors <- nil
  865. }
  866. return
  867. }
  868. defer srv.poolRemove("pull", "img:"+img.ID)
  869. out.Write(sf.FormatProgress(utils.TruncateID(img.ID), fmt.Sprintf("Pulling image (%s) from %s", img.Tag, localName), nil))
  870. success := false
  871. var lastErr error
  872. for _, ep := range repoData.Endpoints {
  873. out.Write(sf.FormatProgress(utils.TruncateID(img.ID), fmt.Sprintf("Pulling image (%s) from %s, endpoint: %s", img.Tag, localName, ep), nil))
  874. if err := srv.pullImage(r, out, img.ID, ep, repoData.Tokens, sf); err != nil {
  875. // Its not ideal that only the last error is returned, it would be better to concatenate the errors.
  876. // As the error is also given to the output stream the user will see the error.
  877. lastErr = err
  878. out.Write(sf.FormatProgress(utils.TruncateID(img.ID), fmt.Sprintf("Error pulling image (%s) from %s, endpoint: %s, %s", img.Tag, localName, ep, err), nil))
  879. continue
  880. }
  881. success = true
  882. break
  883. }
  884. if !success {
  885. out.Write(sf.FormatProgress(utils.TruncateID(img.ID), fmt.Sprintf("Error pulling image (%s) from %s, %s", img.Tag, localName, lastErr), nil))
  886. if parallel {
  887. errors <- fmt.Errorf("Could not find repository on any of the indexed registries.")
  888. return
  889. }
  890. }
  891. out.Write(sf.FormatProgress(utils.TruncateID(img.ID), "Download complete", nil))
  892. if parallel {
  893. errors <- nil
  894. }
  895. }
  896. if parallel {
  897. go downloadImage(image)
  898. } else {
  899. downloadImage(image)
  900. }
  901. }
  902. if parallel {
  903. var lastError error
  904. for i := 0; i < len(repoData.ImgList); i++ {
  905. if err := <-errors; err != nil {
  906. lastError = err
  907. }
  908. }
  909. if lastError != nil {
  910. return lastError
  911. }
  912. }
  913. for tag, id := range tagsList {
  914. if askedTag != "" && tag != askedTag {
  915. continue
  916. }
  917. if err := srv.runtime.repositories.Set(localName, tag, id, true); err != nil {
  918. return err
  919. }
  920. }
  921. if err := srv.runtime.repositories.Save(); err != nil {
  922. return err
  923. }
  924. return nil
  925. }
  926. func (srv *Server) poolAdd(kind, key string) (chan struct{}, error) {
  927. srv.Lock()
  928. defer srv.Unlock()
  929. if c, exists := srv.pullingPool[key]; exists {
  930. return c, fmt.Errorf("pull %s is already in progress", key)
  931. }
  932. if c, exists := srv.pushingPool[key]; exists {
  933. return c, fmt.Errorf("push %s is already in progress", key)
  934. }
  935. c := make(chan struct{})
  936. switch kind {
  937. case "pull":
  938. srv.pullingPool[key] = c
  939. case "push":
  940. srv.pushingPool[key] = c
  941. default:
  942. return nil, fmt.Errorf("Unknown pool type")
  943. }
  944. return c, nil
  945. }
  946. func (srv *Server) poolRemove(kind, key string) error {
  947. srv.Lock()
  948. defer srv.Unlock()
  949. switch kind {
  950. case "pull":
  951. if c, exists := srv.pullingPool[key]; exists {
  952. close(c)
  953. delete(srv.pullingPool, key)
  954. }
  955. case "push":
  956. if c, exists := srv.pushingPool[key]; exists {
  957. close(c)
  958. delete(srv.pushingPool, key)
  959. }
  960. default:
  961. return fmt.Errorf("Unknown pool type")
  962. }
  963. return nil
  964. }
  965. func (srv *Server) ImagePull(localName string, tag string, out io.Writer, sf *utils.StreamFormatter, authConfig *auth.AuthConfig, metaHeaders map[string][]string, parallel bool) error {
  966. out = utils.NewWriteFlusher(out)
  967. c, err := srv.poolAdd("pull", localName+":"+tag)
  968. if err != nil {
  969. if c != nil {
  970. // Another pull of the same repository is already taking place; just wait for it to finish
  971. out.Write(sf.FormatStatus("", "Repository %s already being pulled by another client. Waiting.", localName))
  972. <-c
  973. return nil
  974. }
  975. return err
  976. }
  977. defer srv.poolRemove("pull", localName+":"+tag)
  978. // Resolve the Repository name from fqn to endpoint + name
  979. endpoint, remoteName, err := registry.ResolveRepositoryName(localName)
  980. if err != nil {
  981. return err
  982. }
  983. r, err := registry.NewRegistry(authConfig, srv.HTTPRequestFactory(metaHeaders), endpoint)
  984. if err != nil {
  985. return err
  986. }
  987. if endpoint == auth.IndexServerAddress() {
  988. // If pull "index.docker.io/foo/bar", it's stored locally under "foo/bar"
  989. localName = remoteName
  990. }
  991. if err = srv.pullRepository(r, out, localName, remoteName, tag, sf, parallel); err != nil {
  992. return err
  993. }
  994. return nil
  995. }
  996. // Retrieve the all the images to be uploaded in the correct order
  997. // Note: we can't use a map as it is not ordered
  998. func (srv *Server) getImageList(localRepo map[string]string) ([][]*registry.ImgData, error) {
  999. imgList := map[string]*registry.ImgData{}
  1000. depGraph := utils.NewDependencyGraph()
  1001. for tag, id := range localRepo {
  1002. img, err := srv.runtime.graph.Get(id)
  1003. if err != nil {
  1004. return nil, err
  1005. }
  1006. depGraph.NewNode(img.ID)
  1007. img.WalkHistory(func(current *Image) error {
  1008. imgList[current.ID] = &registry.ImgData{
  1009. ID: current.ID,
  1010. Tag: tag,
  1011. }
  1012. parent, err := current.GetParent()
  1013. if err != nil {
  1014. return err
  1015. }
  1016. if parent == nil {
  1017. return nil
  1018. }
  1019. depGraph.NewNode(parent.ID)
  1020. depGraph.AddDependency(current.ID, parent.ID)
  1021. return nil
  1022. })
  1023. }
  1024. traversalMap, err := depGraph.GenerateTraversalMap()
  1025. if err != nil {
  1026. return nil, err
  1027. }
  1028. utils.Debugf("Traversal map: %v", traversalMap)
  1029. result := [][]*registry.ImgData{}
  1030. for _, round := range traversalMap {
  1031. dataRound := []*registry.ImgData{}
  1032. for _, imgID := range round {
  1033. dataRound = append(dataRound, imgList[imgID])
  1034. }
  1035. result = append(result, dataRound)
  1036. }
  1037. return result, nil
  1038. }
  1039. func flatten(slc [][]*registry.ImgData) []*registry.ImgData {
  1040. result := []*registry.ImgData{}
  1041. for _, x := range slc {
  1042. result = append(result, x...)
  1043. }
  1044. return result
  1045. }
  1046. func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, localName, remoteName string, localRepo map[string]string, sf *utils.StreamFormatter) error {
  1047. out = utils.NewWriteFlusher(out)
  1048. imgList, err := srv.getImageList(localRepo)
  1049. if err != nil {
  1050. return err
  1051. }
  1052. flattenedImgList := flatten(imgList)
  1053. out.Write(sf.FormatStatus("", "Sending image list"))
  1054. var repoData *registry.RepositoryData
  1055. repoData, err = r.PushImageJSONIndex(remoteName, flattenedImgList, false, nil)
  1056. if err != nil {
  1057. return err
  1058. }
  1059. for _, ep := range repoData.Endpoints {
  1060. out.Write(sf.FormatStatus("", "Pushing repository %s (%d tags)", localName, len(localRepo)))
  1061. // This section can not be parallelized (each round depends on the previous one)
  1062. for i, round := range imgList {
  1063. // FIXME: This section can be parallelized
  1064. for _, elem := range round {
  1065. var pushTags func() error
  1066. pushTags = func() error {
  1067. if i < (len(imgList) - 1) {
  1068. // Only tag the top layer in the repository
  1069. return nil
  1070. }
  1071. out.Write(sf.FormatStatus("", "Pushing tags for rev [%s] on {%s}", utils.TruncateID(elem.ID), ep+"repositories/"+remoteName+"/tags/"+elem.Tag))
  1072. if err := r.PushRegistryTag(remoteName, elem.ID, elem.Tag, ep, repoData.Tokens); err != nil {
  1073. return err
  1074. }
  1075. return nil
  1076. }
  1077. if _, exists := repoData.ImgList[elem.ID]; exists {
  1078. if err := pushTags(); err != nil {
  1079. return err
  1080. }
  1081. out.Write(sf.FormatProgress(utils.TruncateID(elem.ID), "Image already pushed, skipping", nil))
  1082. continue
  1083. } else if r.LookupRemoteImage(elem.ID, ep, repoData.Tokens) {
  1084. if err := pushTags(); err != nil {
  1085. return err
  1086. }
  1087. out.Write(sf.FormatProgress(utils.TruncateID(elem.ID), "Image already pushed, skipping", nil))
  1088. continue
  1089. }
  1090. checksum, err := srv.pushImage(r, out, remoteName, elem.ID, ep, repoData.Tokens, sf)
  1091. if err != nil {
  1092. // FIXME: Continue on error?
  1093. return err
  1094. }
  1095. elem.Checksum = checksum
  1096. if err := pushTags(); err != nil {
  1097. return err
  1098. }
  1099. }
  1100. }
  1101. }
  1102. if _, err := r.PushImageJSONIndex(remoteName, flattenedImgList, true, repoData.Endpoints); err != nil {
  1103. return err
  1104. }
  1105. return nil
  1106. }
  1107. func (srv *Server) pushImage(r *registry.Registry, out io.Writer, remote, imgID, ep string, token []string, sf *utils.StreamFormatter) (checksum string, err error) {
  1108. out = utils.NewWriteFlusher(out)
  1109. jsonRaw, err := ioutil.ReadFile(path.Join(srv.runtime.graph.Root, imgID, "json"))
  1110. if err != nil {
  1111. return "", fmt.Errorf("Cannot retrieve the path for {%s}: %s", imgID, err)
  1112. }
  1113. out.Write(sf.FormatProgress(utils.TruncateID(imgID), "Pushing", nil))
  1114. imgData := &registry.ImgData{
  1115. ID: imgID,
  1116. }
  1117. // Send the json
  1118. if err := r.PushImageJSONRegistry(imgData, jsonRaw, ep, token); err != nil {
  1119. if err == registry.ErrAlreadyExists {
  1120. out.Write(sf.FormatProgress(utils.TruncateID(imgData.ID), "Image already pushed, skipping", nil))
  1121. return "", nil
  1122. }
  1123. return "", err
  1124. }
  1125. layerData, err := srv.runtime.graph.TempLayerArchive(imgID, archive.Uncompressed, sf, out)
  1126. if err != nil {
  1127. return "", fmt.Errorf("Failed to generate layer archive: %s", err)
  1128. }
  1129. defer os.RemoveAll(layerData.Name())
  1130. // Send the layer
  1131. checksum, err = r.PushImageLayerRegistry(imgData.ID, utils.ProgressReader(layerData, int(layerData.Size), out, sf, false, utils.TruncateID(imgData.ID), "Pushing"), ep, token, jsonRaw)
  1132. if err != nil {
  1133. return "", err
  1134. }
  1135. imgData.Checksum = checksum
  1136. // Send the checksum
  1137. if err := r.PushImageChecksumRegistry(imgData, ep, token); err != nil {
  1138. return "", err
  1139. }
  1140. return imgData.Checksum, nil
  1141. }
  1142. // FIXME: Allow to interrupt current push when new push of same image is done.
  1143. func (srv *Server) ImagePush(localName string, out io.Writer, sf *utils.StreamFormatter, authConfig *auth.AuthConfig, metaHeaders map[string][]string) error {
  1144. if _, err := srv.poolAdd("push", localName); err != nil {
  1145. return err
  1146. }
  1147. defer srv.poolRemove("push", localName)
  1148. // Resolve the Repository name from fqn to endpoint + name
  1149. endpoint, remoteName, err := registry.ResolveRepositoryName(localName)
  1150. if err != nil {
  1151. return err
  1152. }
  1153. out = utils.NewWriteFlusher(out)
  1154. img, err := srv.runtime.graph.Get(localName)
  1155. r, err2 := registry.NewRegistry(authConfig, srv.HTTPRequestFactory(metaHeaders), endpoint)
  1156. if err2 != nil {
  1157. return err2
  1158. }
  1159. if err != nil {
  1160. reposLen := len(srv.runtime.repositories.Repositories[localName])
  1161. out.Write(sf.FormatStatus("", "The push refers to a repository [%s] (len: %d)", localName, reposLen))
  1162. // If it fails, try to get the repository
  1163. if localRepo, exists := srv.runtime.repositories.Repositories[localName]; exists {
  1164. if err := srv.pushRepository(r, out, localName, remoteName, localRepo, sf); err != nil {
  1165. return err
  1166. }
  1167. return nil
  1168. }
  1169. return err
  1170. }
  1171. var token []string
  1172. out.Write(sf.FormatStatus("", "The push refers to an image: [%s]", localName))
  1173. if _, err := srv.pushImage(r, out, remoteName, img.ID, endpoint, token, sf); err != nil {
  1174. return err
  1175. }
  1176. return nil
  1177. }
  1178. func (srv *Server) ImageImport(src, repo, tag string, in io.Reader, out io.Writer, sf *utils.StreamFormatter) error {
  1179. var archive io.Reader
  1180. var resp *http.Response
  1181. if src == "-" {
  1182. archive = in
  1183. } else {
  1184. u, err := url.Parse(src)
  1185. if err != nil {
  1186. return err
  1187. }
  1188. if u.Scheme == "" {
  1189. u.Scheme = "http"
  1190. u.Host = src
  1191. u.Path = ""
  1192. }
  1193. out.Write(sf.FormatStatus("", "Downloading from %s", u))
  1194. // Download with curl (pretty progress bar)
  1195. // If curl is not available, fallback to http.Get()
  1196. resp, err = utils.Download(u.String())
  1197. if err != nil {
  1198. return err
  1199. }
  1200. archive = utils.ProgressReader(resp.Body, int(resp.ContentLength), out, sf, true, "", "Importing")
  1201. }
  1202. img, err := srv.runtime.graph.Create(archive, nil, "Imported from "+src, "", nil)
  1203. if err != nil {
  1204. return err
  1205. }
  1206. // Optionally register the image at REPO/TAG
  1207. if repo != "" {
  1208. if err := srv.runtime.repositories.Set(repo, tag, img.ID, true); err != nil {
  1209. return err
  1210. }
  1211. }
  1212. out.Write(sf.FormatStatus("", img.ID))
  1213. return nil
  1214. }
  1215. func (srv *Server) ContainerCreate(job *engine.Job) engine.Status {
  1216. var name string
  1217. if len(job.Args) == 1 {
  1218. name = job.Args[0]
  1219. } else if len(job.Args) > 1 {
  1220. job.Printf("Usage: %s", job.Name)
  1221. return engine.StatusErr
  1222. }
  1223. var config Config
  1224. if err := job.ExportEnv(&config); err != nil {
  1225. job.Error(err)
  1226. return engine.StatusErr
  1227. }
  1228. if config.Memory != 0 && config.Memory < 524288 {
  1229. job.Errorf("Minimum memory limit allowed is 512k")
  1230. return engine.StatusErr
  1231. }
  1232. if config.Memory > 0 && !srv.runtime.capabilities.MemoryLimit {
  1233. config.Memory = 0
  1234. }
  1235. if config.Memory > 0 && !srv.runtime.capabilities.SwapLimit {
  1236. config.MemorySwap = -1
  1237. }
  1238. container, buildWarnings, err := srv.runtime.Create(&config, name)
  1239. if err != nil {
  1240. if srv.runtime.graph.IsNotExist(err) {
  1241. _, tag := utils.ParseRepositoryTag(config.Image)
  1242. if tag == "" {
  1243. tag = DEFAULTTAG
  1244. }
  1245. job.Errorf("No such image: %s (tag: %s)", config.Image, tag)
  1246. return engine.StatusErr
  1247. }
  1248. job.Error(err)
  1249. return engine.StatusErr
  1250. }
  1251. srv.LogEvent("create", container.ID, srv.runtime.repositories.ImageName(container.Image))
  1252. // FIXME: this is necessary because runtime.Create might return a nil container
  1253. // with a non-nil error. This should not happen! Once it's fixed we
  1254. // can remove this workaround.
  1255. if container != nil {
  1256. job.Printf("%s\n", container.ID)
  1257. }
  1258. for _, warning := range buildWarnings {
  1259. job.Errorf("%s\n", warning)
  1260. }
  1261. return engine.StatusOK
  1262. }
  1263. func (srv *Server) ContainerRestart(name string, t int) error {
  1264. if container := srv.runtime.Get(name); container != nil {
  1265. if err := container.Restart(t); err != nil {
  1266. return fmt.Errorf("Cannot restart container %s: %s", name, err)
  1267. }
  1268. srv.LogEvent("restart", container.ID, srv.runtime.repositories.ImageName(container.Image))
  1269. } else {
  1270. return fmt.Errorf("No such container: %s", name)
  1271. }
  1272. return nil
  1273. }
  1274. func (srv *Server) ContainerDestroy(name string, removeVolume, removeLink bool) error {
  1275. container := srv.runtime.Get(name)
  1276. if removeLink {
  1277. if container == nil {
  1278. return fmt.Errorf("No such link: %s", name)
  1279. }
  1280. name, err := srv.runtime.getFullName(name)
  1281. if err != nil {
  1282. return err
  1283. }
  1284. parent, n := path.Split(name)
  1285. if parent == "/" {
  1286. return fmt.Errorf("Conflict, cannot remove the default name of the container")
  1287. }
  1288. pe := srv.runtime.containerGraph.Get(parent)
  1289. if pe == nil {
  1290. return fmt.Errorf("Cannot get parent %s for name %s", parent, name)
  1291. }
  1292. parentContainer := srv.runtime.Get(pe.ID())
  1293. if parentContainer != nil && parentContainer.activeLinks != nil {
  1294. if link, exists := parentContainer.activeLinks[n]; exists {
  1295. link.Disable()
  1296. } else {
  1297. utils.Debugf("Could not find active link for %s", name)
  1298. }
  1299. }
  1300. if err := srv.runtime.containerGraph.Delete(name); err != nil {
  1301. return err
  1302. }
  1303. return nil
  1304. }
  1305. if container != nil {
  1306. if container.State.IsRunning() {
  1307. return fmt.Errorf("Impossible to remove a running container, please stop it first")
  1308. }
  1309. volumes := make(map[string]struct{})
  1310. binds := make(map[string]struct{})
  1311. for _, bind := range container.hostConfig.Binds {
  1312. splitBind := strings.Split(bind, ":")
  1313. source := splitBind[0]
  1314. binds[source] = struct{}{}
  1315. }
  1316. // Store all the deleted containers volumes
  1317. for _, volumeId := range container.Volumes {
  1318. // Skip the volumes mounted from external
  1319. if _, exists := binds[volumeId]; exists {
  1320. continue
  1321. }
  1322. volumeId = strings.TrimSuffix(volumeId, "/layer")
  1323. volumeId = filepath.Base(volumeId)
  1324. volumes[volumeId] = struct{}{}
  1325. }
  1326. if err := srv.runtime.Destroy(container); err != nil {
  1327. return fmt.Errorf("Cannot destroy container %s: %s", name, err)
  1328. }
  1329. srv.LogEvent("destroy", container.ID, srv.runtime.repositories.ImageName(container.Image))
  1330. if removeVolume {
  1331. // Retrieve all volumes from all remaining containers
  1332. usedVolumes := make(map[string]*Container)
  1333. for _, container := range srv.runtime.List() {
  1334. for _, containerVolumeId := range container.Volumes {
  1335. usedVolumes[containerVolumeId] = container
  1336. }
  1337. }
  1338. for volumeId := range volumes {
  1339. // If the requested volu
  1340. if c, exists := usedVolumes[volumeId]; exists {
  1341. log.Printf("The volume %s is used by the container %s. Impossible to remove it. Skipping.\n", volumeId, c.ID)
  1342. continue
  1343. }
  1344. if err := srv.runtime.volumes.Delete(volumeId); err != nil {
  1345. return err
  1346. }
  1347. }
  1348. }
  1349. } else {
  1350. return fmt.Errorf("No such container: %s", name)
  1351. }
  1352. return nil
  1353. }
  1354. var ErrImageReferenced = errors.New("Image referenced by a repository")
  1355. func (srv *Server) deleteImageAndChildren(id string, imgs *[]APIRmi, byParents map[string][]*Image) error {
  1356. // If the image is referenced by a repo, do not delete
  1357. if len(srv.runtime.repositories.ByID()[id]) != 0 {
  1358. return ErrImageReferenced
  1359. }
  1360. // If the image is not referenced but has children, go recursive
  1361. referenced := false
  1362. for _, img := range byParents[id] {
  1363. if err := srv.deleteImageAndChildren(img.ID, imgs, byParents); err != nil {
  1364. if err != ErrImageReferenced {
  1365. return err
  1366. }
  1367. referenced = true
  1368. }
  1369. }
  1370. if referenced {
  1371. return ErrImageReferenced
  1372. }
  1373. // If the image is not referenced and has no children, remove it
  1374. byParents, err := srv.runtime.graph.ByParent()
  1375. if err != nil {
  1376. return err
  1377. }
  1378. if len(byParents[id]) == 0 {
  1379. if err := srv.runtime.repositories.DeleteAll(id); err != nil {
  1380. return err
  1381. }
  1382. err := srv.runtime.graph.Delete(id)
  1383. if err != nil {
  1384. return err
  1385. }
  1386. *imgs = append(*imgs, APIRmi{Deleted: id})
  1387. srv.LogEvent("delete", id, "")
  1388. return nil
  1389. }
  1390. return nil
  1391. }
  1392. func (srv *Server) deleteImageParents(img *Image, imgs *[]APIRmi) error {
  1393. if img.Parent != "" {
  1394. parent, err := srv.runtime.graph.Get(img.Parent)
  1395. if err != nil {
  1396. return err
  1397. }
  1398. byParents, err := srv.runtime.graph.ByParent()
  1399. if err != nil {
  1400. return err
  1401. }
  1402. // Remove all children images
  1403. if err := srv.deleteImageAndChildren(img.Parent, imgs, byParents); err != nil {
  1404. return err
  1405. }
  1406. return srv.deleteImageParents(parent, imgs)
  1407. }
  1408. return nil
  1409. }
  1410. func (srv *Server) deleteImage(img *Image, repoName, tag string) ([]APIRmi, error) {
  1411. var (
  1412. imgs = []APIRmi{}
  1413. tags = []string{}
  1414. )
  1415. //If delete by id, see if the id belong only to one repository
  1416. if repoName == "" {
  1417. for _, repoAndTag := range srv.runtime.repositories.ByID()[img.ID] {
  1418. parsedRepo, parsedTag := utils.ParseRepositoryTag(repoAndTag)
  1419. if repoName == "" || repoName == parsedRepo {
  1420. repoName = parsedRepo
  1421. if parsedTag != "" {
  1422. tags = append(tags, parsedTag)
  1423. }
  1424. } else if repoName != parsedRepo {
  1425. // the id belongs to multiple repos, like base:latest and user:test,
  1426. // in that case return conflict
  1427. return imgs, nil
  1428. }
  1429. }
  1430. } else {
  1431. tags = append(tags, tag)
  1432. }
  1433. //Untag the current image
  1434. for _, tag := range tags {
  1435. tagDeleted, err := srv.runtime.repositories.Delete(repoName, tag)
  1436. if err != nil {
  1437. return nil, err
  1438. }
  1439. if tagDeleted {
  1440. imgs = append(imgs, APIRmi{Untagged: img.ID})
  1441. srv.LogEvent("untag", img.ID, "")
  1442. }
  1443. }
  1444. if len(srv.runtime.repositories.ByID()[img.ID]) == 0 {
  1445. if err := srv.deleteImageAndChildren(img.ID, &imgs, nil); err != nil {
  1446. if err != ErrImageReferenced {
  1447. return imgs, err
  1448. }
  1449. } else if err := srv.deleteImageParents(img, &imgs); err != nil {
  1450. if err != ErrImageReferenced {
  1451. return imgs, err
  1452. }
  1453. }
  1454. }
  1455. return imgs, nil
  1456. }
  1457. func (srv *Server) ImageDelete(name string, autoPrune bool) ([]APIRmi, error) {
  1458. var (
  1459. repository, tag string
  1460. validate = true
  1461. )
  1462. img, err := srv.runtime.repositories.LookupImage(name)
  1463. if err != nil {
  1464. return nil, fmt.Errorf("No such image: %s", name)
  1465. }
  1466. // FIXME: What does autoPrune mean ?
  1467. if !autoPrune {
  1468. if err := srv.runtime.graph.Delete(img.ID); err != nil {
  1469. return nil, fmt.Errorf("Cannot delete image %s: %s", name, err)
  1470. }
  1471. return nil, nil
  1472. }
  1473. if !strings.Contains(img.ID, name) {
  1474. repository, tag = utils.ParseRepositoryTag(name)
  1475. }
  1476. // If we have a repo and the image is not referenced anywhere else
  1477. // then just perform an untag and do not validate.
  1478. //
  1479. // i.e. only validate if we are performing an actual delete and not
  1480. // an untag op
  1481. if repository != "" {
  1482. validate = len(srv.runtime.repositories.ByID()[img.ID]) == 1
  1483. }
  1484. if validate {
  1485. // Prevent deletion if image is used by a container
  1486. for _, container := range srv.runtime.List() {
  1487. parent, err := srv.runtime.repositories.LookupImage(container.Image)
  1488. if err != nil {
  1489. return nil, err
  1490. }
  1491. if err := parent.WalkHistory(func(p *Image) error {
  1492. if img.ID == p.ID {
  1493. return fmt.Errorf("Conflict, cannot delete %s because the container %s is using it", name, container.ID)
  1494. }
  1495. return nil
  1496. }); err != nil {
  1497. return nil, err
  1498. }
  1499. }
  1500. }
  1501. return srv.deleteImage(img, repository, tag)
  1502. }
  1503. func (srv *Server) ImageGetCached(imgID string, config *Config) (*Image, error) {
  1504. // Retrieve all images
  1505. images, err := srv.runtime.graph.Map()
  1506. if err != nil {
  1507. return nil, err
  1508. }
  1509. // Store the tree in a map of map (map[parentId][childId])
  1510. imageMap := make(map[string]map[string]struct{})
  1511. for _, img := range images {
  1512. if _, exists := imageMap[img.Parent]; !exists {
  1513. imageMap[img.Parent] = make(map[string]struct{})
  1514. }
  1515. imageMap[img.Parent][img.ID] = struct{}{}
  1516. }
  1517. // Loop on the children of the given image and check the config
  1518. for elem := range imageMap[imgID] {
  1519. img, err := srv.runtime.graph.Get(elem)
  1520. if err != nil {
  1521. return nil, err
  1522. }
  1523. if CompareConfig(&img.ContainerConfig, config) {
  1524. return img, nil
  1525. }
  1526. }
  1527. return nil, nil
  1528. }
  1529. func (srv *Server) RegisterLinks(name string, hostConfig *HostConfig) error {
  1530. runtime := srv.runtime
  1531. container := runtime.Get(name)
  1532. if container == nil {
  1533. return fmt.Errorf("No such container: %s", name)
  1534. }
  1535. if hostConfig != nil && hostConfig.Links != nil {
  1536. for _, l := range hostConfig.Links {
  1537. parts, err := parseLink(l)
  1538. if err != nil {
  1539. return err
  1540. }
  1541. child, err := srv.runtime.GetByName(parts["name"])
  1542. if err != nil {
  1543. return err
  1544. }
  1545. if child == nil {
  1546. return fmt.Errorf("Could not get container for %s", parts["name"])
  1547. }
  1548. if err := runtime.RegisterLink(container, child, parts["alias"]); err != nil {
  1549. return err
  1550. }
  1551. }
  1552. // After we load all the links into the runtime
  1553. // set them to nil on the hostconfig
  1554. hostConfig.Links = nil
  1555. if err := container.writeHostConfig(); err != nil {
  1556. return err
  1557. }
  1558. }
  1559. return nil
  1560. }
  1561. func (srv *Server) ContainerStart(job *engine.Job) engine.Status {
  1562. if len(job.Args) < 1 {
  1563. job.Errorf("Usage: %s container_id", job.Name)
  1564. return engine.StatusErr
  1565. }
  1566. name := job.Args[0]
  1567. runtime := srv.runtime
  1568. container := runtime.Get(name)
  1569. if container == nil {
  1570. job.Errorf("No such container: %s", name)
  1571. return engine.StatusErr
  1572. }
  1573. // If no environment was set, then no hostconfig was passed.
  1574. if len(job.Environ()) > 0 {
  1575. var hostConfig HostConfig
  1576. if err := job.ExportEnv(&hostConfig); err != nil {
  1577. job.Error(err)
  1578. return engine.StatusErr
  1579. }
  1580. // Validate the HostConfig binds. Make sure that:
  1581. // 1) the source of a bind mount isn't /
  1582. // The bind mount "/:/foo" isn't allowed.
  1583. // 2) Check that the source exists
  1584. // The source to be bind mounted must exist.
  1585. for _, bind := range hostConfig.Binds {
  1586. splitBind := strings.Split(bind, ":")
  1587. source := splitBind[0]
  1588. // refuse to bind mount "/" to the container
  1589. if source == "/" {
  1590. job.Errorf("Invalid bind mount '%s' : source can't be '/'", bind)
  1591. return engine.StatusErr
  1592. }
  1593. // ensure the source exists on the host
  1594. _, err := os.Stat(source)
  1595. if err != nil && os.IsNotExist(err) {
  1596. job.Errorf("Invalid bind mount '%s' : source doesn't exist", bind)
  1597. return engine.StatusErr
  1598. }
  1599. }
  1600. // Register any links from the host config before starting the container
  1601. // FIXME: we could just pass the container here, no need to lookup by name again.
  1602. if err := srv.RegisterLinks(name, &hostConfig); err != nil {
  1603. job.Error(err)
  1604. return engine.StatusErr
  1605. }
  1606. container.hostConfig = &hostConfig
  1607. container.ToDisk()
  1608. }
  1609. if err := container.Start(); err != nil {
  1610. job.Errorf("Cannot start container %s: %s", name, err)
  1611. return engine.StatusErr
  1612. }
  1613. srv.LogEvent("start", container.ID, runtime.repositories.ImageName(container.Image))
  1614. return engine.StatusOK
  1615. }
  1616. func (srv *Server) ContainerStop(job *engine.Job) engine.Status {
  1617. if len(job.Args) != 1 {
  1618. job.Errorf("Usage: %s CONTAINER\n", job.Name)
  1619. return engine.StatusErr
  1620. }
  1621. name := job.Args[0]
  1622. t := job.GetenvInt("t")
  1623. if t == -1 {
  1624. t = 10
  1625. }
  1626. if container := srv.runtime.Get(name); container != nil {
  1627. if err := container.Stop(int(t)); err != nil {
  1628. job.Errorf("Cannot stop container %s: %s\n", name, err)
  1629. return engine.StatusErr
  1630. }
  1631. srv.LogEvent("stop", container.ID, srv.runtime.repositories.ImageName(container.Image))
  1632. } else {
  1633. job.Errorf("No such container: %s\n", name)
  1634. return engine.StatusErr
  1635. }
  1636. return engine.StatusOK
  1637. }
  1638. func (srv *Server) ContainerWait(job *engine.Job) engine.Status {
  1639. if len(job.Args) != 1 {
  1640. job.Errorf("Usage: %s", job.Name)
  1641. return engine.StatusErr
  1642. }
  1643. name := job.Args[0]
  1644. if container := srv.runtime.Get(name); container != nil {
  1645. status := container.Wait()
  1646. job.Printf("%d\n", status)
  1647. return engine.StatusOK
  1648. }
  1649. job.Errorf("%s: no such container: %s", job.Name, name)
  1650. return engine.StatusErr
  1651. }
  1652. func (srv *Server) ContainerResize(job *engine.Job) engine.Status {
  1653. if len(job.Args) != 3 {
  1654. job.Errorf("Not enough arguments. Usage: %s CONTAINER HEIGHT WIDTH\n", job.Name)
  1655. return engine.StatusErr
  1656. }
  1657. name := job.Args[0]
  1658. height, err := strconv.Atoi(job.Args[1])
  1659. if err != nil {
  1660. job.Error(err)
  1661. return engine.StatusErr
  1662. }
  1663. width, err := strconv.Atoi(job.Args[2])
  1664. if err != nil {
  1665. job.Error(err)
  1666. return engine.StatusErr
  1667. }
  1668. if container := srv.runtime.Get(name); container != nil {
  1669. if err := container.Resize(height, width); err != nil {
  1670. job.Error(err)
  1671. return engine.StatusErr
  1672. }
  1673. return engine.StatusOK
  1674. }
  1675. job.Errorf("No such container: %s", name)
  1676. return engine.StatusErr
  1677. }
  1678. func (srv *Server) ContainerAttach(name string, logs, stream, stdin, stdout, stderr bool, inStream io.ReadCloser, outStream, errStream io.Writer) error {
  1679. container := srv.runtime.Get(name)
  1680. if container == nil {
  1681. return fmt.Errorf("No such container: %s", name)
  1682. }
  1683. //logs
  1684. if logs {
  1685. cLog, err := container.ReadLog("json")
  1686. if err != nil && os.IsNotExist(err) {
  1687. // Legacy logs
  1688. utils.Errorf("Old logs format")
  1689. if stdout {
  1690. cLog, err := container.ReadLog("stdout")
  1691. if err != nil {
  1692. utils.Errorf("Error reading logs (stdout): %s", err)
  1693. } else if _, err := io.Copy(outStream, cLog); err != nil {
  1694. utils.Errorf("Error streaming logs (stdout): %s", err)
  1695. }
  1696. }
  1697. if stderr {
  1698. cLog, err := container.ReadLog("stderr")
  1699. if err != nil {
  1700. utils.Errorf("Error reading logs (stderr): %s", err)
  1701. } else if _, err := io.Copy(errStream, cLog); err != nil {
  1702. utils.Errorf("Error streaming logs (stderr): %s", err)
  1703. }
  1704. }
  1705. } else if err != nil {
  1706. utils.Errorf("Error reading logs (json): %s", err)
  1707. } else {
  1708. dec := json.NewDecoder(cLog)
  1709. for {
  1710. l := &utils.JSONLog{}
  1711. if err := dec.Decode(l); err == io.EOF {
  1712. break
  1713. } else if err != nil {
  1714. utils.Errorf("Error streaming logs: %s", err)
  1715. break
  1716. }
  1717. if l.Stream == "stdout" && stdout {
  1718. fmt.Fprintf(outStream, "%s", l.Log)
  1719. }
  1720. if l.Stream == "stderr" && stderr {
  1721. fmt.Fprintf(errStream, "%s", l.Log)
  1722. }
  1723. }
  1724. }
  1725. }
  1726. //stream
  1727. if stream {
  1728. if container.State.IsGhost() {
  1729. return fmt.Errorf("Impossible to attach to a ghost container")
  1730. }
  1731. var (
  1732. cStdin io.ReadCloser
  1733. cStdout, cStderr io.Writer
  1734. cStdinCloser io.Closer
  1735. )
  1736. if stdin {
  1737. r, w := io.Pipe()
  1738. go func() {
  1739. defer w.Close()
  1740. defer utils.Debugf("Closing buffered stdin pipe")
  1741. io.Copy(w, inStream)
  1742. }()
  1743. cStdin = r
  1744. cStdinCloser = inStream
  1745. }
  1746. if stdout {
  1747. cStdout = outStream
  1748. }
  1749. if stderr {
  1750. cStderr = errStream
  1751. }
  1752. <-container.Attach(cStdin, cStdinCloser, cStdout, cStderr)
  1753. // If we are in stdinonce mode, wait for the process to end
  1754. // otherwise, simply return
  1755. if container.Config.StdinOnce && !container.Config.Tty {
  1756. container.Wait()
  1757. }
  1758. }
  1759. return nil
  1760. }
  1761. func (srv *Server) ContainerInspect(name string) (*Container, error) {
  1762. if container := srv.runtime.Get(name); container != nil {
  1763. return container, nil
  1764. }
  1765. return nil, fmt.Errorf("No such container: %s", name)
  1766. }
  1767. func (srv *Server) ImageInspect(name string) (*Image, error) {
  1768. if image, err := srv.runtime.repositories.LookupImage(name); err == nil && image != nil {
  1769. return image, nil
  1770. }
  1771. return nil, fmt.Errorf("No such image: %s", name)
  1772. }
  1773. func (srv *Server) ContainerCopy(name string, resource string, out io.Writer) error {
  1774. if container := srv.runtime.Get(name); container != nil {
  1775. data, err := container.Copy(resource)
  1776. if err != nil {
  1777. return err
  1778. }
  1779. if _, err := io.Copy(out, data); err != nil {
  1780. return err
  1781. }
  1782. return nil
  1783. }
  1784. return fmt.Errorf("No such container: %s", name)
  1785. }
  1786. func NewServer(eng *engine.Engine, config *DaemonConfig) (*Server, error) {
  1787. runtime, err := NewRuntime(config)
  1788. if err != nil {
  1789. return nil, err
  1790. }
  1791. srv := &Server{
  1792. Eng: eng,
  1793. runtime: runtime,
  1794. pullingPool: make(map[string]chan struct{}),
  1795. pushingPool: make(map[string]chan struct{}),
  1796. events: make([]utils.JSONMessage, 0, 64), //only keeps the 64 last events
  1797. listeners: make(map[string]chan utils.JSONMessage),
  1798. }
  1799. runtime.srv = srv
  1800. return srv, nil
  1801. }
  1802. func (srv *Server) HTTPRequestFactory(metaHeaders map[string][]string) *utils.HTTPRequestFactory {
  1803. srv.Lock()
  1804. defer srv.Unlock()
  1805. v := dockerVersion()
  1806. httpVersion := make([]utils.VersionInfo, 0, 4)
  1807. httpVersion = append(httpVersion, &simpleVersionInfo{"docker", v.Get("Version")})
  1808. httpVersion = append(httpVersion, &simpleVersionInfo{"go", v.Get("GoVersion")})
  1809. httpVersion = append(httpVersion, &simpleVersionInfo{"git-commit", v.Get("GitCommit")})
  1810. httpVersion = append(httpVersion, &simpleVersionInfo{"kernel", v.Get("KernelVersion")})
  1811. ud := utils.NewHTTPUserAgentDecorator(httpVersion...)
  1812. md := &utils.HTTPMetaHeadersDecorator{
  1813. Headers: metaHeaders,
  1814. }
  1815. factory := utils.NewHTTPRequestFactory(ud, md)
  1816. return factory
  1817. }
  1818. func (srv *Server) LogEvent(action, id, from string) *utils.JSONMessage {
  1819. now := time.Now().UTC().Unix()
  1820. jm := utils.JSONMessage{Status: action, ID: id, From: from, Time: now}
  1821. srv.AddEvent(jm)
  1822. for _, c := range srv.listeners {
  1823. select { // non blocking channel
  1824. case c <- jm:
  1825. default:
  1826. }
  1827. }
  1828. return &jm
  1829. }
  1830. func (srv *Server) AddEvent(jm utils.JSONMessage) {
  1831. srv.Lock()
  1832. defer srv.Unlock()
  1833. srv.events = append(srv.events, jm)
  1834. }
  1835. func (srv *Server) GetEvents() []utils.JSONMessage {
  1836. srv.RLock()
  1837. defer srv.RUnlock()
  1838. return srv.events
  1839. }
  1840. type Server struct {
  1841. sync.RWMutex
  1842. runtime *Runtime
  1843. pullingPool map[string]chan struct{}
  1844. pushingPool map[string]chan struct{}
  1845. events []utils.JSONMessage
  1846. listeners map[string]chan utils.JSONMessage
  1847. Eng *engine.Engine
  1848. }