server.go 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425
  1. package docker
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "github.com/dotcloud/docker/archive"
  7. "github.com/dotcloud/docker/auth"
  8. "github.com/dotcloud/docker/dockerversion"
  9. "github.com/dotcloud/docker/engine"
  10. "github.com/dotcloud/docker/pkg/graphdb"
  11. "github.com/dotcloud/docker/registry"
  12. "github.com/dotcloud/docker/runconfig"
  13. "github.com/dotcloud/docker/utils"
  14. "io"
  15. "io/ioutil"
  16. "log"
  17. "net/http"
  18. "net/url"
  19. "os"
  20. "os/exec"
  21. "os/signal"
  22. "path"
  23. "path/filepath"
  24. "runtime"
  25. "strconv"
  26. "strings"
  27. "sync"
  28. "syscall"
  29. "time"
  30. )
  31. func (srv *Server) Close() error {
  32. return srv.runtime.Close()
  33. }
  34. // jobInitApi runs the remote api server `srv` as a daemon,
  35. // Only one api server can run at the same time - this is enforced by a pidfile.
  36. // The signals SIGINT, SIGQUIT and SIGTERM are intercepted for cleanup.
  37. func InitServer(job *engine.Job) engine.Status {
  38. job.Logf("Creating server")
  39. srv, err := NewServer(job.Eng, DaemonConfigFromJob(job))
  40. if err != nil {
  41. return job.Error(err)
  42. }
  43. if srv.runtime.config.Pidfile != "" {
  44. job.Logf("Creating pidfile")
  45. if err := utils.CreatePidFile(srv.runtime.config.Pidfile); err != nil {
  46. // FIXME: do we need fatal here instead of returning a job error?
  47. log.Fatal(err)
  48. }
  49. }
  50. job.Logf("Setting up signal traps")
  51. c := make(chan os.Signal, 1)
  52. signal.Notify(c, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
  53. go func() {
  54. sig := <-c
  55. log.Printf("Received signal '%v', exiting\n", sig)
  56. utils.RemovePidFile(srv.runtime.config.Pidfile)
  57. srv.Close()
  58. os.Exit(0)
  59. }()
  60. job.Eng.Hack_SetGlobalVar("httpapi.server", srv)
  61. job.Eng.Hack_SetGlobalVar("httpapi.runtime", srv.runtime)
  62. for name, handler := range map[string]engine.Handler{
  63. "export": srv.ContainerExport,
  64. "create": srv.ContainerCreate,
  65. "stop": srv.ContainerStop,
  66. "restart": srv.ContainerRestart,
  67. "start": srv.ContainerStart,
  68. "kill": srv.ContainerKill,
  69. "wait": srv.ContainerWait,
  70. "tag": srv.ImageTag,
  71. "resize": srv.ContainerResize,
  72. "commit": srv.ContainerCommit,
  73. "info": srv.DockerInfo,
  74. "container_delete": srv.ContainerDestroy,
  75. "image_export": srv.ImageExport,
  76. "images": srv.Images,
  77. "history": srv.ImageHistory,
  78. "viz": srv.ImagesViz,
  79. "container_copy": srv.ContainerCopy,
  80. "insert": srv.ImageInsert,
  81. "attach": srv.ContainerAttach,
  82. "search": srv.ImagesSearch,
  83. "changes": srv.ContainerChanges,
  84. "top": srv.ContainerTop,
  85. "load": srv.ImageLoad,
  86. "build": srv.Build,
  87. "pull": srv.ImagePull,
  88. "import": srv.ImageImport,
  89. "image_delete": srv.ImageDelete,
  90. "inspect": srv.JobInspect,
  91. "events": srv.Events,
  92. "push": srv.ImagePush,
  93. "containers": srv.Containers,
  94. "auth": srv.Auth,
  95. } {
  96. if err := job.Eng.Register(name, handler); err != nil {
  97. return job.Error(err)
  98. }
  99. }
  100. return engine.StatusOK
  101. }
  102. // simpleVersionInfo is a simple implementation of
  103. // the interface VersionInfo, which is used
  104. // to provide version information for some product,
  105. // component, etc. It stores the product name and the version
  106. // in string and returns them on calls to Name() and Version().
  107. type simpleVersionInfo struct {
  108. name string
  109. version string
  110. }
  111. func (v *simpleVersionInfo) Name() string {
  112. return v.name
  113. }
  114. func (v *simpleVersionInfo) Version() string {
  115. return v.version
  116. }
  117. // ContainerKill send signal to the container
  118. // If no signal is given (sig 0), then Kill with SIGKILL and wait
  119. // for the container to exit.
  120. // If a signal is given, then just send it to the container and return.
  121. func (srv *Server) ContainerKill(job *engine.Job) engine.Status {
  122. signalMap := map[string]syscall.Signal{
  123. "HUP": syscall.SIGHUP,
  124. "INT": syscall.SIGINT,
  125. "QUIT": syscall.SIGQUIT,
  126. "ILL": syscall.SIGILL,
  127. "TRAP": syscall.SIGTRAP,
  128. "ABRT": syscall.SIGABRT,
  129. "BUS": syscall.SIGBUS,
  130. "FPE": syscall.SIGFPE,
  131. "KILL": syscall.SIGKILL,
  132. "USR1": syscall.SIGUSR1,
  133. "SEGV": syscall.SIGSEGV,
  134. "USR2": syscall.SIGUSR2,
  135. "PIPE": syscall.SIGPIPE,
  136. "ALRM": syscall.SIGALRM,
  137. "TERM": syscall.SIGTERM,
  138. //"STKFLT": syscall.SIGSTKFLT,
  139. "CHLD": syscall.SIGCHLD,
  140. "CONT": syscall.SIGCONT,
  141. "STOP": syscall.SIGSTOP,
  142. "TSTP": syscall.SIGTSTP,
  143. "TTIN": syscall.SIGTTIN,
  144. "TTOU": syscall.SIGTTOU,
  145. "URG": syscall.SIGURG,
  146. "XCPU": syscall.SIGXCPU,
  147. "XFSZ": syscall.SIGXFSZ,
  148. "VTALRM": syscall.SIGVTALRM,
  149. "PROF": syscall.SIGPROF,
  150. "WINCH": syscall.SIGWINCH,
  151. "IO": syscall.SIGIO,
  152. //"PWR": syscall.SIGPWR,
  153. "SYS": syscall.SIGSYS,
  154. }
  155. if n := len(job.Args); n < 1 || n > 2 {
  156. return job.Errorf("Usage: %s CONTAINER [SIGNAL]", job.Name)
  157. }
  158. name := job.Args[0]
  159. var sig uint64
  160. if len(job.Args) == 2 && job.Args[1] != "" {
  161. sig = uint64(signalMap[job.Args[1]])
  162. if sig == 0 {
  163. var err error
  164. // The largest legal signal is 31, so let's parse on 5 bits
  165. sig, err = strconv.ParseUint(job.Args[1], 10, 5)
  166. if err != nil {
  167. return job.Errorf("Invalid signal: %s", job.Args[1])
  168. }
  169. }
  170. }
  171. if container := srv.runtime.Get(name); container != nil {
  172. // If no signal is passed, or SIGKILL, perform regular Kill (SIGKILL + wait())
  173. if sig == 0 || syscall.Signal(sig) == syscall.SIGKILL {
  174. if err := container.Kill(); err != nil {
  175. return job.Errorf("Cannot kill container %s: %s", name, err)
  176. }
  177. srv.LogEvent("kill", container.ID, srv.runtime.repositories.ImageName(container.Image))
  178. } else {
  179. // Otherwise, just send the requested signal
  180. if err := container.kill(int(sig)); err != nil {
  181. return job.Errorf("Cannot kill container %s: %s", name, err)
  182. }
  183. // FIXME: Add event for signals
  184. }
  185. } else {
  186. return job.Errorf("No such container: %s", name)
  187. }
  188. return engine.StatusOK
  189. }
  190. func (srv *Server) Auth(job *engine.Job) engine.Status {
  191. var (
  192. err error
  193. authConfig = &auth.AuthConfig{}
  194. )
  195. job.GetenvJson("authConfig", authConfig)
  196. // TODO: this is only done here because auth and registry need to be merged into one pkg
  197. if addr := authConfig.ServerAddress; addr != "" && addr != auth.IndexServerAddress() {
  198. addr, err = registry.ExpandAndVerifyRegistryUrl(addr)
  199. if err != nil {
  200. return job.Error(err)
  201. }
  202. authConfig.ServerAddress = addr
  203. }
  204. status, err := auth.Login(authConfig, srv.HTTPRequestFactory(nil))
  205. if err != nil {
  206. return job.Error(err)
  207. }
  208. job.Printf("%s\n", status)
  209. return engine.StatusOK
  210. }
  211. func (srv *Server) Events(job *engine.Job) engine.Status {
  212. if len(job.Args) != 1 {
  213. return job.Errorf("Usage: %s FROM", job.Name)
  214. }
  215. var (
  216. from = job.Args[0]
  217. since = job.GetenvInt64("since")
  218. )
  219. sendEvent := func(event *utils.JSONMessage) error {
  220. b, err := json.Marshal(event)
  221. if err != nil {
  222. return fmt.Errorf("JSON error")
  223. }
  224. _, err = job.Stdout.Write(b)
  225. if err != nil {
  226. // On error, evict the listener
  227. utils.Errorf("%s", err)
  228. srv.Lock()
  229. delete(srv.listeners, from)
  230. srv.Unlock()
  231. return err
  232. }
  233. return nil
  234. }
  235. listener := make(chan utils.JSONMessage)
  236. srv.Lock()
  237. srv.listeners[from] = listener
  238. srv.Unlock()
  239. job.Stdout.Write(nil) // flush
  240. if since != 0 {
  241. // If since, send previous events that happened after the timestamp
  242. for _, event := range srv.GetEvents() {
  243. if event.Time >= since {
  244. err := sendEvent(&event)
  245. if err != nil && err.Error() == "JSON error" {
  246. continue
  247. }
  248. if err != nil {
  249. job.Error(err)
  250. return engine.StatusErr
  251. }
  252. }
  253. }
  254. }
  255. for event := range listener {
  256. err := sendEvent(&event)
  257. if err != nil && err.Error() == "JSON error" {
  258. continue
  259. }
  260. if err != nil {
  261. return job.Error(err)
  262. }
  263. }
  264. return engine.StatusOK
  265. }
  266. func (srv *Server) ContainerExport(job *engine.Job) engine.Status {
  267. if len(job.Args) != 1 {
  268. return job.Errorf("Usage: %s container_id", job.Name)
  269. }
  270. name := job.Args[0]
  271. if container := srv.runtime.Get(name); container != nil {
  272. data, err := container.Export()
  273. if err != nil {
  274. return job.Errorf("%s: %s", name, err)
  275. }
  276. defer data.Close()
  277. // Stream the entire contents of the container (basically a volatile snapshot)
  278. if _, err := io.Copy(job.Stdout, data); err != nil {
  279. return job.Errorf("%s: %s", name, err)
  280. }
  281. // FIXME: factor job-specific LogEvent to engine.Job.Run()
  282. srv.LogEvent("export", container.ID, srv.runtime.repositories.ImageName(container.Image))
  283. return engine.StatusOK
  284. }
  285. return job.Errorf("No such container: %s", name)
  286. }
  287. // ImageExport exports all images with the given tag. All versions
  288. // containing the same tag are exported. The resulting output is an
  289. // uncompressed tar ball.
  290. // name is the set of tags to export.
  291. // out is the writer where the images are written to.
  292. func (srv *Server) ImageExport(job *engine.Job) engine.Status {
  293. if len(job.Args) != 1 {
  294. return job.Errorf("Usage: %s CONTAINER\n", job.Name)
  295. }
  296. name := job.Args[0]
  297. // get image json
  298. tempdir, err := ioutil.TempDir("", "docker-export-")
  299. if err != nil {
  300. return job.Error(err)
  301. }
  302. defer os.RemoveAll(tempdir)
  303. utils.Debugf("Serializing %s", name)
  304. rootRepo, err := srv.runtime.repositories.Get(name)
  305. if err != nil {
  306. return job.Error(err)
  307. }
  308. if rootRepo != nil {
  309. for _, id := range rootRepo {
  310. image, err := srv.ImageInspect(id)
  311. if err != nil {
  312. return job.Error(err)
  313. }
  314. if err := srv.exportImage(image, tempdir); err != nil {
  315. return job.Error(err)
  316. }
  317. }
  318. // write repositories
  319. rootRepoMap := map[string]Repository{}
  320. rootRepoMap[name] = rootRepo
  321. rootRepoJson, _ := json.Marshal(rootRepoMap)
  322. if err := ioutil.WriteFile(path.Join(tempdir, "repositories"), rootRepoJson, os.ModeAppend); err != nil {
  323. return job.Error(err)
  324. }
  325. } else {
  326. image, err := srv.ImageInspect(name)
  327. if err != nil {
  328. return job.Error(err)
  329. }
  330. if err := srv.exportImage(image, tempdir); err != nil {
  331. return job.Error(err)
  332. }
  333. }
  334. fs, err := archive.Tar(tempdir, archive.Uncompressed)
  335. if err != nil {
  336. return job.Error(err)
  337. }
  338. defer fs.Close()
  339. if _, err := io.Copy(job.Stdout, fs); err != nil {
  340. return job.Error(err)
  341. }
  342. return engine.StatusOK
  343. }
  344. func (srv *Server) exportImage(image *Image, tempdir string) error {
  345. for i := image; i != nil; {
  346. // temporary directory
  347. tmpImageDir := path.Join(tempdir, i.ID)
  348. if err := os.Mkdir(tmpImageDir, os.ModeDir); err != nil {
  349. if os.IsExist(err) {
  350. return nil
  351. }
  352. return err
  353. }
  354. var version = "1.0"
  355. var versionBuf = []byte(version)
  356. if err := ioutil.WriteFile(path.Join(tmpImageDir, "VERSION"), versionBuf, os.ModeAppend); err != nil {
  357. return err
  358. }
  359. // serialize json
  360. b, err := json.Marshal(i)
  361. if err != nil {
  362. return err
  363. }
  364. if err := ioutil.WriteFile(path.Join(tmpImageDir, "json"), b, os.ModeAppend); err != nil {
  365. return err
  366. }
  367. // serialize filesystem
  368. fs, err := i.TarLayer()
  369. if err != nil {
  370. return err
  371. }
  372. defer fs.Close()
  373. fsTar, err := os.Create(path.Join(tmpImageDir, "layer.tar"))
  374. if err != nil {
  375. return err
  376. }
  377. if _, err = io.Copy(fsTar, fs); err != nil {
  378. return err
  379. }
  380. fsTar.Close()
  381. // find parent
  382. if i.Parent != "" {
  383. i, err = srv.ImageInspect(i.Parent)
  384. if err != nil {
  385. return err
  386. }
  387. } else {
  388. i = nil
  389. }
  390. }
  391. return nil
  392. }
  393. func (srv *Server) Build(job *engine.Job) engine.Status {
  394. if len(job.Args) != 0 {
  395. return job.Errorf("Usage: %s\n", job.Name)
  396. }
  397. var (
  398. remoteURL = job.Getenv("remote")
  399. repoName = job.Getenv("t")
  400. suppressOutput = job.GetenvBool("q")
  401. noCache = job.GetenvBool("nocache")
  402. rm = job.GetenvBool("rm")
  403. authConfig = &auth.AuthConfig{}
  404. configFile = &auth.ConfigFile{}
  405. tag string
  406. context io.ReadCloser
  407. )
  408. job.GetenvJson("authConfig", authConfig)
  409. job.GetenvJson("configFile", configFile)
  410. repoName, tag = utils.ParseRepositoryTag(repoName)
  411. if remoteURL == "" {
  412. context = ioutil.NopCloser(job.Stdin)
  413. } else if utils.IsGIT(remoteURL) {
  414. if !strings.HasPrefix(remoteURL, "git://") {
  415. remoteURL = "https://" + remoteURL
  416. }
  417. root, err := ioutil.TempDir("", "docker-build-git")
  418. if err != nil {
  419. return job.Error(err)
  420. }
  421. defer os.RemoveAll(root)
  422. if output, err := exec.Command("git", "clone", "--recursive", remoteURL, root).CombinedOutput(); err != nil {
  423. return job.Errorf("Error trying to use git: %s (%s)", err, output)
  424. }
  425. c, err := archive.Tar(root, archive.Uncompressed)
  426. if err != nil {
  427. return job.Error(err)
  428. }
  429. context = c
  430. } else if utils.IsURL(remoteURL) {
  431. f, err := utils.Download(remoteURL)
  432. if err != nil {
  433. return job.Error(err)
  434. }
  435. defer f.Body.Close()
  436. dockerFile, err := ioutil.ReadAll(f.Body)
  437. if err != nil {
  438. return job.Error(err)
  439. }
  440. c, err := archive.Generate("Dockerfile", string(dockerFile))
  441. if err != nil {
  442. return job.Error(err)
  443. }
  444. context = c
  445. }
  446. defer context.Close()
  447. sf := utils.NewStreamFormatter(job.GetenvBool("json"))
  448. b := NewBuildFile(srv,
  449. &StdoutFormater{
  450. Writer: job.Stdout,
  451. StreamFormatter: sf,
  452. },
  453. &StderrFormater{
  454. Writer: job.Stdout,
  455. StreamFormatter: sf,
  456. },
  457. !suppressOutput, !noCache, rm, job.Stdout, sf, authConfig, configFile)
  458. id, err := b.Build(context)
  459. if err != nil {
  460. return job.Error(err)
  461. }
  462. if repoName != "" {
  463. srv.runtime.repositories.Set(repoName, tag, id, false)
  464. }
  465. return engine.StatusOK
  466. }
  467. // Loads a set of images into the repository. This is the complementary of ImageExport.
  468. // The input stream is an uncompressed tar ball containing images and metadata.
  469. func (srv *Server) ImageLoad(job *engine.Job) engine.Status {
  470. tmpImageDir, err := ioutil.TempDir("", "docker-import-")
  471. if err != nil {
  472. return job.Error(err)
  473. }
  474. defer os.RemoveAll(tmpImageDir)
  475. var (
  476. repoTarFile = path.Join(tmpImageDir, "repo.tar")
  477. repoDir = path.Join(tmpImageDir, "repo")
  478. )
  479. tarFile, err := os.Create(repoTarFile)
  480. if err != nil {
  481. return job.Error(err)
  482. }
  483. if _, err := io.Copy(tarFile, job.Stdin); err != nil {
  484. return job.Error(err)
  485. }
  486. tarFile.Close()
  487. repoFile, err := os.Open(repoTarFile)
  488. if err != nil {
  489. return job.Error(err)
  490. }
  491. if err := os.Mkdir(repoDir, os.ModeDir); err != nil {
  492. return job.Error(err)
  493. }
  494. if err := archive.Untar(repoFile, repoDir, nil); err != nil {
  495. return job.Error(err)
  496. }
  497. dirs, err := ioutil.ReadDir(repoDir)
  498. if err != nil {
  499. return job.Error(err)
  500. }
  501. for _, d := range dirs {
  502. if d.IsDir() {
  503. if err := srv.recursiveLoad(d.Name(), tmpImageDir); err != nil {
  504. return job.Error(err)
  505. }
  506. }
  507. }
  508. repositoriesJson, err := ioutil.ReadFile(path.Join(tmpImageDir, "repo", "repositories"))
  509. if err == nil {
  510. repositories := map[string]Repository{}
  511. if err := json.Unmarshal(repositoriesJson, &repositories); err != nil {
  512. return job.Error(err)
  513. }
  514. for imageName, tagMap := range repositories {
  515. for tag, address := range tagMap {
  516. if err := srv.runtime.repositories.Set(imageName, tag, address, true); err != nil {
  517. return job.Error(err)
  518. }
  519. }
  520. }
  521. } else if !os.IsNotExist(err) {
  522. return job.Error(err)
  523. }
  524. return engine.StatusOK
  525. }
  526. func (srv *Server) recursiveLoad(address, tmpImageDir string) error {
  527. if _, err := srv.ImageInspect(address); err != nil {
  528. utils.Debugf("Loading %s", address)
  529. imageJson, err := ioutil.ReadFile(path.Join(tmpImageDir, "repo", address, "json"))
  530. if err != nil {
  531. utils.Debugf("Error reading json", err)
  532. return err
  533. }
  534. layer, err := os.Open(path.Join(tmpImageDir, "repo", address, "layer.tar"))
  535. if err != nil {
  536. utils.Debugf("Error reading embedded tar", err)
  537. return err
  538. }
  539. img, err := NewImgJSON(imageJson)
  540. if err != nil {
  541. utils.Debugf("Error unmarshalling json", err)
  542. return err
  543. }
  544. if img.Parent != "" {
  545. if !srv.runtime.graph.Exists(img.Parent) {
  546. if err := srv.recursiveLoad(img.Parent, tmpImageDir); err != nil {
  547. return err
  548. }
  549. }
  550. }
  551. if err := srv.runtime.graph.Register(imageJson, layer, img); err != nil {
  552. return err
  553. }
  554. }
  555. utils.Debugf("Completed processing %s", address)
  556. return nil
  557. }
  558. func (srv *Server) ImagesSearch(job *engine.Job) engine.Status {
  559. if n := len(job.Args); n != 1 {
  560. return job.Errorf("Usage: %s TERM", job.Name)
  561. }
  562. var (
  563. term = job.Args[0]
  564. metaHeaders = map[string][]string{}
  565. authConfig = &auth.AuthConfig{}
  566. )
  567. job.GetenvJson("authConfig", authConfig)
  568. job.GetenvJson("metaHeaders", metaHeaders)
  569. r, err := registry.NewRegistry(authConfig, srv.HTTPRequestFactory(metaHeaders), auth.IndexServerAddress())
  570. if err != nil {
  571. return job.Error(err)
  572. }
  573. results, err := r.SearchRepositories(term)
  574. if err != nil {
  575. return job.Error(err)
  576. }
  577. outs := engine.NewTable("star_count", 0)
  578. for _, result := range results.Results {
  579. out := &engine.Env{}
  580. out.Import(result)
  581. outs.Add(out)
  582. }
  583. outs.ReverseSort()
  584. if _, err := outs.WriteListTo(job.Stdout); err != nil {
  585. return job.Error(err)
  586. }
  587. return engine.StatusOK
  588. }
  589. func (srv *Server) ImageInsert(job *engine.Job) engine.Status {
  590. if len(job.Args) != 3 {
  591. return job.Errorf("Usage: %s IMAGE URL PATH\n", job.Name)
  592. }
  593. var (
  594. name = job.Args[0]
  595. url = job.Args[1]
  596. path = job.Args[2]
  597. )
  598. sf := utils.NewStreamFormatter(job.GetenvBool("json"))
  599. out := utils.NewWriteFlusher(job.Stdout)
  600. img, err := srv.runtime.repositories.LookupImage(name)
  601. if err != nil {
  602. return job.Error(err)
  603. }
  604. file, err := utils.Download(url)
  605. if err != nil {
  606. return job.Error(err)
  607. }
  608. defer file.Body.Close()
  609. config, _, _, err := runconfig.Parse([]string{img.ID, "echo", "insert", url, path}, srv.runtime.sysInfo)
  610. if err != nil {
  611. return job.Error(err)
  612. }
  613. c, _, err := srv.runtime.Create(config, "")
  614. if err != nil {
  615. return job.Error(err)
  616. }
  617. if err := c.Inject(utils.ProgressReader(file.Body, int(file.ContentLength), out, sf, false, utils.TruncateID(img.ID), "Downloading"), path); err != nil {
  618. return job.Error(err)
  619. }
  620. // FIXME: Handle custom repo, tag comment, author
  621. img, err = srv.runtime.Commit(c, "", "", img.Comment, img.Author, nil)
  622. if err != nil {
  623. out.Write(sf.FormatError(err))
  624. return engine.StatusErr
  625. }
  626. out.Write(sf.FormatStatus("", img.ID))
  627. return engine.StatusOK
  628. }
  629. func (srv *Server) ImagesViz(job *engine.Job) engine.Status {
  630. images, _ := srv.runtime.graph.Map()
  631. if images == nil {
  632. return engine.StatusOK
  633. }
  634. job.Stdout.Write([]byte("digraph docker {\n"))
  635. var (
  636. parentImage *Image
  637. err error
  638. )
  639. for _, image := range images {
  640. parentImage, err = image.GetParent()
  641. if err != nil {
  642. return job.Errorf("Error while getting parent image: %v", err)
  643. }
  644. if parentImage != nil {
  645. job.Stdout.Write([]byte(" \"" + parentImage.ID + "\" -> \"" + image.ID + "\"\n"))
  646. } else {
  647. job.Stdout.Write([]byte(" base -> \"" + image.ID + "\" [style=invis]\n"))
  648. }
  649. }
  650. reporefs := make(map[string][]string)
  651. for name, repository := range srv.runtime.repositories.Repositories {
  652. for tag, id := range repository {
  653. reporefs[utils.TruncateID(id)] = append(reporefs[utils.TruncateID(id)], fmt.Sprintf("%s:%s", name, tag))
  654. }
  655. }
  656. for id, repos := range reporefs {
  657. job.Stdout.Write([]byte(" \"" + id + "\" [label=\"" + id + "\\n" + strings.Join(repos, "\\n") + "\",shape=box,fillcolor=\"paleturquoise\",style=\"filled,rounded\"];\n"))
  658. }
  659. job.Stdout.Write([]byte(" base [style=invisible]\n}\n"))
  660. return engine.StatusOK
  661. }
  662. func (srv *Server) Images(job *engine.Job) engine.Status {
  663. var (
  664. allImages map[string]*Image
  665. err error
  666. )
  667. if job.GetenvBool("all") {
  668. allImages, err = srv.runtime.graph.Map()
  669. } else {
  670. allImages, err = srv.runtime.graph.Heads()
  671. }
  672. if err != nil {
  673. return job.Error(err)
  674. }
  675. lookup := make(map[string]*engine.Env)
  676. for name, repository := range srv.runtime.repositories.Repositories {
  677. if job.Getenv("filter") != "" {
  678. if match, _ := path.Match(job.Getenv("filter"), name); !match {
  679. continue
  680. }
  681. }
  682. for tag, id := range repository {
  683. image, err := srv.runtime.graph.Get(id)
  684. if err != nil {
  685. log.Printf("Warning: couldn't load %s from %s/%s: %s", id, name, tag, err)
  686. continue
  687. }
  688. if out, exists := lookup[id]; exists {
  689. out.SetList("RepoTags", append(out.GetList("RepoTags"), fmt.Sprintf("%s:%s", name, tag)))
  690. } else {
  691. out := &engine.Env{}
  692. delete(allImages, id)
  693. out.Set("ParentId", image.Parent)
  694. out.SetList("RepoTags", []string{fmt.Sprintf("%s:%s", name, tag)})
  695. out.Set("Id", image.ID)
  696. out.SetInt64("Created", image.Created.Unix())
  697. out.SetInt64("Size", image.Size)
  698. out.SetInt64("VirtualSize", image.getParentsSize(0)+image.Size)
  699. lookup[id] = out
  700. }
  701. }
  702. }
  703. outs := engine.NewTable("Created", len(lookup))
  704. for _, value := range lookup {
  705. outs.Add(value)
  706. }
  707. // Display images which aren't part of a repository/tag
  708. if job.Getenv("filter") == "" {
  709. for _, image := range allImages {
  710. out := &engine.Env{}
  711. out.Set("ParentId", image.Parent)
  712. out.SetList("RepoTags", []string{"<none>:<none>"})
  713. out.Set("Id", image.ID)
  714. out.SetInt64("Created", image.Created.Unix())
  715. out.SetInt64("Size", image.Size)
  716. out.SetInt64("VirtualSize", image.getParentsSize(0)+image.Size)
  717. outs.Add(out)
  718. }
  719. }
  720. outs.ReverseSort()
  721. if _, err := outs.WriteListTo(job.Stdout); err != nil {
  722. return job.Error(err)
  723. }
  724. return engine.StatusOK
  725. }
  726. func (srv *Server) DockerInfo(job *engine.Job) engine.Status {
  727. images, _ := srv.runtime.graph.Map()
  728. var imgcount int
  729. if images == nil {
  730. imgcount = 0
  731. } else {
  732. imgcount = len(images)
  733. }
  734. kernelVersion := "<unknown>"
  735. if kv, err := utils.GetKernelVersion(); err == nil {
  736. kernelVersion = kv.String()
  737. }
  738. // 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)
  739. initPath := utils.DockerInitPath("")
  740. if initPath == "" {
  741. // if that fails, we'll just return the path from the runtime
  742. initPath = srv.runtime.sysInitPath
  743. }
  744. v := &engine.Env{}
  745. v.SetInt("Containers", len(srv.runtime.List()))
  746. v.SetInt("Images", imgcount)
  747. v.Set("Driver", srv.runtime.driver.String())
  748. v.SetJson("DriverStatus", srv.runtime.driver.Status())
  749. v.SetBool("MemoryLimit", srv.runtime.sysInfo.MemoryLimit)
  750. v.SetBool("SwapLimit", srv.runtime.sysInfo.SwapLimit)
  751. v.SetBool("IPv4Forwarding", !srv.runtime.sysInfo.IPv4ForwardingDisabled)
  752. v.SetBool("Debug", os.Getenv("DEBUG") != "")
  753. v.SetInt("NFd", utils.GetTotalUsedFds())
  754. v.SetInt("NGoroutines", runtime.NumGoroutine())
  755. v.Set("ExecutionDriver", srv.runtime.execDriver.Name())
  756. v.SetInt("NEventsListener", len(srv.events))
  757. v.Set("KernelVersion", kernelVersion)
  758. v.Set("IndexServerAddress", auth.IndexServerAddress())
  759. v.Set("InitSha1", dockerversion.INITSHA1)
  760. v.Set("InitPath", initPath)
  761. if _, err := v.WriteTo(job.Stdout); err != nil {
  762. return job.Error(err)
  763. }
  764. return engine.StatusOK
  765. }
  766. func (srv *Server) ImageHistory(job *engine.Job) engine.Status {
  767. if n := len(job.Args); n != 1 {
  768. return job.Errorf("Usage: %s IMAGE", job.Name)
  769. }
  770. name := job.Args[0]
  771. image, err := srv.runtime.repositories.LookupImage(name)
  772. if err != nil {
  773. return job.Error(err)
  774. }
  775. lookupMap := make(map[string][]string)
  776. for name, repository := range srv.runtime.repositories.Repositories {
  777. for tag, id := range repository {
  778. // If the ID already has a reverse lookup, do not update it unless for "latest"
  779. if _, exists := lookupMap[id]; !exists {
  780. lookupMap[id] = []string{}
  781. }
  782. lookupMap[id] = append(lookupMap[id], name+":"+tag)
  783. }
  784. }
  785. outs := engine.NewTable("Created", 0)
  786. err = image.WalkHistory(func(img *Image) error {
  787. out := &engine.Env{}
  788. out.Set("Id", img.ID)
  789. out.SetInt64("Created", img.Created.Unix())
  790. out.Set("CreatedBy", strings.Join(img.ContainerConfig.Cmd, " "))
  791. out.SetList("Tags", lookupMap[img.ID])
  792. out.SetInt64("Size", img.Size)
  793. outs.Add(out)
  794. return nil
  795. })
  796. outs.ReverseSort()
  797. if _, err := outs.WriteListTo(job.Stdout); err != nil {
  798. return job.Error(err)
  799. }
  800. return engine.StatusOK
  801. }
  802. func (srv *Server) ContainerTop(job *engine.Job) engine.Status {
  803. if len(job.Args) != 1 && len(job.Args) != 2 {
  804. return job.Errorf("Not enough arguments. Usage: %s CONTAINER [PS_ARGS]\n", job.Name)
  805. }
  806. var (
  807. name = job.Args[0]
  808. psArgs = "-ef"
  809. )
  810. if len(job.Args) == 2 && job.Args[1] != "" {
  811. psArgs = job.Args[1]
  812. }
  813. if container := srv.runtime.Get(name); container != nil {
  814. if !container.State.IsRunning() {
  815. return job.Errorf("Container %s is not running", name)
  816. }
  817. pids, err := srv.runtime.execDriver.GetPidsForContainer(container.ID)
  818. if err != nil {
  819. return job.Error(err)
  820. }
  821. output, err := exec.Command("ps", psArgs).Output()
  822. if err != nil {
  823. return job.Errorf("Error running ps: %s", err)
  824. }
  825. lines := strings.Split(string(output), "\n")
  826. header := strings.Fields(lines[0])
  827. out := &engine.Env{}
  828. out.SetList("Titles", header)
  829. pidIndex := -1
  830. for i, name := range header {
  831. if name == "PID" {
  832. pidIndex = i
  833. }
  834. }
  835. if pidIndex == -1 {
  836. return job.Errorf("Couldn't find PID field in ps output")
  837. }
  838. processes := [][]string{}
  839. for _, line := range lines[1:] {
  840. if len(line) == 0 {
  841. continue
  842. }
  843. fields := strings.Fields(line)
  844. p, err := strconv.Atoi(fields[pidIndex])
  845. if err != nil {
  846. return job.Errorf("Unexpected pid '%s': %s", fields[pidIndex], err)
  847. }
  848. for _, pid := range pids {
  849. if pid == p {
  850. // Make sure number of fields equals number of header titles
  851. // merging "overhanging" fields
  852. process := fields[:len(header)-1]
  853. process = append(process, strings.Join(fields[len(header)-1:], " "))
  854. processes = append(processes, process)
  855. }
  856. }
  857. }
  858. out.SetJson("Processes", processes)
  859. out.WriteTo(job.Stdout)
  860. return engine.StatusOK
  861. }
  862. return job.Errorf("No such container: %s", name)
  863. }
  864. func (srv *Server) ContainerChanges(job *engine.Job) engine.Status {
  865. if n := len(job.Args); n != 1 {
  866. return job.Errorf("Usage: %s CONTAINER", job.Name)
  867. }
  868. name := job.Args[0]
  869. if container := srv.runtime.Get(name); container != nil {
  870. outs := engine.NewTable("", 0)
  871. changes, err := container.Changes()
  872. if err != nil {
  873. return job.Error(err)
  874. }
  875. for _, change := range changes {
  876. out := &engine.Env{}
  877. if err := out.Import(change); err != nil {
  878. return job.Error(err)
  879. }
  880. outs.Add(out)
  881. }
  882. if _, err := outs.WriteListTo(job.Stdout); err != nil {
  883. return job.Error(err)
  884. }
  885. } else {
  886. return job.Errorf("No such container: %s", name)
  887. }
  888. return engine.StatusOK
  889. }
  890. func (srv *Server) Containers(job *engine.Job) engine.Status {
  891. var (
  892. foundBefore bool
  893. displayed int
  894. all = job.GetenvBool("all")
  895. since = job.Getenv("since")
  896. before = job.Getenv("before")
  897. n = job.GetenvInt("limit")
  898. size = job.GetenvBool("size")
  899. )
  900. outs := engine.NewTable("Created", 0)
  901. names := map[string][]string{}
  902. srv.runtime.containerGraph.Walk("/", func(p string, e *graphdb.Entity) error {
  903. names[e.ID()] = append(names[e.ID()], p)
  904. return nil
  905. }, -1)
  906. for _, container := range srv.runtime.List() {
  907. if !container.State.IsRunning() && !all && n <= 0 && since == "" && before == "" {
  908. continue
  909. }
  910. if before != "" && !foundBefore {
  911. if container.ID == before || utils.TruncateID(container.ID) == before {
  912. foundBefore = true
  913. }
  914. continue
  915. }
  916. if n > 0 && displayed == n {
  917. break
  918. }
  919. if container.ID == since || utils.TruncateID(container.ID) == since {
  920. break
  921. }
  922. displayed++
  923. out := &engine.Env{}
  924. out.Set("Id", container.ID)
  925. out.SetList("Names", names[container.ID])
  926. out.Set("Image", srv.runtime.repositories.ImageName(container.Image))
  927. out.Set("Command", fmt.Sprintf("%s %s", container.Path, strings.Join(container.Args, " ")))
  928. out.SetInt64("Created", container.Created.Unix())
  929. out.Set("Status", container.State.String())
  930. str, err := container.NetworkSettings.PortMappingAPI().ToListString()
  931. if err != nil {
  932. return job.Error(err)
  933. }
  934. out.Set("Ports", str)
  935. if size {
  936. sizeRw, sizeRootFs := container.GetSize()
  937. out.SetInt64("SizeRw", sizeRw)
  938. out.SetInt64("SizeRootFs", sizeRootFs)
  939. }
  940. outs.Add(out)
  941. }
  942. outs.ReverseSort()
  943. if _, err := outs.WriteListTo(job.Stdout); err != nil {
  944. return job.Error(err)
  945. }
  946. return engine.StatusOK
  947. }
  948. func (srv *Server) ContainerCommit(job *engine.Job) engine.Status {
  949. if len(job.Args) != 1 {
  950. return job.Errorf("Not enough arguments. Usage: %s CONTAINER\n", job.Name)
  951. }
  952. name := job.Args[0]
  953. container := srv.runtime.Get(name)
  954. if container == nil {
  955. return job.Errorf("No such container: %s", name)
  956. }
  957. var config runconfig.Config
  958. if err := job.GetenvJson("config", &config); err != nil {
  959. return job.Error(err)
  960. }
  961. img, err := srv.runtime.Commit(container, job.Getenv("repo"), job.Getenv("tag"), job.Getenv("comment"), job.Getenv("author"), &config)
  962. if err != nil {
  963. return job.Error(err)
  964. }
  965. job.Printf("%s\n", img.ID)
  966. return engine.StatusOK
  967. }
  968. func (srv *Server) ImageTag(job *engine.Job) engine.Status {
  969. if len(job.Args) != 2 && len(job.Args) != 3 {
  970. return job.Errorf("Usage: %s IMAGE REPOSITORY [TAG]\n", job.Name)
  971. }
  972. var tag string
  973. if len(job.Args) == 3 {
  974. tag = job.Args[2]
  975. }
  976. if err := srv.runtime.repositories.Set(job.Args[1], tag, job.Args[0], job.GetenvBool("force")); err != nil {
  977. return job.Error(err)
  978. }
  979. return engine.StatusOK
  980. }
  981. func (srv *Server) pullImage(r *registry.Registry, out io.Writer, imgID, endpoint string, token []string, sf *utils.StreamFormatter) error {
  982. history, err := r.GetRemoteHistory(imgID, endpoint, token)
  983. if err != nil {
  984. return err
  985. }
  986. out.Write(sf.FormatProgress(utils.TruncateID(imgID), "Pulling dependent layers", nil))
  987. // FIXME: Try to stream the images?
  988. // FIXME: Launch the getRemoteImage() in goroutines
  989. for i := len(history) - 1; i >= 0; i-- {
  990. id := history[i]
  991. // ensure no two downloads of the same layer happen at the same time
  992. if c, err := srv.poolAdd("pull", "layer:"+id); err != nil {
  993. utils.Errorf("Image (id: %s) pull is already running, skipping: %v", id, err)
  994. <-c
  995. }
  996. defer srv.poolRemove("pull", "layer:"+id)
  997. if !srv.runtime.graph.Exists(id) {
  998. out.Write(sf.FormatProgress(utils.TruncateID(id), "Pulling metadata", nil))
  999. imgJSON, imgSize, err := r.GetRemoteImageJSON(id, endpoint, token)
  1000. if err != nil {
  1001. out.Write(sf.FormatProgress(utils.TruncateID(id), "Error pulling dependent layers", nil))
  1002. // FIXME: Keep going in case of error?
  1003. return err
  1004. }
  1005. img, err := NewImgJSON(imgJSON)
  1006. if err != nil {
  1007. out.Write(sf.FormatProgress(utils.TruncateID(id), "Error pulling dependent layers", nil))
  1008. return fmt.Errorf("Failed to parse json: %s", err)
  1009. }
  1010. // Get the layer
  1011. out.Write(sf.FormatProgress(utils.TruncateID(id), "Pulling fs layer", nil))
  1012. layer, err := r.GetRemoteImageLayer(img.ID, endpoint, token)
  1013. if err != nil {
  1014. out.Write(sf.FormatProgress(utils.TruncateID(id), "Error pulling dependent layers", nil))
  1015. return err
  1016. }
  1017. defer layer.Close()
  1018. if err := srv.runtime.graph.Register(imgJSON, utils.ProgressReader(layer, imgSize, out, sf, false, utils.TruncateID(id), "Downloading"), img); err != nil {
  1019. out.Write(sf.FormatProgress(utils.TruncateID(id), "Error downloading dependent layers", nil))
  1020. return err
  1021. }
  1022. }
  1023. out.Write(sf.FormatProgress(utils.TruncateID(id), "Download complete", nil))
  1024. }
  1025. return nil
  1026. }
  1027. func (srv *Server) pullRepository(r *registry.Registry, out io.Writer, localName, remoteName, askedTag string, sf *utils.StreamFormatter, parallel bool) error {
  1028. out.Write(sf.FormatStatus("", "Pulling repository %s", localName))
  1029. repoData, err := r.GetRepositoryData(remoteName)
  1030. if err != nil {
  1031. return err
  1032. }
  1033. utils.Debugf("Retrieving the tag list")
  1034. tagsList, err := r.GetRemoteTags(repoData.Endpoints, remoteName, repoData.Tokens)
  1035. if err != nil {
  1036. utils.Errorf("%v", err)
  1037. return err
  1038. }
  1039. for tag, id := range tagsList {
  1040. repoData.ImgList[id] = &registry.ImgData{
  1041. ID: id,
  1042. Tag: tag,
  1043. Checksum: "",
  1044. }
  1045. }
  1046. utils.Debugf("Registering tags")
  1047. // If no tag has been specified, pull them all
  1048. if askedTag == "" {
  1049. for tag, id := range tagsList {
  1050. repoData.ImgList[id].Tag = tag
  1051. }
  1052. } else {
  1053. // Otherwise, check that the tag exists and use only that one
  1054. id, exists := tagsList[askedTag]
  1055. if !exists {
  1056. return fmt.Errorf("Tag %s not found in repository %s", askedTag, localName)
  1057. }
  1058. repoData.ImgList[id].Tag = askedTag
  1059. }
  1060. errors := make(chan error)
  1061. for _, image := range repoData.ImgList {
  1062. downloadImage := func(img *registry.ImgData) {
  1063. if askedTag != "" && img.Tag != askedTag {
  1064. utils.Debugf("(%s) does not match %s (id: %s), skipping", img.Tag, askedTag, img.ID)
  1065. if parallel {
  1066. errors <- nil
  1067. }
  1068. return
  1069. }
  1070. if img.Tag == "" {
  1071. utils.Debugf("Image (id: %s) present in this repository but untagged, skipping", img.ID)
  1072. if parallel {
  1073. errors <- nil
  1074. }
  1075. return
  1076. }
  1077. // ensure no two downloads of the same image happen at the same time
  1078. if c, err := srv.poolAdd("pull", "img:"+img.ID); err != nil {
  1079. if c != nil {
  1080. out.Write(sf.FormatProgress(utils.TruncateID(img.ID), "Layer already being pulled by another client. Waiting.", nil))
  1081. <-c
  1082. out.Write(sf.FormatProgress(utils.TruncateID(img.ID), "Download complete", nil))
  1083. } else {
  1084. utils.Errorf("Image (id: %s) pull is already running, skipping: %v", img.ID, err)
  1085. }
  1086. if parallel {
  1087. errors <- nil
  1088. }
  1089. return
  1090. }
  1091. defer srv.poolRemove("pull", "img:"+img.ID)
  1092. out.Write(sf.FormatProgress(utils.TruncateID(img.ID), fmt.Sprintf("Pulling image (%s) from %s", img.Tag, localName), nil))
  1093. success := false
  1094. var lastErr error
  1095. for _, ep := range repoData.Endpoints {
  1096. out.Write(sf.FormatProgress(utils.TruncateID(img.ID), fmt.Sprintf("Pulling image (%s) from %s, endpoint: %s", img.Tag, localName, ep), nil))
  1097. if err := srv.pullImage(r, out, img.ID, ep, repoData.Tokens, sf); err != nil {
  1098. // Its not ideal that only the last error is returned, it would be better to concatenate the errors.
  1099. // As the error is also given to the output stream the user will see the error.
  1100. lastErr = err
  1101. 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))
  1102. continue
  1103. }
  1104. success = true
  1105. break
  1106. }
  1107. if !success {
  1108. out.Write(sf.FormatProgress(utils.TruncateID(img.ID), fmt.Sprintf("Error pulling image (%s) from %s, %s", img.Tag, localName, lastErr), nil))
  1109. if parallel {
  1110. errors <- fmt.Errorf("Could not find repository on any of the indexed registries.")
  1111. return
  1112. }
  1113. }
  1114. out.Write(sf.FormatProgress(utils.TruncateID(img.ID), "Download complete", nil))
  1115. if parallel {
  1116. errors <- nil
  1117. }
  1118. }
  1119. if parallel {
  1120. go downloadImage(image)
  1121. } else {
  1122. downloadImage(image)
  1123. }
  1124. }
  1125. if parallel {
  1126. var lastError error
  1127. for i := 0; i < len(repoData.ImgList); i++ {
  1128. if err := <-errors; err != nil {
  1129. lastError = err
  1130. }
  1131. }
  1132. if lastError != nil {
  1133. return lastError
  1134. }
  1135. }
  1136. for tag, id := range tagsList {
  1137. if askedTag != "" && tag != askedTag {
  1138. continue
  1139. }
  1140. if err := srv.runtime.repositories.Set(localName, tag, id, true); err != nil {
  1141. return err
  1142. }
  1143. }
  1144. if err := srv.runtime.repositories.Save(); err != nil {
  1145. return err
  1146. }
  1147. return nil
  1148. }
  1149. func (srv *Server) poolAdd(kind, key string) (chan struct{}, error) {
  1150. srv.Lock()
  1151. defer srv.Unlock()
  1152. if c, exists := srv.pullingPool[key]; exists {
  1153. return c, fmt.Errorf("pull %s is already in progress", key)
  1154. }
  1155. if c, exists := srv.pushingPool[key]; exists {
  1156. return c, fmt.Errorf("push %s is already in progress", key)
  1157. }
  1158. c := make(chan struct{})
  1159. switch kind {
  1160. case "pull":
  1161. srv.pullingPool[key] = c
  1162. case "push":
  1163. srv.pushingPool[key] = c
  1164. default:
  1165. return nil, fmt.Errorf("Unknown pool type")
  1166. }
  1167. return c, nil
  1168. }
  1169. func (srv *Server) poolRemove(kind, key string) error {
  1170. srv.Lock()
  1171. defer srv.Unlock()
  1172. switch kind {
  1173. case "pull":
  1174. if c, exists := srv.pullingPool[key]; exists {
  1175. close(c)
  1176. delete(srv.pullingPool, key)
  1177. }
  1178. case "push":
  1179. if c, exists := srv.pushingPool[key]; exists {
  1180. close(c)
  1181. delete(srv.pushingPool, key)
  1182. }
  1183. default:
  1184. return fmt.Errorf("Unknown pool type")
  1185. }
  1186. return nil
  1187. }
  1188. func (srv *Server) ImagePull(job *engine.Job) engine.Status {
  1189. if n := len(job.Args); n != 1 && n != 2 {
  1190. return job.Errorf("Usage: %s IMAGE [TAG]", job.Name)
  1191. }
  1192. var (
  1193. localName = job.Args[0]
  1194. tag string
  1195. sf = utils.NewStreamFormatter(job.GetenvBool("json"))
  1196. authConfig = &auth.AuthConfig{}
  1197. metaHeaders map[string][]string
  1198. )
  1199. if len(job.Args) > 1 {
  1200. tag = job.Args[1]
  1201. }
  1202. job.GetenvJson("authConfig", authConfig)
  1203. job.GetenvJson("metaHeaders", metaHeaders)
  1204. c, err := srv.poolAdd("pull", localName+":"+tag)
  1205. if err != nil {
  1206. if c != nil {
  1207. // Another pull of the same repository is already taking place; just wait for it to finish
  1208. job.Stdout.Write(sf.FormatStatus("", "Repository %s already being pulled by another client. Waiting.", localName))
  1209. <-c
  1210. return engine.StatusOK
  1211. }
  1212. return job.Error(err)
  1213. }
  1214. defer srv.poolRemove("pull", localName+":"+tag)
  1215. // Resolve the Repository name from fqn to endpoint + name
  1216. endpoint, remoteName, err := registry.ResolveRepositoryName(localName)
  1217. if err != nil {
  1218. return job.Error(err)
  1219. }
  1220. r, err := registry.NewRegistry(authConfig, srv.HTTPRequestFactory(metaHeaders), endpoint)
  1221. if err != nil {
  1222. return job.Error(err)
  1223. }
  1224. if endpoint == auth.IndexServerAddress() {
  1225. // If pull "index.docker.io/foo/bar", it's stored locally under "foo/bar"
  1226. localName = remoteName
  1227. }
  1228. if err = srv.pullRepository(r, job.Stdout, localName, remoteName, tag, sf, job.GetenvBool("parallel")); err != nil {
  1229. return job.Error(err)
  1230. }
  1231. return engine.StatusOK
  1232. }
  1233. // Retrieve the all the images to be uploaded in the correct order
  1234. func (srv *Server) getImageList(localRepo map[string]string) ([]string, map[string][]string, error) {
  1235. var (
  1236. imageList []string
  1237. imagesSeen map[string]bool = make(map[string]bool)
  1238. tagsByImage map[string][]string = make(map[string][]string)
  1239. )
  1240. for tag, id := range localRepo {
  1241. var imageListForThisTag []string
  1242. tagsByImage[id] = append(tagsByImage[id], tag)
  1243. for img, err := srv.runtime.graph.Get(id); img != nil; img, err = img.GetParent() {
  1244. if err != nil {
  1245. return nil, nil, err
  1246. }
  1247. if imagesSeen[img.ID] {
  1248. // This image is already on the list, we can ignore it and all its parents
  1249. break
  1250. }
  1251. imagesSeen[img.ID] = true
  1252. imageListForThisTag = append(imageListForThisTag, img.ID)
  1253. }
  1254. // reverse the image list for this tag (so the "most"-parent image is first)
  1255. for i, j := 0, len(imageListForThisTag)-1; i < j; i, j = i+1, j-1 {
  1256. imageListForThisTag[i], imageListForThisTag[j] = imageListForThisTag[j], imageListForThisTag[i]
  1257. }
  1258. // append to main image list
  1259. imageList = append(imageList, imageListForThisTag...)
  1260. }
  1261. utils.Debugf("Image list: %v", imageList)
  1262. utils.Debugf("Tags by image: %v", tagsByImage)
  1263. return imageList, tagsByImage, nil
  1264. }
  1265. func (srv *Server) pushRepository(r *registry.Registry, out io.Writer, localName, remoteName string, localRepo map[string]string, sf *utils.StreamFormatter) error {
  1266. out = utils.NewWriteFlusher(out)
  1267. utils.Debugf("Local repo: %s", localRepo)
  1268. imgList, tagsByImage, err := srv.getImageList(localRepo)
  1269. if err != nil {
  1270. return err
  1271. }
  1272. out.Write(sf.FormatStatus("", "Sending image list"))
  1273. var repoData *registry.RepositoryData
  1274. var imageIndex []*registry.ImgData
  1275. for _, imgId := range imgList {
  1276. if tags, exists := tagsByImage[imgId]; exists {
  1277. // If an image has tags you must add an entry in the image index
  1278. // for each tag
  1279. for _, tag := range tags {
  1280. imageIndex = append(imageIndex, &registry.ImgData{
  1281. ID: imgId,
  1282. Tag: tag,
  1283. })
  1284. }
  1285. } else {
  1286. // If the image does not have a tag it still needs to be sent to the
  1287. // registry with an empty tag so that it is accociated with the repository
  1288. imageIndex = append(imageIndex, &registry.ImgData{
  1289. ID: imgId,
  1290. Tag: "",
  1291. })
  1292. }
  1293. }
  1294. utils.Debugf("Preparing to push %s with the following images and tags\n", localRepo)
  1295. for _, data := range imageIndex {
  1296. utils.Debugf("Pushing ID: %s with Tag: %s\n", data.ID, data.Tag)
  1297. }
  1298. // Register all the images in a repository with the registry
  1299. // If an image is not in this list it will not be associated with the repository
  1300. repoData, err = r.PushImageJSONIndex(remoteName, imageIndex, false, nil)
  1301. if err != nil {
  1302. return err
  1303. }
  1304. for _, ep := range repoData.Endpoints {
  1305. out.Write(sf.FormatStatus("", "Pushing repository %s (%d tags)", localName, len(localRepo)))
  1306. for _, imgId := range imgList {
  1307. if r.LookupRemoteImage(imgId, ep, repoData.Tokens) {
  1308. out.Write(sf.FormatStatus("", "Image %s already pushed, skipping", utils.TruncateID(imgId)))
  1309. } else {
  1310. if _, err := srv.pushImage(r, out, remoteName, imgId, ep, repoData.Tokens, sf); err != nil {
  1311. // FIXME: Continue on error?
  1312. return err
  1313. }
  1314. }
  1315. for _, tag := range tagsByImage[imgId] {
  1316. out.Write(sf.FormatStatus("", "Pushing tag for rev [%s] on {%s}", utils.TruncateID(imgId), ep+"repositories/"+remoteName+"/tags/"+tag))
  1317. if err := r.PushRegistryTag(remoteName, imgId, tag, ep, repoData.Tokens); err != nil {
  1318. return err
  1319. }
  1320. }
  1321. }
  1322. }
  1323. if _, err := r.PushImageJSONIndex(remoteName, imageIndex, true, repoData.Endpoints); err != nil {
  1324. return err
  1325. }
  1326. return nil
  1327. }
  1328. func (srv *Server) pushImage(r *registry.Registry, out io.Writer, remote, imgID, ep string, token []string, sf *utils.StreamFormatter) (checksum string, err error) {
  1329. out = utils.NewWriteFlusher(out)
  1330. jsonRaw, err := ioutil.ReadFile(path.Join(srv.runtime.graph.Root, imgID, "json"))
  1331. if err != nil {
  1332. return "", fmt.Errorf("Cannot retrieve the path for {%s}: %s", imgID, err)
  1333. }
  1334. out.Write(sf.FormatProgress(utils.TruncateID(imgID), "Pushing", nil))
  1335. imgData := &registry.ImgData{
  1336. ID: imgID,
  1337. }
  1338. // Send the json
  1339. if err := r.PushImageJSONRegistry(imgData, jsonRaw, ep, token); err != nil {
  1340. if err == registry.ErrAlreadyExists {
  1341. out.Write(sf.FormatProgress(utils.TruncateID(imgData.ID), "Image already pushed, skipping", nil))
  1342. return "", nil
  1343. }
  1344. return "", err
  1345. }
  1346. layerData, err := srv.runtime.graph.TempLayerArchive(imgID, archive.Uncompressed, sf, out)
  1347. if err != nil {
  1348. return "", fmt.Errorf("Failed to generate layer archive: %s", err)
  1349. }
  1350. defer os.RemoveAll(layerData.Name())
  1351. // Send the layer
  1352. checksum, err = r.PushImageLayerRegistry(imgData.ID, utils.ProgressReader(layerData, int(layerData.Size), out, sf, false, utils.TruncateID(imgData.ID), "Pushing"), ep, token, jsonRaw)
  1353. if err != nil {
  1354. return "", err
  1355. }
  1356. imgData.Checksum = checksum
  1357. // Send the checksum
  1358. if err := r.PushImageChecksumRegistry(imgData, ep, token); err != nil {
  1359. return "", err
  1360. }
  1361. out.Write(sf.FormatProgress(utils.TruncateID(imgData.ID), "Image successfully pushed", nil))
  1362. return imgData.Checksum, nil
  1363. }
  1364. // FIXME: Allow to interrupt current push when new push of same image is done.
  1365. func (srv *Server) ImagePush(job *engine.Job) engine.Status {
  1366. if n := len(job.Args); n != 1 {
  1367. return job.Errorf("Usage: %s IMAGE", job.Name)
  1368. }
  1369. var (
  1370. localName = job.Args[0]
  1371. sf = utils.NewStreamFormatter(job.GetenvBool("json"))
  1372. authConfig = &auth.AuthConfig{}
  1373. metaHeaders map[string][]string
  1374. )
  1375. job.GetenvJson("authConfig", authConfig)
  1376. job.GetenvJson("metaHeaders", metaHeaders)
  1377. if _, err := srv.poolAdd("push", localName); err != nil {
  1378. return job.Error(err)
  1379. }
  1380. defer srv.poolRemove("push", localName)
  1381. // Resolve the Repository name from fqn to endpoint + name
  1382. endpoint, remoteName, err := registry.ResolveRepositoryName(localName)
  1383. if err != nil {
  1384. return job.Error(err)
  1385. }
  1386. img, err := srv.runtime.graph.Get(localName)
  1387. r, err2 := registry.NewRegistry(authConfig, srv.HTTPRequestFactory(metaHeaders), endpoint)
  1388. if err2 != nil {
  1389. return job.Error(err2)
  1390. }
  1391. if err != nil {
  1392. reposLen := len(srv.runtime.repositories.Repositories[localName])
  1393. job.Stdout.Write(sf.FormatStatus("", "The push refers to a repository [%s] (len: %d)", localName, reposLen))
  1394. // If it fails, try to get the repository
  1395. if localRepo, exists := srv.runtime.repositories.Repositories[localName]; exists {
  1396. if err := srv.pushRepository(r, job.Stdout, localName, remoteName, localRepo, sf); err != nil {
  1397. return job.Error(err)
  1398. }
  1399. return engine.StatusOK
  1400. }
  1401. return job.Error(err)
  1402. }
  1403. var token []string
  1404. job.Stdout.Write(sf.FormatStatus("", "The push refers to an image: [%s]", localName))
  1405. if _, err := srv.pushImage(r, job.Stdout, remoteName, img.ID, endpoint, token, sf); err != nil {
  1406. return job.Error(err)
  1407. }
  1408. return engine.StatusOK
  1409. }
  1410. func (srv *Server) ImageImport(job *engine.Job) engine.Status {
  1411. if n := len(job.Args); n != 2 && n != 3 {
  1412. return job.Errorf("Usage: %s SRC REPO [TAG]", job.Name)
  1413. }
  1414. var (
  1415. src = job.Args[0]
  1416. repo = job.Args[1]
  1417. tag string
  1418. sf = utils.NewStreamFormatter(job.GetenvBool("json"))
  1419. archive archive.ArchiveReader
  1420. resp *http.Response
  1421. )
  1422. if len(job.Args) > 2 {
  1423. tag = job.Args[2]
  1424. }
  1425. if src == "-" {
  1426. archive = job.Stdin
  1427. } else {
  1428. u, err := url.Parse(src)
  1429. if err != nil {
  1430. return job.Error(err)
  1431. }
  1432. if u.Scheme == "" {
  1433. u.Scheme = "http"
  1434. u.Host = src
  1435. u.Path = ""
  1436. }
  1437. job.Stdout.Write(sf.FormatStatus("", "Downloading from %s", u))
  1438. // Download with curl (pretty progress bar)
  1439. // If curl is not available, fallback to http.Get()
  1440. resp, err = utils.Download(u.String())
  1441. if err != nil {
  1442. return job.Error(err)
  1443. }
  1444. progressReader := utils.ProgressReader(resp.Body, int(resp.ContentLength), job.Stdout, sf, true, "", "Importing")
  1445. defer progressReader.Close()
  1446. archive = progressReader
  1447. }
  1448. img, err := srv.runtime.graph.Create(archive, nil, "Imported from "+src, "", nil)
  1449. if err != nil {
  1450. return job.Error(err)
  1451. }
  1452. // Optionally register the image at REPO/TAG
  1453. if repo != "" {
  1454. if err := srv.runtime.repositories.Set(repo, tag, img.ID, true); err != nil {
  1455. return job.Error(err)
  1456. }
  1457. }
  1458. job.Stdout.Write(sf.FormatStatus("", img.ID))
  1459. return engine.StatusOK
  1460. }
  1461. func (srv *Server) ContainerCreate(job *engine.Job) engine.Status {
  1462. var name string
  1463. if len(job.Args) == 1 {
  1464. name = job.Args[0]
  1465. } else if len(job.Args) > 1 {
  1466. return job.Errorf("Usage: %s", job.Name)
  1467. }
  1468. config := runconfig.ContainerConfigFromJob(job)
  1469. if config.Memory != 0 && config.Memory < 524288 {
  1470. return job.Errorf("Minimum memory limit allowed is 512k")
  1471. }
  1472. if config.Memory > 0 && !srv.runtime.sysInfo.MemoryLimit {
  1473. job.Errorf("WARNING: Your kernel does not support memory limit capabilities. Limitation discarded.\n")
  1474. config.Memory = 0
  1475. }
  1476. if config.Memory > 0 && !srv.runtime.sysInfo.SwapLimit {
  1477. job.Errorf("WARNING: Your kernel does not support swap limit capabilities. Limitation discarded.\n")
  1478. config.MemorySwap = -1
  1479. }
  1480. resolvConf, err := utils.GetResolvConf()
  1481. if err != nil {
  1482. return job.Error(err)
  1483. }
  1484. if !config.NetworkDisabled && len(config.Dns) == 0 && len(srv.runtime.config.Dns) == 0 && utils.CheckLocalDns(resolvConf) {
  1485. job.Errorf("WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : %v\n", defaultDns)
  1486. config.Dns = defaultDns
  1487. }
  1488. container, buildWarnings, err := srv.runtime.Create(config, name)
  1489. if err != nil {
  1490. if srv.runtime.graph.IsNotExist(err) {
  1491. _, tag := utils.ParseRepositoryTag(config.Image)
  1492. if tag == "" {
  1493. tag = DEFAULTTAG
  1494. }
  1495. return job.Errorf("No such image: %s (tag: %s)", config.Image, tag)
  1496. }
  1497. return job.Error(err)
  1498. }
  1499. if !container.Config.NetworkDisabled && srv.runtime.sysInfo.IPv4ForwardingDisabled {
  1500. job.Errorf("WARNING: IPv4 forwarding is disabled.\n")
  1501. }
  1502. srv.LogEvent("create", container.ID, srv.runtime.repositories.ImageName(container.Image))
  1503. // FIXME: this is necessary because runtime.Create might return a nil container
  1504. // with a non-nil error. This should not happen! Once it's fixed we
  1505. // can remove this workaround.
  1506. if container != nil {
  1507. job.Printf("%s\n", container.ID)
  1508. }
  1509. for _, warning := range buildWarnings {
  1510. return job.Errorf("%s\n", warning)
  1511. }
  1512. return engine.StatusOK
  1513. }
  1514. func (srv *Server) ContainerRestart(job *engine.Job) engine.Status {
  1515. if len(job.Args) != 1 {
  1516. return job.Errorf("Usage: %s CONTAINER\n", job.Name)
  1517. }
  1518. var (
  1519. name = job.Args[0]
  1520. t = 10
  1521. )
  1522. if job.EnvExists("t") {
  1523. t = job.GetenvInt("t")
  1524. }
  1525. if container := srv.runtime.Get(name); container != nil {
  1526. if err := container.Restart(int(t)); err != nil {
  1527. return job.Errorf("Cannot restart container %s: %s\n", name, err)
  1528. }
  1529. srv.LogEvent("restart", container.ID, srv.runtime.repositories.ImageName(container.Image))
  1530. } else {
  1531. return job.Errorf("No such container: %s\n", name)
  1532. }
  1533. return engine.StatusOK
  1534. }
  1535. func (srv *Server) ContainerDestroy(job *engine.Job) engine.Status {
  1536. if len(job.Args) != 1 {
  1537. return job.Errorf("Not enough arguments. Usage: %s CONTAINER\n", job.Name)
  1538. }
  1539. name := job.Args[0]
  1540. removeVolume := job.GetenvBool("removeVolume")
  1541. removeLink := job.GetenvBool("removeLink")
  1542. container := srv.runtime.Get(name)
  1543. if removeLink {
  1544. if container == nil {
  1545. return job.Errorf("No such link: %s", name)
  1546. }
  1547. name, err := getFullName(name)
  1548. if err != nil {
  1549. job.Error(err)
  1550. }
  1551. parent, n := path.Split(name)
  1552. if parent == "/" {
  1553. return job.Errorf("Conflict, cannot remove the default name of the container")
  1554. }
  1555. pe := srv.runtime.containerGraph.Get(parent)
  1556. if pe == nil {
  1557. return job.Errorf("Cannot get parent %s for name %s", parent, name)
  1558. }
  1559. parentContainer := srv.runtime.Get(pe.ID())
  1560. if parentContainer != nil && parentContainer.activeLinks != nil {
  1561. if link, exists := parentContainer.activeLinks[n]; exists {
  1562. link.Disable()
  1563. } else {
  1564. utils.Debugf("Could not find active link for %s", name)
  1565. }
  1566. }
  1567. if err := srv.runtime.containerGraph.Delete(name); err != nil {
  1568. return job.Error(err)
  1569. }
  1570. return engine.StatusOK
  1571. }
  1572. if container != nil {
  1573. if container.State.IsRunning() {
  1574. return job.Errorf("Impossible to remove a running container, please stop it first")
  1575. }
  1576. if err := srv.runtime.Destroy(container); err != nil {
  1577. return job.Errorf("Cannot destroy container %s: %s", name, err)
  1578. }
  1579. srv.LogEvent("destroy", container.ID, srv.runtime.repositories.ImageName(container.Image))
  1580. if removeVolume {
  1581. var (
  1582. volumes = make(map[string]struct{})
  1583. binds = make(map[string]struct{})
  1584. usedVolumes = make(map[string]*Container)
  1585. )
  1586. // the volume id is always the base of the path
  1587. getVolumeId := func(p string) string {
  1588. return filepath.Base(strings.TrimSuffix(p, "/layer"))
  1589. }
  1590. // populate bind map so that they can be skipped and not removed
  1591. for _, bind := range container.hostConfig.Binds {
  1592. source := strings.Split(bind, ":")[0]
  1593. // TODO: refactor all volume stuff, all of it
  1594. // this is very important that we eval the link
  1595. // or comparing the keys to container.Volumes will not work
  1596. p, err := filepath.EvalSymlinks(source)
  1597. if err != nil {
  1598. return job.Error(err)
  1599. }
  1600. source = p
  1601. binds[source] = struct{}{}
  1602. }
  1603. // Store all the deleted containers volumes
  1604. for _, volumeId := range container.Volumes {
  1605. // Skip the volumes mounted from external
  1606. // bind mounts here will will be evaluated for a symlink
  1607. if _, exists := binds[volumeId]; exists {
  1608. continue
  1609. }
  1610. volumeId = getVolumeId(volumeId)
  1611. volumes[volumeId] = struct{}{}
  1612. }
  1613. // Retrieve all volumes from all remaining containers
  1614. for _, container := range srv.runtime.List() {
  1615. for _, containerVolumeId := range container.Volumes {
  1616. containerVolumeId = getVolumeId(containerVolumeId)
  1617. usedVolumes[containerVolumeId] = container
  1618. }
  1619. }
  1620. for volumeId := range volumes {
  1621. // If the requested volu
  1622. if c, exists := usedVolumes[volumeId]; exists {
  1623. log.Printf("The volume %s is used by the container %s. Impossible to remove it. Skipping.\n", volumeId, c.ID)
  1624. continue
  1625. }
  1626. if err := srv.runtime.volumes.Delete(volumeId); err != nil {
  1627. return job.Errorf("Error calling volumes.Delete(%q): %v", volumeId, err)
  1628. }
  1629. }
  1630. }
  1631. } else {
  1632. return job.Errorf("No such container: %s", name)
  1633. }
  1634. return engine.StatusOK
  1635. }
  1636. var ErrImageReferenced = errors.New("Image referenced by a repository")
  1637. func (srv *Server) deleteImageAndChildren(id string, imgs *engine.Table, byParents map[string][]*Image) error {
  1638. // If the image is referenced by a repo, do not delete
  1639. if len(srv.runtime.repositories.ByID()[id]) != 0 {
  1640. return ErrImageReferenced
  1641. }
  1642. // If the image is not referenced but has children, go recursive
  1643. referenced := false
  1644. for _, img := range byParents[id] {
  1645. if err := srv.deleteImageAndChildren(img.ID, imgs, byParents); err != nil {
  1646. if err != ErrImageReferenced {
  1647. return err
  1648. }
  1649. referenced = true
  1650. }
  1651. }
  1652. if referenced {
  1653. return ErrImageReferenced
  1654. }
  1655. // If the image is not referenced and has no children, remove it
  1656. byParents, err := srv.runtime.graph.ByParent()
  1657. if err != nil {
  1658. return err
  1659. }
  1660. if len(byParents[id]) == 0 && srv.canDeleteImage(id) == nil {
  1661. if err := srv.runtime.repositories.DeleteAll(id); err != nil {
  1662. return err
  1663. }
  1664. err := srv.runtime.graph.Delete(id)
  1665. if err != nil {
  1666. return err
  1667. }
  1668. out := &engine.Env{}
  1669. out.Set("Deleted", id)
  1670. imgs.Add(out)
  1671. srv.LogEvent("delete", id, "")
  1672. return nil
  1673. }
  1674. return nil
  1675. }
  1676. func (srv *Server) deleteImageParents(img *Image, imgs *engine.Table) error {
  1677. if img.Parent != "" {
  1678. parent, err := srv.runtime.graph.Get(img.Parent)
  1679. if err != nil {
  1680. return err
  1681. }
  1682. byParents, err := srv.runtime.graph.ByParent()
  1683. if err != nil {
  1684. return err
  1685. }
  1686. // Remove all children images
  1687. if err := srv.deleteImageAndChildren(img.Parent, imgs, byParents); err != nil {
  1688. return err
  1689. }
  1690. return srv.deleteImageParents(parent, imgs)
  1691. }
  1692. return nil
  1693. }
  1694. func (srv *Server) DeleteImage(name string, autoPrune bool) (*engine.Table, error) {
  1695. var (
  1696. repoName, tag string
  1697. img, err = srv.runtime.repositories.LookupImage(name)
  1698. imgs = engine.NewTable("", 0)
  1699. tags = []string{}
  1700. )
  1701. if err != nil {
  1702. return nil, fmt.Errorf("No such image: %s", name)
  1703. }
  1704. // FIXME: What does autoPrune mean ?
  1705. if !autoPrune {
  1706. if err := srv.runtime.graph.Delete(img.ID); err != nil {
  1707. return nil, fmt.Errorf("Cannot delete image %s: %s", name, err)
  1708. }
  1709. return nil, nil
  1710. }
  1711. if !strings.Contains(img.ID, name) {
  1712. repoName, tag = utils.ParseRepositoryTag(name)
  1713. }
  1714. // If we have a repo and the image is not referenced anywhere else
  1715. // then just perform an untag and do not validate.
  1716. //
  1717. // i.e. only validate if we are performing an actual delete and not
  1718. // an untag op
  1719. if repoName != "" && len(srv.runtime.repositories.ByID()[img.ID]) == 1 {
  1720. // Prevent deletion if image is used by a container
  1721. if err := srv.canDeleteImage(img.ID); err != nil {
  1722. return nil, err
  1723. }
  1724. }
  1725. //If delete by id, see if the id belong only to one repository
  1726. if repoName == "" {
  1727. for _, repoAndTag := range srv.runtime.repositories.ByID()[img.ID] {
  1728. parsedRepo, parsedTag := utils.ParseRepositoryTag(repoAndTag)
  1729. if repoName == "" || repoName == parsedRepo {
  1730. repoName = parsedRepo
  1731. if parsedTag != "" {
  1732. tags = append(tags, parsedTag)
  1733. }
  1734. } else if repoName != parsedRepo {
  1735. // the id belongs to multiple repos, like base:latest and user:test,
  1736. // in that case return conflict
  1737. return nil, fmt.Errorf("Conflict, cannot delete image %s because it is tagged in multiple repositories", utils.TruncateID(img.ID))
  1738. }
  1739. }
  1740. } else {
  1741. tags = append(tags, tag)
  1742. }
  1743. //Untag the current image
  1744. for _, tag := range tags {
  1745. tagDeleted, err := srv.runtime.repositories.Delete(repoName, tag)
  1746. if err != nil {
  1747. return nil, err
  1748. }
  1749. if tagDeleted {
  1750. out := &engine.Env{}
  1751. out.Set("Untagged", img.ID)
  1752. imgs.Add(out)
  1753. srv.LogEvent("untag", img.ID, "")
  1754. }
  1755. }
  1756. if len(srv.runtime.repositories.ByID()[img.ID]) == 0 {
  1757. if err := srv.deleteImageAndChildren(img.ID, imgs, nil); err != nil {
  1758. if err != ErrImageReferenced {
  1759. return imgs, err
  1760. }
  1761. } else if err := srv.deleteImageParents(img, imgs); err != nil {
  1762. if err != ErrImageReferenced {
  1763. return imgs, err
  1764. }
  1765. }
  1766. }
  1767. return imgs, nil
  1768. }
  1769. func (srv *Server) ImageDelete(job *engine.Job) engine.Status {
  1770. if n := len(job.Args); n != 1 {
  1771. return job.Errorf("Usage: %s IMAGE", job.Name)
  1772. }
  1773. imgs, err := srv.DeleteImage(job.Args[0], job.GetenvBool("autoPrune"))
  1774. if err != nil {
  1775. return job.Error(err)
  1776. }
  1777. if len(imgs.Data) == 0 {
  1778. return job.Errorf("Conflict, %s wasn't deleted", job.Args[0])
  1779. }
  1780. if _, err := imgs.WriteListTo(job.Stdout); err != nil {
  1781. return job.Error(err)
  1782. }
  1783. return engine.StatusOK
  1784. }
  1785. func (srv *Server) canDeleteImage(imgID string) error {
  1786. for _, container := range srv.runtime.List() {
  1787. parent, err := srv.runtime.repositories.LookupImage(container.Image)
  1788. if err != nil {
  1789. return err
  1790. }
  1791. if err := parent.WalkHistory(func(p *Image) error {
  1792. if imgID == p.ID {
  1793. return fmt.Errorf("Conflict, cannot delete %s because the container %s is using it", utils.TruncateID(imgID), utils.TruncateID(container.ID))
  1794. }
  1795. return nil
  1796. }); err != nil {
  1797. return err
  1798. }
  1799. }
  1800. return nil
  1801. }
  1802. func (srv *Server) ImageGetCached(imgID string, config *runconfig.Config) (*Image, error) {
  1803. // Retrieve all images
  1804. images, err := srv.runtime.graph.Map()
  1805. if err != nil {
  1806. return nil, err
  1807. }
  1808. // Store the tree in a map of map (map[parentId][childId])
  1809. imageMap := make(map[string]map[string]struct{})
  1810. for _, img := range images {
  1811. if _, exists := imageMap[img.Parent]; !exists {
  1812. imageMap[img.Parent] = make(map[string]struct{})
  1813. }
  1814. imageMap[img.Parent][img.ID] = struct{}{}
  1815. }
  1816. // Loop on the children of the given image and check the config
  1817. var match *Image
  1818. for elem := range imageMap[imgID] {
  1819. img, err := srv.runtime.graph.Get(elem)
  1820. if err != nil {
  1821. return nil, err
  1822. }
  1823. if runconfig.Compare(&img.ContainerConfig, config) {
  1824. if match == nil || match.Created.Before(img.Created) {
  1825. match = img
  1826. }
  1827. }
  1828. }
  1829. return match, nil
  1830. }
  1831. func (srv *Server) RegisterLinks(container *Container, hostConfig *runconfig.HostConfig) error {
  1832. runtime := srv.runtime
  1833. if hostConfig != nil && hostConfig.Links != nil {
  1834. for _, l := range hostConfig.Links {
  1835. parts, err := parseLink(l)
  1836. if err != nil {
  1837. return err
  1838. }
  1839. child, err := srv.runtime.GetByName(parts["name"])
  1840. if err != nil {
  1841. return err
  1842. }
  1843. if child == nil {
  1844. return fmt.Errorf("Could not get container for %s", parts["name"])
  1845. }
  1846. if err := runtime.RegisterLink(container, child, parts["alias"]); err != nil {
  1847. return err
  1848. }
  1849. }
  1850. // After we load all the links into the runtime
  1851. // set them to nil on the hostconfig
  1852. hostConfig.Links = nil
  1853. if err := container.writeHostConfig(); err != nil {
  1854. return err
  1855. }
  1856. }
  1857. return nil
  1858. }
  1859. func (srv *Server) ContainerStart(job *engine.Job) engine.Status {
  1860. if len(job.Args) < 1 {
  1861. return job.Errorf("Usage: %s container_id", job.Name)
  1862. }
  1863. name := job.Args[0]
  1864. runtime := srv.runtime
  1865. container := runtime.Get(name)
  1866. if container == nil {
  1867. return job.Errorf("No such container: %s", name)
  1868. }
  1869. // If no environment was set, then no hostconfig was passed.
  1870. if len(job.Environ()) > 0 {
  1871. hostConfig := runconfig.ContainerHostConfigFromJob(job)
  1872. // Validate the HostConfig binds. Make sure that:
  1873. // 1) the source of a bind mount isn't /
  1874. // The bind mount "/:/foo" isn't allowed.
  1875. // 2) Check that the source exists
  1876. // The source to be bind mounted must exist.
  1877. for _, bind := range hostConfig.Binds {
  1878. splitBind := strings.Split(bind, ":")
  1879. source := splitBind[0]
  1880. // refuse to bind mount "/" to the container
  1881. if source == "/" {
  1882. return job.Errorf("Invalid bind mount '%s' : source can't be '/'", bind)
  1883. }
  1884. // ensure the source exists on the host
  1885. _, err := os.Stat(source)
  1886. if err != nil && os.IsNotExist(err) {
  1887. err = os.MkdirAll(source, 0755)
  1888. if err != nil {
  1889. return job.Errorf("Could not create local directory '%s' for bind mount: %s!", source, err.Error())
  1890. }
  1891. }
  1892. }
  1893. // Register any links from the host config before starting the container
  1894. if err := srv.RegisterLinks(container, hostConfig); err != nil {
  1895. return job.Error(err)
  1896. }
  1897. container.hostConfig = hostConfig
  1898. container.ToDisk()
  1899. }
  1900. if err := container.Start(); err != nil {
  1901. return job.Errorf("Cannot start container %s: %s", name, err)
  1902. }
  1903. srv.LogEvent("start", container.ID, runtime.repositories.ImageName(container.Image))
  1904. return engine.StatusOK
  1905. }
  1906. func (srv *Server) ContainerStop(job *engine.Job) engine.Status {
  1907. if len(job.Args) != 1 {
  1908. return job.Errorf("Usage: %s CONTAINER\n", job.Name)
  1909. }
  1910. var (
  1911. name = job.Args[0]
  1912. t = 10
  1913. )
  1914. if job.EnvExists("t") {
  1915. t = job.GetenvInt("t")
  1916. }
  1917. if container := srv.runtime.Get(name); container != nil {
  1918. if err := container.Stop(int(t)); err != nil {
  1919. return job.Errorf("Cannot stop container %s: %s\n", name, err)
  1920. }
  1921. srv.LogEvent("stop", container.ID, srv.runtime.repositories.ImageName(container.Image))
  1922. } else {
  1923. return job.Errorf("No such container: %s\n", name)
  1924. }
  1925. return engine.StatusOK
  1926. }
  1927. func (srv *Server) ContainerWait(job *engine.Job) engine.Status {
  1928. if len(job.Args) != 1 {
  1929. return job.Errorf("Usage: %s", job.Name)
  1930. }
  1931. name := job.Args[0]
  1932. if container := srv.runtime.Get(name); container != nil {
  1933. status := container.Wait()
  1934. job.Printf("%d\n", status)
  1935. return engine.StatusOK
  1936. }
  1937. return job.Errorf("%s: no such container: %s", job.Name, name)
  1938. }
  1939. func (srv *Server) ContainerResize(job *engine.Job) engine.Status {
  1940. if len(job.Args) != 3 {
  1941. return job.Errorf("Not enough arguments. Usage: %s CONTAINER HEIGHT WIDTH\n", job.Name)
  1942. }
  1943. name := job.Args[0]
  1944. height, err := strconv.Atoi(job.Args[1])
  1945. if err != nil {
  1946. return job.Error(err)
  1947. }
  1948. width, err := strconv.Atoi(job.Args[2])
  1949. if err != nil {
  1950. return job.Error(err)
  1951. }
  1952. if container := srv.runtime.Get(name); container != nil {
  1953. if err := container.Resize(height, width); err != nil {
  1954. return job.Error(err)
  1955. }
  1956. return engine.StatusOK
  1957. }
  1958. return job.Errorf("No such container: %s", name)
  1959. }
  1960. func (srv *Server) ContainerAttach(job *engine.Job) engine.Status {
  1961. if len(job.Args) != 1 {
  1962. return job.Errorf("Usage: %s CONTAINER\n", job.Name)
  1963. }
  1964. var (
  1965. name = job.Args[0]
  1966. logs = job.GetenvBool("logs")
  1967. stream = job.GetenvBool("stream")
  1968. stdin = job.GetenvBool("stdin")
  1969. stdout = job.GetenvBool("stdout")
  1970. stderr = job.GetenvBool("stderr")
  1971. )
  1972. container := srv.runtime.Get(name)
  1973. if container == nil {
  1974. return job.Errorf("No such container: %s", name)
  1975. }
  1976. //logs
  1977. if logs {
  1978. cLog, err := container.ReadLog("json")
  1979. if err != nil && os.IsNotExist(err) {
  1980. // Legacy logs
  1981. utils.Debugf("Old logs format")
  1982. if stdout {
  1983. cLog, err := container.ReadLog("stdout")
  1984. if err != nil {
  1985. utils.Errorf("Error reading logs (stdout): %s", err)
  1986. } else if _, err := io.Copy(job.Stdout, cLog); err != nil {
  1987. utils.Errorf("Error streaming logs (stdout): %s", err)
  1988. }
  1989. }
  1990. if stderr {
  1991. cLog, err := container.ReadLog("stderr")
  1992. if err != nil {
  1993. utils.Errorf("Error reading logs (stderr): %s", err)
  1994. } else if _, err := io.Copy(job.Stderr, cLog); err != nil {
  1995. utils.Errorf("Error streaming logs (stderr): %s", err)
  1996. }
  1997. }
  1998. } else if err != nil {
  1999. utils.Errorf("Error reading logs (json): %s", err)
  2000. } else {
  2001. dec := json.NewDecoder(cLog)
  2002. for {
  2003. l := &utils.JSONLog{}
  2004. if err := dec.Decode(l); err == io.EOF {
  2005. break
  2006. } else if err != nil {
  2007. utils.Errorf("Error streaming logs: %s", err)
  2008. break
  2009. }
  2010. if l.Stream == "stdout" && stdout {
  2011. fmt.Fprintf(job.Stdout, "%s", l.Log)
  2012. }
  2013. if l.Stream == "stderr" && stderr {
  2014. fmt.Fprintf(job.Stderr, "%s", l.Log)
  2015. }
  2016. }
  2017. }
  2018. }
  2019. //stream
  2020. if stream {
  2021. if container.State.IsGhost() {
  2022. return job.Errorf("Impossible to attach to a ghost container")
  2023. }
  2024. var (
  2025. cStdin io.ReadCloser
  2026. cStdout, cStderr io.Writer
  2027. cStdinCloser io.Closer
  2028. )
  2029. if stdin {
  2030. r, w := io.Pipe()
  2031. go func() {
  2032. defer w.Close()
  2033. defer utils.Debugf("Closing buffered stdin pipe")
  2034. io.Copy(w, job.Stdin)
  2035. }()
  2036. cStdin = r
  2037. cStdinCloser = job.Stdin
  2038. }
  2039. if stdout {
  2040. cStdout = job.Stdout
  2041. }
  2042. if stderr {
  2043. cStderr = job.Stderr
  2044. }
  2045. <-container.Attach(cStdin, cStdinCloser, cStdout, cStderr)
  2046. // If we are in stdinonce mode, wait for the process to end
  2047. // otherwise, simply return
  2048. if container.Config.StdinOnce && !container.Config.Tty {
  2049. container.Wait()
  2050. }
  2051. }
  2052. return engine.StatusOK
  2053. }
  2054. func (srv *Server) ContainerInspect(name string) (*Container, error) {
  2055. if container := srv.runtime.Get(name); container != nil {
  2056. return container, nil
  2057. }
  2058. return nil, fmt.Errorf("No such container: %s", name)
  2059. }
  2060. func (srv *Server) ImageInspect(name string) (*Image, error) {
  2061. if image, err := srv.runtime.repositories.LookupImage(name); err == nil && image != nil {
  2062. return image, nil
  2063. }
  2064. return nil, fmt.Errorf("No such image: %s", name)
  2065. }
  2066. func (srv *Server) JobInspect(job *engine.Job) engine.Status {
  2067. // TODO: deprecate KIND/conflict
  2068. if n := len(job.Args); n != 2 {
  2069. return job.Errorf("Usage: %s CONTAINER|IMAGE KIND", job.Name)
  2070. }
  2071. var (
  2072. name = job.Args[0]
  2073. kind = job.Args[1]
  2074. object interface{}
  2075. conflict = job.GetenvBool("conflict") //should the job detect conflict between containers and images
  2076. image, errImage = srv.ImageInspect(name)
  2077. container, errContainer = srv.ContainerInspect(name)
  2078. )
  2079. if conflict && image != nil && container != nil {
  2080. return job.Errorf("Conflict between containers and images")
  2081. }
  2082. switch kind {
  2083. case "image":
  2084. if errImage != nil {
  2085. return job.Error(errImage)
  2086. }
  2087. object = image
  2088. case "container":
  2089. if errContainer != nil {
  2090. return job.Error(errContainer)
  2091. }
  2092. object = &struct {
  2093. *Container
  2094. HostConfig *runconfig.HostConfig
  2095. }{container, container.hostConfig}
  2096. default:
  2097. return job.Errorf("Unknown kind: %s", kind)
  2098. }
  2099. b, err := json.Marshal(object)
  2100. if err != nil {
  2101. return job.Error(err)
  2102. }
  2103. job.Stdout.Write(b)
  2104. return engine.StatusOK
  2105. }
  2106. func (srv *Server) ContainerCopy(job *engine.Job) engine.Status {
  2107. if len(job.Args) != 2 {
  2108. return job.Errorf("Usage: %s CONTAINER RESOURCE\n", job.Name)
  2109. }
  2110. var (
  2111. name = job.Args[0]
  2112. resource = job.Args[1]
  2113. )
  2114. if container := srv.runtime.Get(name); container != nil {
  2115. data, err := container.Copy(resource)
  2116. if err != nil {
  2117. return job.Error(err)
  2118. }
  2119. defer data.Close()
  2120. if _, err := io.Copy(job.Stdout, data); err != nil {
  2121. return job.Error(err)
  2122. }
  2123. return engine.StatusOK
  2124. }
  2125. return job.Errorf("No such container: %s", name)
  2126. }
  2127. func NewServer(eng *engine.Engine, config *DaemonConfig) (*Server, error) {
  2128. runtime, err := NewRuntime(config, eng)
  2129. if err != nil {
  2130. return nil, err
  2131. }
  2132. srv := &Server{
  2133. Eng: eng,
  2134. runtime: runtime,
  2135. pullingPool: make(map[string]chan struct{}),
  2136. pushingPool: make(map[string]chan struct{}),
  2137. events: make([]utils.JSONMessage, 0, 64), //only keeps the 64 last events
  2138. listeners: make(map[string]chan utils.JSONMessage),
  2139. }
  2140. runtime.srv = srv
  2141. return srv, nil
  2142. }
  2143. func (srv *Server) HTTPRequestFactory(metaHeaders map[string][]string) *utils.HTTPRequestFactory {
  2144. srv.Lock()
  2145. defer srv.Unlock()
  2146. v := dockerVersion()
  2147. httpVersion := make([]utils.VersionInfo, 0, 4)
  2148. httpVersion = append(httpVersion, &simpleVersionInfo{"docker", v.Get("Version")})
  2149. httpVersion = append(httpVersion, &simpleVersionInfo{"go", v.Get("GoVersion")})
  2150. httpVersion = append(httpVersion, &simpleVersionInfo{"git-commit", v.Get("GitCommit")})
  2151. httpVersion = append(httpVersion, &simpleVersionInfo{"kernel", v.Get("KernelVersion")})
  2152. httpVersion = append(httpVersion, &simpleVersionInfo{"os", v.Get("Os")})
  2153. httpVersion = append(httpVersion, &simpleVersionInfo{"arch", v.Get("Arch")})
  2154. ud := utils.NewHTTPUserAgentDecorator(httpVersion...)
  2155. md := &utils.HTTPMetaHeadersDecorator{
  2156. Headers: metaHeaders,
  2157. }
  2158. factory := utils.NewHTTPRequestFactory(ud, md)
  2159. return factory
  2160. }
  2161. func (srv *Server) LogEvent(action, id, from string) *utils.JSONMessage {
  2162. now := time.Now().UTC().Unix()
  2163. jm := utils.JSONMessage{Status: action, ID: id, From: from, Time: now}
  2164. srv.AddEvent(jm)
  2165. for _, c := range srv.listeners {
  2166. select { // non blocking channel
  2167. case c <- jm:
  2168. default:
  2169. }
  2170. }
  2171. return &jm
  2172. }
  2173. func (srv *Server) AddEvent(jm utils.JSONMessage) {
  2174. srv.Lock()
  2175. defer srv.Unlock()
  2176. srv.events = append(srv.events, jm)
  2177. }
  2178. func (srv *Server) GetEvents() []utils.JSONMessage {
  2179. srv.RLock()
  2180. defer srv.RUnlock()
  2181. return srv.events
  2182. }
  2183. type Server struct {
  2184. sync.RWMutex
  2185. runtime *Runtime
  2186. pullingPool map[string]chan struct{}
  2187. pushingPool map[string]chan struct{}
  2188. events []utils.JSONMessage
  2189. listeners map[string]chan utils.JSONMessage
  2190. Eng *engine.Engine
  2191. }