From da60e634a85e9045fbbe0c9bbc82e8febe64cd3e Mon Sep 17 00:00:00 2001 From: Marcos Lilljedahl Date: Wed, 21 Jun 2017 16:55:13 -0300 Subject: [PATCH 01/18] Add go a install linuxkit / moby --- .profile | 1 + Dockerfile.dind | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.profile b/.profile index 4fd34a7..ac9d1f9 100644 --- a/.profile +++ b/.profile @@ -1,3 +1,4 @@ export PS1='\e[1m\e[31m[\h] \e[32m($(docker-prompt)) \e[34m\u@$(hostname -i)\e[35m \w\e[0m\n$ ' alias vi='vim' +export PATH=$PATH:/root/go/bin cat /etc/motd diff --git a/Dockerfile.dind b/Dockerfile.dind index 2b7378f..8b92f4a 100644 --- a/Dockerfile.dind +++ b/Dockerfile.dind @@ -1,8 +1,15 @@ ARG VERSION=docker:17.05.0-ce-dind FROM ${VERSION} -RUN apk add --no-cache git tmux py2-pip apache2-utils vim build-base gettext-dev curl bash-completion bash util-linux jq openssh +RUN apk add --no-cache git tmux py2-pip apache2-utils vim build-base gettext-dev curl bash-completion bash util-linux jq openssh go \ + && mkdir /root/go +ENV GOPATH /root/go +ENV PATH $PATH:$GOPATH + +# Download moby and linuxkit + +RUN go get -u github.com/moby/tool/cmd/moby github.com/linuxkit/linuxkit/src/cmd/linuxkit # Compile and install httping # (used in orchestration workshop, and very useful anyway) From 00ef9dacd1d1b1207c278abf4477811cd1b57b10 Mon Sep 17 00:00:00 2001 From: Mano Marks Date: Mon, 19 Jun 2017 10:27:34 -0700 Subject: [PATCH 02/18] updating logo --- www/assets/.DS_Store | Bin 0 -> 6148 bytes www/assets/full_horizontal.svg | 115 +++++++++++++++++++++++++++++++++ www/assets/large_h.png | Bin 35802 -> 0 bytes www/welcome.html | 2 +- 4 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 www/assets/.DS_Store create mode 100644 www/assets/full_horizontal.svg delete mode 100644 www/assets/large_h.png diff --git a/www/assets/.DS_Store b/www/assets/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 + + + +full_horizontal +Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/www/assets/large_h.png b/www/assets/large_h.png deleted file mode 100644 index eddd2b6cc2b026fa9d8a4c8b3ad6faa03837b56a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35802 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 aMJ^iq6+0e!@0B&`pr2~!KQ33Zjrf0w>NU>* diff --git a/www/welcome.html b/www/welcome.html index 6a74da9..3262346 100644 --- a/www/welcome.html +++ b/www/welcome.html @@ -19,7 +19,7 @@ - + + + + From 632adee6533caa62b916753a5771f71f1ec37040 Mon Sep 17 00:00:00 2001 From: Marcos Lilljedahl Date: Mon, 10 Jul 2017 15:55:13 -0300 Subject: [PATCH 10/18] Fix stack diaglog terminal render --- www/assets/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/assets/app.js b/www/assets/app.js index 75d735b..2d17cc6 100644 --- a/www/assets/app.js +++ b/www/assets/app.js @@ -105,7 +105,7 @@ if (!state) { $mdDialog.show({ - controller: SessionBuilderModalController, + onComplete: function(){SessionBuilderModalController($mdDialog, $scope)}, contentElement: '#builderDialog', parent: angular.element(document.body), clickOutsideToClose: false, From 5bd30907b8105919845f5b89f63754dd3a5b8367 Mon Sep 17 00:00:00 2001 From: Marcos Lilljedahl Date: Mon, 10 Jul 2017 17:42:04 -0300 Subject: [PATCH 11/18] No need to loop anymore as terminal is created after dialog opens now --- www/assets/app.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/www/assets/app.js b/www/assets/app.js index 2d17cc6..e7b1067 100644 --- a/www/assets/app.js +++ b/www/assets/app.js @@ -273,11 +273,6 @@ $scope.createBuilderTerminal = function() { var builderTerminalContainer = document.getElementById('builder-terminal'); - // For some reason the dialog DOM might not be ready, so we just keep trying - if (!builderTerminalContainer) { - setTimeout($scope.createBuilderTerminal, 100); - return; - } let term = new Terminal({ cursorBlink: false }); From b9f154c07cdc0222cd7dbfc7eaf28fb7ec9a9234 Mon Sep 17 00:00:00 2001 From: Marcos Lilljedahl Date: Mon, 10 Jul 2017 18:53:33 -0300 Subject: [PATCH 12/18] Unify file upload strategies --- handlers/file_upload.go | 28 +++++++++++----------------- pwd/instance.go | 35 ++++++++++++++--------------------- pwd/pwd.go | 5 ++--- pwd/session.go | 7 +++++-- www/assets/app.js | 2 +- 5 files changed, 33 insertions(+), 44 deletions(-) diff --git a/handlers/file_upload.go b/handlers/file_upload.go index 0420241..dda880b 100644 --- a/handlers/file_upload.go +++ b/handlers/file_upload.go @@ -4,6 +4,7 @@ import ( "io" "log" "net/http" + "path/filepath" "github.com/gorilla/mux" ) @@ -20,7 +21,10 @@ func FileUpload(rw http.ResponseWriter, req *http.Request) { // has a url query parameter, ignore body if url := req.URL.Query().Get("url"); url != "" { - err := core.InstanceUploadFromUrl(i, req.URL.Query().Get("url")) + + _, fileName := filepath.Split(url) + + err := core.InstanceUploadFromUrl(i, fileName, "", req.URL.Query().Get("url")) if err != nil { log.Println(err) rw.WriteHeader(http.StatusInternalServerError) @@ -35,7 +39,7 @@ func FileUpload(rw http.ResponseWriter, req *http.Request) { rw.WriteHeader(http.StatusBadRequest) return } - r := req.URL.Query().Get("relative") + path := req.URL.Query().Get("path") for { p, err := red.NextPart() @@ -50,21 +54,11 @@ func FileUpload(rw http.ResponseWriter, req *http.Request) { if p.FileName() == "" { continue } - - if r != "" { - err = core.InstanceUploadToCWDFromReader(i, p.FileName(), p) - if err != nil { - log.Println(err) - rw.WriteHeader(http.StatusInternalServerError) - return - } - } else { - err = core.InstanceUploadFromReader(i, p.FileName(), "/var/run/pwd/uploads", p) - if err != nil { - log.Println(err) - rw.WriteHeader(http.StatusInternalServerError) - return - } + err = core.InstanceUploadFromReader(i, p.FileName(), path, p) + if err != nil { + log.Println(err) + rw.WriteHeader(http.StatusInternalServerError) + return } log.Printf("Uploaded [%s] to [%s]\n", p.FileName(), i.Name) diff --git a/pwd/instance.go b/pwd/instance.go index c160628..4482728 100644 --- a/pwd/instance.go +++ b/pwd/instance.go @@ -60,7 +60,7 @@ func (p *pwd) InstanceAttachTerminal(instance *types.Instance) error { return nil } -func (p *pwd) InstanceUploadFromUrl(instance *types.Instance, url string) error { +func (p *pwd) InstanceUploadFromUrl(instance *types.Instance, fileName, dest string, url string) error { defer observeAction("InstanceUploadFromUrl", time.Now()) log.Printf("Downloading file [%s]\n", url) resp, err := http.Get(url) @@ -72,9 +72,7 @@ func (p *pwd) InstanceUploadFromUrl(instance *types.Instance, url string) error return fmt.Errorf("Could not download file [%s]. Status code: %d\n", url, resp.StatusCode) } - _, fileName := filepath.Split(url) - - copyErr := p.docker.CopyToContainer(instance.Name, "/var/run/pwd/uploads", fileName, resp.Body) + copyErr := p.docker.CopyToContainer(instance.Name, dest, fileName, resp.Body) if copyErr != nil { return fmt.Errorf("Error while downloading file [%s]. Error: %s\n", url, copyErr) @@ -98,26 +96,21 @@ func (p *pwd) getInstanceCWD(instance *types.Instance) (string, error) { return cwd, nil } -func (p *pwd) InstanceUploadToCWDFromReader(instance *types.Instance, fileName string, reader io.Reader) error { - defer observeAction("InstanceUploadToCWDFromReader", time.Now()) - - var cwd string - var err error - if cwd, err = p.getInstanceCWD(instance); err != nil { - return err - } - - if err = p.InstanceUploadFromReader(instance, fileName, cwd, reader); err != nil { - return err - } - - return nil -} - func (p *pwd) InstanceUploadFromReader(instance *types.Instance, fileName, dest string, reader io.Reader) error { defer observeAction("InstanceUploadFromReader", time.Now()) - copyErr := p.docker.CopyToContainer(instance.Name, dest, fileName, reader) + var finalDest string + if filepath.IsAbs(dest) { + finalDest = dest + } else { + if cwd, err := p.getInstanceCWD(instance); err != nil { + return err + } else { + finalDest = fmt.Sprintf("%s/%s", cwd, dest) + } + } + + copyErr := p.docker.CopyToContainer(instance.Name, finalDest, fileName, reader) if copyErr != nil { return fmt.Errorf("Error while uploading file [%s]. Error: %s\n", fileName, copyErr) diff --git a/pwd/pwd.go b/pwd/pwd.go index 2aa1e7b..4c397fb 100644 --- a/pwd/pwd.go +++ b/pwd/pwd.go @@ -60,9 +60,8 @@ type PWDApi interface { InstanceNew(session *types.Session, conf InstanceConfig) (*types.Instance, error) InstanceResizeTerminal(instance *types.Instance, cols, rows uint) error InstanceAttachTerminal(instance *types.Instance) error - InstanceUploadFromUrl(instance *types.Instance, url string) error - InstanceUploadFromReader(instance *types.Instance, filename, dest string, reader io.Reader) error - InstanceUploadToCWDFromReader(instance *types.Instance, fileName string, reader io.Reader) error + InstanceUploadFromUrl(instance *types.Instance, fileName, dest, url string) error + InstanceUploadFromReader(instance *types.Instance, fileName, dest string, reader io.Reader) error InstanceGet(session *types.Session, name string) *types.Instance InstanceFindByIP(ip string) *types.Instance InstanceFindByAlias(sessionPrefix, alias string) *types.Instance diff --git a/pwd/session.go b/pwd/session.go index ad36812..18d5873 100644 --- a/pwd/session.go +++ b/pwd/session.go @@ -5,6 +5,7 @@ import ( "log" "math" "path" + "path/filepath" "strings" "sync" "time" @@ -152,13 +153,15 @@ func (p *pwd) SessionDeployStack(s *types.Session) error { log.Printf("Error creating instance for stack [%s]: %s\n", s.Stack, err) return err } - err = p.InstanceUploadFromUrl(i, s.Stack) + + _, fileName := filepath.Split(s.Stack) + err = p.InstanceUploadFromUrl(i, fileName, "", s.Stack) if err != nil { log.Printf("Error uploading stack file [%s]: %s\n", s.Stack, err) return err } - fileName := path.Base(s.Stack) + fileName = path.Base(s.Stack) file := fmt.Sprintf("/var/run/pwd/uploads/%s", fileName) cmd := fmt.Sprintf("docker swarm init --advertise-addr eth0 && docker-compose -f %s pull && docker stack deploy -c %s %s", file, file, s.StackName) diff --git a/www/assets/app.js b/www/assets/app.js index ef34dc8..8f67e77 100644 --- a/www/assets/app.js +++ b/www/assets/app.js @@ -35,7 +35,7 @@ $scope.uploadFiles = function (files) { if (files && files.length) { for (var i = 0; i < files.length; i++) { - Upload.upload({url: '/sessions/' + $scope.sessionId + '/instances/' + $scope.selectedInstance.name + '/uploads?relative=true', data: {file: files[i]}, method: 'POST'}); + Upload.upload({url: '/sessions/' + $scope.sessionId + '/instances/' + $scope.selectedInstance.name + '/uploads', data: {file: files[i]}, method: 'POST'}); } } } From 3e38804393263dab67fca880f1917cff00a31086 Mon Sep 17 00:00:00 2001 From: Marcos Lilljedahl Date: Mon, 10 Jul 2017 18:59:38 -0300 Subject: [PATCH 13/18] Fix path for stack files --- pwd/session.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pwd/session.go b/pwd/session.go index 18d5873..fedf2f1 100644 --- a/pwd/session.go +++ b/pwd/session.go @@ -155,7 +155,7 @@ func (p *pwd) SessionDeployStack(s *types.Session) error { } _, fileName := filepath.Split(s.Stack) - err = p.InstanceUploadFromUrl(i, fileName, "", s.Stack) + err = p.InstanceUploadFromUrl(i, fileName, "/var/run/pwd/uploads", s.Stack) if err != nil { log.Printf("Error uploading stack file [%s]: %s\n", s.Stack, err) return err From 32bbe01c87a0ef591da3c23c0cf135bb6ccafeb4 Mon Sep 17 00:00:00 2001 From: Marcos Lilljedahl Date: Wed, 12 Jul 2017 15:18:07 -0300 Subject: [PATCH 14/18] Add progress bar --- www/assets/app.js | 6 +++++- www/index.html | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/www/assets/app.js b/www/assets/app.js index d8fc98f..c1e4a02 100644 --- a/www/assets/app.js +++ b/www/assets/app.js @@ -31,11 +31,15 @@ $scope.newInstanceBtnText = '+ Add new instance'; $scope.deleteInstanceBtnText = 'Delete'; $scope.isInstanceBeingDeleted = false; + $scope.uploadProgress = 0; $scope.uploadFiles = function (files) { if (files && files.length) { for (var i = 0; i < files.length; i++) { - Upload.upload({url: '/sessions/' + $scope.sessionId + '/instances/' + $scope.selectedInstance.name + '/uploads', data: {file: files[i]}, method: 'POST'}); + Upload.upload({url: '/sessions/' + $scope.sessionId + '/instances/' + $scope.selectedInstance.name + '/uploads', data: {file: files[i]}, method: 'POST'}) + .then(function(){}, function(){}, function(evt) { + $scope.uploadProgress = parseInt(100.0 * evt.loaded / evt.total); + }); } } } diff --git a/www/index.html b/www/index.html index 0b926ed..aea1a6e 100644 --- a/www/index.html +++ b/www/index.html @@ -106,6 +106,7 @@ {{deleteInstanceBtnText}} + From 377880080f84fa574880257e52806e00aea0848a Mon Sep 17 00:00:00 2001 From: Marcos Lilljedahl Date: Wed, 12 Jul 2017 15:53:31 -0300 Subject: [PATCH 15/18] Remove unnecessary dockerfile --- Dockerfile.run | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 Dockerfile.run diff --git a/Dockerfile.run b/Dockerfile.run deleted file mode 100644 index bc5db60..0000000 --- a/Dockerfile.run +++ /dev/null @@ -1,12 +0,0 @@ -FROM alpine - -RUN apk --update add ca-certificates -RUN mkdir -p /app/pwd - -ADD play-with-docker /app/play-with-docker -COPY ./www /app/www - -WORKDIR /app -CMD ["./play-with-docker"] - -EXPOSE 3000 From 3be03b1b85d8849c030e1e2b951d8d96846d67aa Mon Sep 17 00:00:00 2001 From: Marcos Lilljedahl Date: Wed, 12 Jul 2017 19:15:09 -0300 Subject: [PATCH 16/18] Add MOBY_COMMIT to dockerfile --- Dockerfile.dind | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Dockerfile.dind b/Dockerfile.dind index 2251d9e..378fdfd 100644 --- a/Dockerfile.dind +++ b/Dockerfile.dind @@ -6,10 +6,12 @@ RUN apk add --no-cache git tmux py2-pip apache2-utils vim build-base gettext-dev ENV GOPATH /root/go ENV PATH $PATH:$GOPATH -# Download moby and linuxkit +# Use specific moby commit due to vendoring mismatch +ENV MOBY_COMMIT="a73c3d3667f32fd61febcd2e824aa0341a57bafd" RUN mkdir /root/go && apk add --no-cache go \ - && go get -u github.com/moby/tool/cmd/moby github.com/linuxkit/linuxkit/src/cmd/linuxkit \ + && go get -u -d github.com/moby/tool/cmd/moby && (cd $GOPATH/src/github.com/moby/tool/cmd/moby && git checkout $MOBY_COMMIT && go install) \ + && go get -u github.com/linuxkit/linuxkit/src/cmd/linuxkit \ && rm -rf /root/go/pkg && rm -rf /root/go/src && rm -rf /usr/lib/go # Compile and install httping From aaa55785ba797a3094b878e670c5d8ad0f96d906 Mon Sep 17 00:00:00 2001 From: Marcos Lilljedahl Date: Wed, 12 Jul 2017 19:16:37 -0300 Subject: [PATCH 17/18] Add QEMU for moby --- Dockerfile.dind | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.dind b/Dockerfile.dind index 378fdfd..4c58bc3 100644 --- a/Dockerfile.dind +++ b/Dockerfile.dind @@ -1,7 +1,7 @@ ARG VERSION=docker:17.06.0-ce-dind FROM ${VERSION} -RUN apk add --no-cache git tmux py2-pip apache2-utils vim build-base gettext-dev curl bash-completion bash util-linux jq openssh +RUN apk add --no-cache git tmux py2-pip apache2-utils vim build-base gettext-dev curl bash-completion bash util-linux jq openssh qemu-img qemu-system-x86_64 ENV GOPATH /root/go ENV PATH $PATH:$GOPATH From a6fdfcaa7defa4e85f5996e971cc47ca1138dce4 Mon Sep 17 00:00:00 2001 From: Marcos Lilljedahl Date: Thu, 13 Jul 2017 13:54:00 -0300 Subject: [PATCH 18/18] Upload files synchronously and add more description --- www/assets/app.js | 28 ++++++++++++++++++++-------- www/assets/style.css | 23 +++++++++++++++++++++++ www/index.html | 9 +++++++-- 3 files changed, 50 insertions(+), 10 deletions(-) diff --git a/www/assets/app.js b/www/assets/app.js index c1e4a02..c04d774 100644 --- a/www/assets/app.js +++ b/www/assets/app.js @@ -33,15 +33,27 @@ $scope.isInstanceBeingDeleted = false; $scope.uploadProgress = 0; - $scope.uploadFiles = function (files) { - if (files && files.length) { - for (var i = 0; i < files.length; i++) { - Upload.upload({url: '/sessions/' + $scope.sessionId + '/instances/' + $scope.selectedInstance.name + '/uploads', data: {file: files[i]}, method: 'POST'}) - .then(function(){}, function(){}, function(evt) { - $scope.uploadProgress = parseInt(100.0 * evt.loaded / evt.total); - }); - } + + $scope.uploadFiles = function (files, invalidFiles) { + let total = files.length; + let uploadFile = function() { + let file = files.shift(); + if (!file){ + $scope.uploadMessage = ""; + $scope.uploadProgress = 0; + return + } + $scope.uploadMessage = "Uploading file(s) " + (total - files.length) + "/"+ total + " : " + file.name; + let upload = Upload.upload({url: '/sessions/' + $scope.sessionId + '/instances/' + $scope.selectedInstance.name + '/uploads', data: {file: file}, method: 'POST'}) + .then(function(){}, function(){}, function(evt) { + $scope.uploadProgress = parseInt(100.0 * evt.loaded / evt.total); + }); + + // process next file + upload.finally(uploadFile); } + + uploadFile(); } var selectedKeyboardShortcuts = KeyboardShortcutService.getCurrentShortcuts(); diff --git a/www/assets/style.css b/www/assets/style.css index 9feb2d0..d676c89 100644 --- a/www/assets/style.css +++ b/www/assets/style.css @@ -35,6 +35,29 @@ md-card-content.terminal-container { margin-top: 50px; } +.uploadStatus .bottom-block { + display: block; + position: relative; + background-color: rgba(255, 235, 169, 0.25); + height: 30px; + width: 100%; +} + +.uploadStatus .bottom-block > span { + display: inline-block; + padding: 8px; + font-size: 0.9em; +} + +.uploadStatus { + display: block; + position: relative; + width: 100%; + border: 2px solid #aad1f9; + transition: opacity 0.1s linear; + border-top: 0px; +} + .disconnected { background-color: #FDF4B6; } diff --git a/www/index.html b/www/index.html index aea1a6e..d5efd57 100644 --- a/www/index.html +++ b/www/index.html @@ -72,7 +72,7 @@
- + @@ -106,8 +106,13 @@ {{deleteInstanceBtnText}} - +
+ +
+ {{uploadMessage}} +
+