diff --git a/go.mod b/go.mod index c7225d18..c2a9ccaf 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/cloudfoundry/node-engine-cnb require ( github.com/Masterminds/semver v1.5.0 github.com/buildpack/libbuildpack v1.24.5 - github.com/cloudfoundry/dagger v0.0.0-20191001184736-b0f1e98b53b2 + github.com/cloudfoundry/dagger v0.0.0-20191008210309-499f8aacb425 github.com/cloudfoundry/libcfbuildpack v1.89.0 github.com/onsi/gomega v1.7.0 github.com/sclevine/spec v1.3.0 diff --git a/go.sum b/go.sum index 5c26955b..d2644eb3 100644 --- a/go.sum +++ b/go.sum @@ -9,6 +9,8 @@ cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +code.cloudfoundry.org/lager v2.0.0+incompatible h1:WZwDKDB2PLd/oL+USK4b4aEjUymIej9My2nUQ9oWEwQ= +code.cloudfoundry.org/lager v2.0.0+incompatible/go.mod h1:O2sS7gKP3HM2iemG+EnwvyNQK7pTSC6Foi4QiMp9sSk= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -16,17 +18,26 @@ github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITg github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/buildpack/libbuildpack v1.19.0 h1:HUkaIwuGmPbQhujBjYNpd+E4f0NdAgAgHq7skydiL5s= github.com/buildpack/libbuildpack v1.19.0/go.mod h1:oxgSTzPbWscHs27iuYrctEZpSak2m/qPThA+9JM0Boo= +github.com/buildpack/libbuildpack v1.24.3/go.mod h1:16+PwmWtgcwzIVcCzwxwc9yi1g/NwqF+ji9IU0deBpg= github.com/buildpack/libbuildpack v1.24.5 h1:r7AM7r8ff7ocI1KOopVHEC3EDTCdrj0YeTXkfYuqH0I= github.com/buildpack/libbuildpack v1.24.5/go.mod h1:cBmq8aozSDfy+RiKCERQbT6lk0M/Xf3aJWK2PLbPG1g= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudfoundry/dagger v0.0.0-20191001184736-b0f1e98b53b2 h1:5HDZgNugnr9WeZpkYSD1W/jbScbTTNXHOoNFUgk2XSI= -github.com/cloudfoundry/dagger v0.0.0-20191001184736-b0f1e98b53b2/go.mod h1:vbeid+MuoJPZXM8fGvJy87lDLvu/q0Rs1NN4M6lFFg4= +github.com/cloudfoundry/dagger v0.0.0-20191008210309-499f8aacb425 h1:ChFf80cNIvOj+TT4ChEMehaluzFEcsXev9LMFxZIcOQ= +github.com/cloudfoundry/dagger v0.0.0-20191008210309-499f8aacb425/go.mod h1:5SsFi1j50yJ8GEcvyX/Ftg+FsT4HX0dw9VjH3nDCb/o= +github.com/cloudfoundry/libbuildpack v0.0.0-20191007182113-c10f57166e5b h1:W/ieO8SAZfeRlxpla9WF4INqBCWXTELoa12+akON6mI= +github.com/cloudfoundry/libbuildpack v0.0.0-20191007182113-c10f57166e5b/go.mod h1:F89xsc6s04sSmwubA99WA9m5uvcLBFeNln17bT8xap0= github.com/cloudfoundry/libcfbuildpack v1.76.0 h1:oMTv35mjk5Jogzy2sshVXHyolDWnWHMfANQ0UooXJq0= github.com/cloudfoundry/libcfbuildpack v1.76.0/go.mod h1:QGm+nzixn579dvQNlS7ZQET541y2hEpZ0/5uNxkQ04Y= github.com/cloudfoundry/libcfbuildpack v1.89.0 h1:A0OXihcHjvDRLYendhfqMxTBVe5pi5fmM5t4sqNRpao= github.com/cloudfoundry/libcfbuildpack v1.89.0/go.mod h1:ufhp/bp0LxbDDwbf2Ms3Bf4x9YnLr9dkL1RTUYSdKg0= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= +github.com/elazarl/goproxy/ext v0.0.0-20190911111923-ecfe977594f1/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= @@ -53,12 +64,14 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jarcoal/httpmock v1.0.4/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -90,11 +103,18 @@ github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sclevine/spec v1.2.0 h1:1Jwdf9jSfDl9NVmt8ndHqbTZ7XCCPbh1jI3hkDBHVYA= github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= github.com/sclevine/spec v1.3.0 h1:iTB51CYlnju5oRh0/l67fg1+RlQ2nqmFecwdvN+5TrI= github.com/sclevine/spec v1.3.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/tidwall/gjson v1.3.2/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= +github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -130,8 +150,7 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190916140828-c8589233b77d/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 h1:6KET3Sqa7fkVfD63QnAM81ZeYg5n4HwApOJkufONnHA= golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191003171128-d98b1b443823 h1:Ypyv6BNJh07T1pUSrehkLemqPKXhus2MkfktJ91kRh4= @@ -161,6 +180,7 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916165910-8a69140bde95/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24 h1:R8bzl0244nw47n1xKs1MUMAaTNgjavKcN/aX2Ss3+Fo= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191003212358-c178f38b412c h1:6Zx7DRlKXf79yfxuQ/7GqV3w2y7aDsk6bGg0MzF5RVU= diff --git a/vendor/code.cloudfoundry.org/lager/LICENSE b/vendor/code.cloudfoundry.org/lager/LICENSE new file mode 100644 index 00000000..f49a4e16 --- /dev/null +++ b/vendor/code.cloudfoundry.org/lager/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/vendor/code.cloudfoundry.org/lager/NOTICE b/vendor/code.cloudfoundry.org/lager/NOTICE new file mode 100644 index 00000000..3c8dd5b6 --- /dev/null +++ b/vendor/code.cloudfoundry.org/lager/NOTICE @@ -0,0 +1,20 @@ +Copyright (c) 2015-Present CloudFoundry.org Foundation, Inc. All Rights Reserved. + +This project contains software that is Copyright (c) 2014-2015 Pivotal Software, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +This project may include a number of subcomponents with separate +copyright notices and license terms. Your use of these subcomponents +is subject to the terms and conditions of each subcomponent's license, +as noted in the LICENSE file. diff --git a/vendor/code.cloudfoundry.org/lager/README.md b/vendor/code.cloudfoundry.org/lager/README.md new file mode 100644 index 00000000..c9f28cc6 --- /dev/null +++ b/vendor/code.cloudfoundry.org/lager/README.md @@ -0,0 +1,78 @@ +lager +===== + +**Note**: This repository should be imported as `code.cloudfoundry.org/lager`. + +Lager is a logging library for go. + +## Usage + +Instantiate a logger with the name of your component. + +```go +import ( + "code.cloudfoundry.org/lager" +) + +logger := lager.NewLogger("my-app") +``` + +### Sinks + +Lager can write logs to a variety of destinations. You can specify the destinations +using Lager sinks: + +To write to an arbitrary `Writer` object: + +```go +logger.RegisterSink(lager.NewWriterSink(myWriter, lager.INFO)) +``` + +### Emitting logs + +Lager supports the usual level-based logging, with an optional argument for arbitrary key-value data. + +```go +logger.Info("doing-stuff", lager.Data{ + "informative": true, +}) +``` + +output: +```json +{ "source": "my-app", "message": "doing-stuff", "data": { "informative": true }, "timestamp": 1232345, "log_level": 1 } +``` + +Error messages also take an `Error` object: + +```go +logger.Error("failed-to-do-stuff", errors.New("Something went wrong")) +``` + +output: +```json +{ "source": "my-app", "message": "failed-to-do-stuff", "data": { "error": "Something went wrong" }, "timestamp": 1232345, "log_level": 1 } +``` + +### Sessions + +You can avoid repetition of contextual data using 'Sessions': + +```go + +contextualLogger := logger.Session("my-task", lager.Data{ + "request-id": 5, +}) + +contextualLogger.Info("my-action") +``` + +output: + +```json +{ "source": "my-app", "message": "my-task.my-action", "data": { "request-id": 5 }, "timestamp": 1232345, "log_level": 1 } +``` + +## License + +Lager is [Apache 2.0](https://github.com/cloudfoundry/lager/blob/master/LICENSE) licensed. diff --git a/vendor/code.cloudfoundry.org/lager/json_redacter.go b/vendor/code.cloudfoundry.org/lager/json_redacter.go new file mode 100644 index 00000000..12263c64 --- /dev/null +++ b/vendor/code.cloudfoundry.org/lager/json_redacter.go @@ -0,0 +1,111 @@ +package lager + +import ( + "encoding/json" + "regexp" +) + +const awsAccessKeyIDPattern = `AKIA[A-Z0-9]{16}` +const awsSecretAccessKeyPattern = `KEY["']?\s*(?::|=>|=)\s*["']?[A-Z0-9/\+=]{40}["']?` +const cryptMD5Pattern = `\$1\$[A-Z0-9./]{1,16}\$[A-Z0-9./]{22}` +const cryptSHA256Pattern = `\$5\$[A-Z0-9./]{1,16}\$[A-Z0-9./]{43}` +const cryptSHA512Pattern = `\$6\$[A-Z0-9./]{1,16}\$[A-Z0-9./]{86}` +const privateKeyHeaderPattern = `-----BEGIN(.*)PRIVATE KEY-----` + +type JSONRedacter struct { + keyMatchers []*regexp.Regexp + valueMatchers []*regexp.Regexp +} + +func NewJSONRedacter(keyPatterns []string, valuePatterns []string) (*JSONRedacter, error) { + if keyPatterns == nil { + keyPatterns = []string{"[Pp]wd", "[Pp]ass"} + } + if valuePatterns == nil { + valuePatterns = []string{awsAccessKeyIDPattern, awsSecretAccessKeyPattern, cryptMD5Pattern, cryptSHA256Pattern, cryptSHA512Pattern, privateKeyHeaderPattern} + } + ret := &JSONRedacter{} + for _, v := range keyPatterns { + r, err := regexp.Compile(v) + if err != nil { + return nil, err + } + ret.keyMatchers = append(ret.keyMatchers, r) + } + for _, v := range valuePatterns { + r, err := regexp.Compile(v) + if err != nil { + return nil, err + } + ret.valueMatchers = append(ret.valueMatchers, r) + } + return ret, nil +} + +func (r JSONRedacter) Redact(data []byte) []byte { + var jsonBlob interface{} + err := json.Unmarshal(data, &jsonBlob) + if err != nil { + return handleError(err) + } + r.redactValue(&jsonBlob) + + data, err = json.Marshal(jsonBlob) + if err != nil { + return handleError(err) + } + + return data +} + +func (r JSONRedacter) redactValue(data *interface{}) interface{} { + if data == nil { + return data + } + + if a, ok := (*data).([]interface{}); ok { + r.redactArray(&a) + } else if m, ok := (*data).(map[string]interface{}); ok { + r.redactObject(&m) + } else if s, ok := (*data).(string); ok { + for _, m := range r.valueMatchers { + if m.MatchString(s) { + (*data) = "*REDACTED*" + break + } + } + } + return (*data) +} + +func (r JSONRedacter) redactArray(data *[]interface{}) { + for i, _ := range *data { + r.redactValue(&((*data)[i])) + } +} + +func (r JSONRedacter) redactObject(data *map[string]interface{}) { + for k, v := range *data { + for _, m := range r.keyMatchers { + if m.MatchString(k) { + (*data)[k] = "*REDACTED*" + break + } + } + if (*data)[k] != "*REDACTED*" { + (*data)[k] = r.redactValue(&v) + } + } +} + +func handleError(err error) []byte { + var content []byte + if _, ok := err.(*json.UnsupportedTypeError); ok { + data := map[string]interface{}{"lager serialisation error": err.Error()} + content, err = json.Marshal(data) + } + if err != nil { + panic(err) + } + return content +} diff --git a/vendor/code.cloudfoundry.org/lager/logger.go b/vendor/code.cloudfoundry.org/lager/logger.go new file mode 100644 index 00000000..6167220f --- /dev/null +++ b/vendor/code.cloudfoundry.org/lager/logger.go @@ -0,0 +1,189 @@ +package lager + +import ( + "fmt" + "runtime" + "sync/atomic" + "time" +) + +const StackTraceBufferSize = 1024 * 100 + +type Logger interface { + RegisterSink(Sink) + Session(task string, data ...Data) Logger + SessionName() string + Debug(action string, data ...Data) + Info(action string, data ...Data) + Error(action string, err error, data ...Data) + Fatal(action string, err error, data ...Data) + WithData(Data) Logger +} + +type logger struct { + component string + task string + sinks []Sink + sessionID string + nextSession uint32 + data Data +} + +func NewLogger(component string) Logger { + return &logger{ + component: component, + task: component, + sinks: []Sink{}, + data: Data{}, + } +} + +func (l *logger) RegisterSink(sink Sink) { + l.sinks = append(l.sinks, sink) +} + +func (l *logger) SessionName() string { + return l.task +} + +func (l *logger) Session(task string, data ...Data) Logger { + sid := atomic.AddUint32(&l.nextSession, 1) + + var sessionIDstr string + + if l.sessionID != "" { + sessionIDstr = fmt.Sprintf("%s.%d", l.sessionID, sid) + } else { + sessionIDstr = fmt.Sprintf("%d", sid) + } + + return &logger{ + component: l.component, + task: fmt.Sprintf("%s.%s", l.task, task), + sinks: l.sinks, + sessionID: sessionIDstr, + data: l.baseData(data...), + } +} + +func (l *logger) WithData(data Data) Logger { + return &logger{ + component: l.component, + task: l.task, + sinks: l.sinks, + sessionID: l.sessionID, + data: l.baseData(data), + } +} + +func (l *logger) Debug(action string, data ...Data) { + t := time.Now().UTC() + log := LogFormat{ + time: t, + Timestamp: formatTimestamp(t), + Source: l.component, + Message: fmt.Sprintf("%s.%s", l.task, action), + LogLevel: DEBUG, + Data: l.baseData(data...), + } + + for _, sink := range l.sinks { + sink.Log(log) + } +} + +func (l *logger) Info(action string, data ...Data) { + t := time.Now().UTC() + log := LogFormat{ + time: t, + Timestamp: formatTimestamp(t), + Source: l.component, + Message: fmt.Sprintf("%s.%s", l.task, action), + LogLevel: INFO, + Data: l.baseData(data...), + } + + for _, sink := range l.sinks { + sink.Log(log) + } +} + +func (l *logger) Error(action string, err error, data ...Data) { + logData := l.baseData(data...) + + if err != nil { + logData["error"] = err.Error() + } + + t := time.Now().UTC() + log := LogFormat{ + time: t, + Timestamp: formatTimestamp(t), + Source: l.component, + Message: fmt.Sprintf("%s.%s", l.task, action), + LogLevel: ERROR, + Data: logData, + Error: err, + } + + for _, sink := range l.sinks { + sink.Log(log) + } +} + +func (l *logger) Fatal(action string, err error, data ...Data) { + logData := l.baseData(data...) + + stackTrace := make([]byte, StackTraceBufferSize) + stackSize := runtime.Stack(stackTrace, false) + stackTrace = stackTrace[:stackSize] + + if err != nil { + logData["error"] = err.Error() + } + + logData["trace"] = string(stackTrace) + + t := time.Now().UTC() + log := LogFormat{ + time: t, + Timestamp: formatTimestamp(t), + Source: l.component, + Message: fmt.Sprintf("%s.%s", l.task, action), + LogLevel: FATAL, + Data: logData, + Error: err, + } + + for _, sink := range l.sinks { + sink.Log(log) + } + + panic(err) +} + +func (l *logger) baseData(givenData ...Data) Data { + data := Data{} + + for k, v := range l.data { + data[k] = v + } + + if len(givenData) > 0 { + for _, dataArg := range givenData { + for key, val := range dataArg { + data[key] = val + } + } + } + + if l.sessionID != "" { + data["session"] = l.sessionID + } + + return data +} + +func formatTimestamp(t time.Time) string { + return fmt.Sprintf("%.9f", float64(t.UnixNano())/1e9) +} diff --git a/vendor/code.cloudfoundry.org/lager/models.go b/vendor/code.cloudfoundry.org/lager/models.go new file mode 100644 index 00000000..6571a4b0 --- /dev/null +++ b/vendor/code.cloudfoundry.org/lager/models.go @@ -0,0 +1,146 @@ +package lager + +import ( + "encoding/json" + "fmt" + "strconv" + "strings" + "time" +) + +type LogLevel int + +const ( + DEBUG LogLevel = iota + INFO + ERROR + FATAL +) + +var logLevelStr = [...]string{ + DEBUG: "debug", + INFO: "info", + ERROR: "error", + FATAL: "fatal", +} + +func (l LogLevel) String() string { + if DEBUG <= l && l <= FATAL { + return logLevelStr[l] + } + return "invalid" +} + +func LogLevelFromString(s string) (LogLevel, error) { + for k, v := range logLevelStr { + if v == s { + return LogLevel(k), nil + } + } + return -1, fmt.Errorf("invalid log level: %s", s) +} + +type Data map[string]interface{} + +type rfc3339Time time.Time + +const rfc3339Nano = "2006-01-02T15:04:05.000000000Z07:00" + +func (t rfc3339Time) MarshalJSON() ([]byte, error) { + stamp := fmt.Sprintf(`"%s"`, time.Time(t).UTC().Format(rfc3339Nano)) + return []byte(stamp), nil +} + +func (t *rfc3339Time) UnmarshalJSON(data []byte) error { + return (*time.Time)(t).UnmarshalJSON(data) +} + +type LogFormat struct { + Timestamp string `json:"timestamp"` + Source string `json:"source"` + Message string `json:"message"` + LogLevel LogLevel `json:"log_level"` + Data Data `json:"data"` + Error error `json:"-"` + time time.Time +} + +func (log LogFormat) ToJSON() []byte { + content, err := json.Marshal(log) + if err != nil { + log.Data = dataForJSONMarhallingError(err, log.Data) + content, err = json.Marshal(log) + if err != nil { + panic(err) + } + } + return content +} + +func (log LogFormat) toPrettyJSON() []byte { + t := log.time + if t.IsZero() { + t = parseTimestamp(log.Timestamp) + } + + prettyLog := struct { + Timestamp rfc3339Time `json:"timestamp"` + Level string `json:"level"` + Source string `json:"source"` + Message string `json:"message"` + Data Data `json:"data"` + Error error `json:"-"` + }{ + Timestamp: rfc3339Time(t), + Level: log.LogLevel.String(), + Source: log.Source, + Message: log.Message, + Data: log.Data, + Error: log.Error, + } + + content, err := json.Marshal(prettyLog) + + if err != nil { + prettyLog.Data = dataForJSONMarhallingError(err, prettyLog.Data) + content, err = json.Marshal(prettyLog) + if err != nil { + panic(err) + } + } + + return content +} + +func dataForJSONMarhallingError(err error, data Data) Data { + _, ok1 := err.(*json.UnsupportedTypeError) + _, ok2 := err.(*json.MarshalerError) + errKey := "unknown_error" + if ok1 || ok2 { + errKey = "lager serialisation error" + } + + return map[string]interface{}{ + errKey: err.Error(), + "data_dump": fmt.Sprintf("%#v", data), + } +} + +func parseTimestamp(s string) time.Time { + if s == "" { + return time.Now() + } + n := strings.IndexByte(s, '.') + if n <= 0 || n == len(s)-1 { + return time.Now() + } + sec, err := strconv.ParseInt(s[:n], 10, 64) + if err != nil || sec < 0 { + return time.Now() + } + nsec, err := strconv.ParseInt(s[n+1:], 10, 64) + if err != nil || nsec < 0 { + return time.Now() + } + return time.Unix(sec, nsec) +} diff --git a/vendor/code.cloudfoundry.org/lager/package.go b/vendor/code.cloudfoundry.org/lager/package.go new file mode 100644 index 00000000..7e8b063d --- /dev/null +++ b/vendor/code.cloudfoundry.org/lager/package.go @@ -0,0 +1 @@ +package lager // import "code.cloudfoundry.org/lager" diff --git a/vendor/code.cloudfoundry.org/lager/reconfigurable_sink.go b/vendor/code.cloudfoundry.org/lager/reconfigurable_sink.go new file mode 100644 index 00000000..7c3b228e --- /dev/null +++ b/vendor/code.cloudfoundry.org/lager/reconfigurable_sink.go @@ -0,0 +1,35 @@ +package lager + +import "sync/atomic" + +type ReconfigurableSink struct { + sink Sink + + minLogLevel int32 +} + +func NewReconfigurableSink(sink Sink, initialMinLogLevel LogLevel) *ReconfigurableSink { + return &ReconfigurableSink{ + sink: sink, + + minLogLevel: int32(initialMinLogLevel), + } +} + +func (sink *ReconfigurableSink) Log(log LogFormat) { + minLogLevel := LogLevel(atomic.LoadInt32(&sink.minLogLevel)) + + if log.LogLevel < minLogLevel { + return + } + + sink.sink.Log(log) +} + +func (sink *ReconfigurableSink) SetMinLevel(level LogLevel) { + atomic.StoreInt32(&sink.minLogLevel, int32(level)) +} + +func (sink *ReconfigurableSink) GetMinLevel() LogLevel { + return LogLevel(atomic.LoadInt32(&sink.minLogLevel)) +} diff --git a/vendor/code.cloudfoundry.org/lager/redacting_sink.go b/vendor/code.cloudfoundry.org/lager/redacting_sink.go new file mode 100644 index 00000000..17a30295 --- /dev/null +++ b/vendor/code.cloudfoundry.org/lager/redacting_sink.go @@ -0,0 +1,62 @@ +package lager + +import ( + "encoding/json" +) + +type redactingSink struct { + sink Sink + jsonRedacter *JSONRedacter +} + +// NewRedactingSink creates a sink that redacts sensitive information from the +// data field. The old behavior of NewRedactingWriterSink (which was removed +// in v2) can be obtained using the following code: +// +// redactingSink, err := NewRedactingSink( +// NewWriterSink(writer, minLogLevel), +// keyPatterns, +// valuePatterns, +// ) +// +// if err != nil { +// return nil, err +// } +// +// return NewReconfigurableSink( +// redactingSink, +// minLogLevel, +// ), nil +// +func NewRedactingSink(sink Sink, keyPatterns []string, valuePatterns []string) (Sink, error) { + jsonRedacter, err := NewJSONRedacter(keyPatterns, valuePatterns) + if err != nil { + return nil, err + } + + return &redactingSink{ + sink: sink, + jsonRedacter: jsonRedacter, + }, nil +} + +func (sink *redactingSink) Log(log LogFormat) { + rawJSON, err := json.Marshal(log.Data) + if err != nil { + log.Data = dataForJSONMarhallingError(err, log.Data) + + rawJSON, err = json.Marshal(log.Data) + if err != nil { + panic(err) + } + } + + redactedJSON := sink.jsonRedacter.Redact(rawJSON) + + err = json.Unmarshal(redactedJSON, &log.Data) + if err != nil { + panic(err) + } + + sink.sink.Log(log) +} diff --git a/vendor/code.cloudfoundry.org/lager/writer_sink.go b/vendor/code.cloudfoundry.org/lager/writer_sink.go new file mode 100644 index 00000000..bb77d708 --- /dev/null +++ b/vendor/code.cloudfoundry.org/lager/writer_sink.go @@ -0,0 +1,62 @@ +package lager + +import ( + "io" + "sync" +) + +// A Sink represents a write destination for a Logger. It provides +// a thread-safe interface for writing logs +type Sink interface { + //Log to the sink. Best effort -- no need to worry about errors. + Log(LogFormat) +} + +type writerSink struct { + writer io.Writer + minLogLevel LogLevel + writeL *sync.Mutex +} + +func NewWriterSink(writer io.Writer, minLogLevel LogLevel) Sink { + return &writerSink{ + writer: writer, + minLogLevel: minLogLevel, + writeL: new(sync.Mutex), + } +} + +func (sink *writerSink) Log(log LogFormat) { + if log.LogLevel < sink.minLogLevel { + return + } + + sink.writeL.Lock() + sink.writer.Write(log.ToJSON()) + sink.writer.Write([]byte("\n")) + sink.writeL.Unlock() +} + +type prettySink struct { + writer io.Writer + minLogLevel LogLevel + writeL sync.Mutex +} + +func NewPrettySink(writer io.Writer, minLogLevel LogLevel) Sink { + return &prettySink{ + writer: writer, + minLogLevel: minLogLevel, + } +} + +func (sink *prettySink) Log(log LogFormat) { + if log.LogLevel < sink.minLogLevel { + return + } + + sink.writeL.Lock() + sink.writer.Write(log.toPrettyJSON()) + sink.writer.Write([]byte("\n")) + sink.writeL.Unlock() +} diff --git a/vendor/github.com/cloudfoundry/dagger/app.go b/vendor/github.com/cloudfoundry/dagger/app.go index 9cdf30f9..4ddbc2df 100644 --- a/vendor/github.com/cloudfoundry/dagger/app.go +++ b/vendor/github.com/cloudfoundry/dagger/app.go @@ -2,10 +2,11 @@ package dagger import ( "bytes" + "code.cloudfoundry.org/lager" "fmt" + "github.com/cloudfoundry/libbuildpack/cutlass/docker" "io/ioutil" "net/http" - "os" "os/exec" "regexp" "strings" @@ -33,13 +34,21 @@ type HealthCheck struct { timeout string } +func NewApp(fixturePath, imageName, cacheImage string, buildLogs *bytes.Buffer, env map[string]string) App { + return App{ + ImageName: imageName, + CacheImage: cacheImage, + buildLogs: buildLogs, + Env: env, + fixtureName: fixturePath, + } +} + func (a *App) Start() error { return a.StartWithCommand("") } func (a *App) StartWithCommand(startCmd string) error { - buf := &bytes.Buffer{} - if a.Env["PORT"] == "" { a.Env["PORT"] = "8080" } @@ -73,13 +82,14 @@ func (a *App) StartWithCommand(startCmd string) error { args = append(args, startCmd) } - cmd := exec.Command("docker", args...) - cmd.Stdout = buf - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { + dockerLogger := lager.NewLogger("docker") + log, _, err := docker.NewDockerExecutable(dockerLogger).Execute(docker.ExecuteOptions{}, args...) + + if err != nil { return errors.Wrap(err, fmt.Sprintf("failed to run docker image: %s\n with command: %s", a.ImageName, args)) } - a.ContainerID = buf.String()[:12] + + a.ContainerID = log[:12] ticker := time.NewTicker(1 * time.Second) timeOut := time.After(2 * time.Minute) @@ -112,38 +122,40 @@ docker: } } - cmd = exec.Command("docker", "container", "port", a.ContainerID) - cmd.Stdout = buf - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { + log, _, err = docker.NewDockerExecutable(dockerLogger).Execute(docker.ExecuteOptions{}, "container", "port", a.ContainerID) + if err != nil { return errors.Wrap(err, fmt.Sprintf("docker error: failed to get port from container: %s", a.ContainerID)) } - ports := strings.Split(buf.String(), ":") + ports := strings.Split(log, ":") if len(ports) > 1 { a.port = strings.TrimSpace(ports[1]) } else { - return fmt.Errorf("unable to get well formed port map from docker") + return fmt.Errorf("unable to get port map from docker") } return nil } func (a *App) Destroy() error { + dockerLogger := lager.NewLogger("docker") + dockerExec := docker.NewDockerExecutable(dockerLogger) + execOption := docker.ExecuteOptions{} + cntrExists, err := DockerArtifactExists(a.ContainerID) if err != nil { return fmt.Errorf("failed to find container %s: %s", a.ContainerID, err) } if cntrExists { - cmd := exec.Command("docker", "stop", a.ContainerID) - if err := cmd.Run(); err != nil { + _, _, err := dockerExec.Execute(execOption, "stop", a.ContainerID) + if err != nil { return fmt.Errorf("failed to stop container %s: %s", a.ContainerID, err) } - cmd = exec.Command("docker", "rm", a.ContainerID, "-f", "--volumes") - if err := cmd.Run(); err != nil { + _, _, err = dockerExec.Execute(execOption, "rm", a.ContainerID, "-f", "--volumes") + if err != nil { return fmt.Errorf("failed to remove container %s: %s", a.ContainerID, err) } } @@ -154,8 +166,8 @@ func (a *App) Destroy() error { } if imgExists { - cmd := exec.Command("docker", "rmi", a.ImageName, "-f") - if err := cmd.Run(); err != nil { + _, _, err = dockerExec.Execute(execOption, "rmi", a.ImageName, "-f") + if err != nil { return fmt.Errorf("failed to remove image %s: %s", a.ImageName, err) } } @@ -166,8 +178,8 @@ func (a *App) Destroy() error { } if cacheExists { - cmd := exec.Command("docker", "rmi", a.CacheImage, "-f") - if err := cmd.Run(); err != nil { + _, _, err = dockerExec.Execute(execOption, "rmi", a.CacheImage, "-f") + if err != nil { return fmt.Errorf("failed to remove cache image %s: %s", a.CacheImage, err) } } @@ -178,8 +190,8 @@ func (a *App) Destroy() error { } if cacheBuildVolumeExists { - cmd := exec.Command("docker", "volume", "rm", fmt.Sprintf("%s.build", a.CacheImage)) - if err := cmd.Run(); err != nil { + _, _, err = dockerExec.Execute(execOption, "volume", "rm", fmt.Sprintf("%s.build", a.CacheImage)) + if err != nil { return fmt.Errorf("failed to remove cache build volume %s.build: %s", a.CacheImage, err) } } @@ -190,14 +202,14 @@ func (a *App) Destroy() error { } if cacheLaunchVolumeExists { - cmd := exec.Command("docker", "volume", "rm", fmt.Sprintf("%s.launch", a.CacheImage)) - if err := cmd.Run(); err != nil { + _, _, err = dockerExec.Execute(execOption, "volume", "rm", fmt.Sprintf("%s.launch", a.CacheImage)) + if err != nil { return fmt.Errorf("failed to remove cache launch volume %s.launch: %s", a.CacheImage, err) } } - cmd := exec.Command("docker", "image", "prune", "-f") - if err := cmd.Run(); err != nil { + _, _, err = dockerExec.Execute(execOption, "image", "prune", "-f") + if err != nil { return fmt.Errorf("failed to prune images: %s", err) } @@ -206,13 +218,13 @@ func (a *App) Destroy() error { } func (a *App) Logs() (string, error) { - cmd := exec.Command("docker", "logs", a.ContainerID) - output, err := cmd.CombinedOutput() + dockerLogger := lager.NewLogger("docker") + log, _, err := docker.NewDockerExecutable(dockerLogger).Execute(docker.ExecuteOptions{}, "logs", a.ContainerID) if err != nil { return "", err } - return stripColor(string(output)), nil + return stripColor(log), nil } func (a *App) BuildLogs() string { @@ -229,13 +241,21 @@ func (a *App) SetHealthCheck(command, interval, timeout string) { func (a *App) Files(path string) ([]string, error) { // Ensures that the error and results from "Permission denied" don't get sent to the output - line := fmt.Sprintf("docker run %s find ./.. -wholename *%s* 2>&1 | grep -v \"Permission denied\"", a.ImageName, path) - cmd := exec.Command("bash", "-c", line) - output, err := cmd.CombinedOutput() + dockerLogger := lager.NewLogger("docker") + log, _, err := docker.NewDockerExecutable(dockerLogger).Execute( + docker.ExecuteOptions{}, + "run", + a.ImageName, + "find", + "./..", + fmt.Sprintf("-wholename *%s* 2>&1 | grep -v \"Permission denied\"", path), + ) + if err != nil { return []string{}, err } - return strings.Split(string(output), "\n"), nil + + return strings.Split(log, "\n"), nil } func (a *App) Info() (cID string, imageID string, cacheID []string, e error) { @@ -280,13 +300,18 @@ func stripColor(input string) string { } func getCacheVolumes() ([]string, error) { - cmd := exec.Command("docker", "volume", "ls", "-q") - output, err := cmd.Output() + dockerLogger := lager.NewLogger("docker") + log, _, err := docker.NewDockerExecutable(dockerLogger).Execute( + docker.ExecuteOptions{}, + "volume", + "ls", + "-q", + ) if err != nil { return []string{}, err } - outputArr := strings.Split(string(output), "\n") + outputArr := strings.Split(log, "\n") var finalVolumes []string for _, line := range outputArr { if strings.Contains(line, "pack-cache") { @@ -297,10 +322,14 @@ func getCacheVolumes() ([]string, error) { } func DockerArtifactExists(name string) (bool, error) { - cmd := exec.Command("docker", "inspect", name) - output, err := cmd.CombinedOutput() + dockerLogger := lager.NewLogger("docker") + log, _, err := docker.NewDockerExecutable(dockerLogger).Execute( + docker.ExecuteOptions{}, + "inspect", + name, + ) if err != nil { - if strings.Contains(string(output), "No such object") { + if strings.Contains(log, "No such object") { return false, nil } diff --git a/vendor/github.com/cloudfoundry/dagger/buildpack.go b/vendor/github.com/cloudfoundry/dagger/buildpack.go index 999df68f..5adeb0a6 100644 --- a/vendor/github.com/cloudfoundry/dagger/buildpack.go +++ b/vendor/github.com/cloudfoundry/dagger/buildpack.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "github.com/cloudfoundry/dagger/utils" "io" "io/ioutil" "math/rand" @@ -62,7 +63,7 @@ func PackageBuildpack(root string) (string, error) { return "", err } - bpName := fmt.Sprintf("%s_%s", filepath.Base(path), RandStringRunes(8)) + bpName := fmt.Sprintf("%s_%s", filepath.Base(path), utils.RandStringRunes(8)) bpPath := filepath.Join(path, bpName) cmd := exec.Command("scripts/package.sh") @@ -83,19 +84,24 @@ func PackageCachedBuildpack(root string) (string, string, error) { return "", "", err } - tarFile := filepath.Join(tmp, filepath.Base(root)) - cmd := exec.Command("./.bin/packager", tarFile) + path := filepath.Join(tmp, filepath.Base(root)) + cmd := exec.Command("scripts/package.sh", "-c", "-v", "0.0.0") + cmd.Env = append(os.Environ(), fmt.Sprintf("PACKAGE_DIR=%s", path)) cmd.Dir = root cmd.Stderr = os.Stderr out, err := cmd.Output() - return tarFile, string(out), err + return fmt.Sprintf("%s-cached", path), string(out), err } func GetLatestBuildpack(name string) (string, error) { return GetLatestCommunityBuildpack("cloudfoundry", name) } +func GetLatestUnpackagedBuildpack(name string) (string, error) { + return GetLatestUnpackagedCommunityBuildpack("cloudfoundry", name) +} + func DeleteBuildpack(root string) error { if root == os.Getenv("BP_PACKAGED_PATH") { return nil @@ -103,10 +109,30 @@ func DeleteBuildpack(root string) error { return os.RemoveAll(root) } +func GetLatestUnpackagedCommunityBuildpack(org, name string) (string, error) { + uri := fmt.Sprintf("https://api.github.com/repos/%s/%s/releases/latest", org, name) + ctx := context.Background() + client := utils.NewGitClient(ctx) + + release := struct { + TagName string `json:"tag_name"` + TarballURL string `json:"tarball_url"` + }{} + request, err := http.NewRequest(http.MethodGet, uri, nil) + if err != nil { + return "", err + } + if _, err := client.Do(ctx, request, &release); err != nil { + return "", err + } + + return downloadAndUnTarBuildpack(release.TarballURL, fmt.Sprintf("%s-cached", name), release.TagName, 1) +} + func GetLatestCommunityBuildpack(org, name string) (string, error) { uri := fmt.Sprintf("https://api.github.com/repos/%s/%s/releases/latest", org, name) ctx := context.Background() - client := NewGitClient(ctx) + client := utils.NewGitClient(ctx) release := struct { TagName string `json:"tag_name"` @@ -125,9 +151,13 @@ func GetLatestCommunityBuildpack(org, name string) (string, error) { return "", fmt.Errorf("there are no releases for %s", name) } - contents, found := downloadCache.Load(name + release.TagName) + return downloadAndUnTarBuildpack(release.Assets[0].BrowserDownloadURL, name, release.TagName, 0) +} + +func downloadAndUnTarBuildpack(downloadURL, name, tagName string, level int) (string, error) { //'level' specifies which level of the untarred directory we care about + contents, found := downloadCache.Load(name + tagName) if !found { - buildpackResp, err := http.Get(release.Assets[0].BrowserDownloadURL) + buildpackResp, err := http.Get(downloadURL) if err != nil { return "", err } @@ -143,7 +173,7 @@ func GetLatestCommunityBuildpack(org, name string) (string, error) { return "", errors.Errorf("Erroring Getting buildpack : status %d : %s", buildpackResp.StatusCode, contents) } - downloadCache.Store(name+release.TagName, contents) + downloadCache.Store(name+tagName, contents) } downloadFile, err := ioutil.TempFile("", "") @@ -162,5 +192,5 @@ func GetLatestCommunityBuildpack(org, name string) (string, error) { return "", err } - return dest, helper.ExtractTarGz(downloadFile.Name(), dest, 0) + return dest, helper.ExtractTarGz(downloadFile.Name(), dest, level) } diff --git a/vendor/github.com/cloudfoundry/dagger/executable.go b/vendor/github.com/cloudfoundry/dagger/executable.go new file mode 100644 index 00000000..0c2e2feb --- /dev/null +++ b/vendor/github.com/cloudfoundry/dagger/executable.go @@ -0,0 +1,44 @@ +package dagger + +import ( + "bytes" + "github.com/buildpack/libbuildpack/logger" + executable "github.com/cloudfoundry/libbuildpack/cutlass/docker" + "os/exec" +) + +const PackExecutableName = "pack" + +type PackExecutable struct { + name string + logger logger.Logger +} + +func NewPackExecutable(logger logger.Logger) PackExecutable { + return PackExecutable{ + name: PackExecutableName, + logger: logger, + } +} + +func (p PackExecutable) Execute(options executable.ExecuteOptions, args ...string) (string, string, error) { + p.logger.Info("Running Pack") + + packCmd := exec.Command(p.name, args...) + if options.Dir != "" { + packCmd.Dir = options.Dir + } + stdout := bytes.NewBuffer([]byte{}) + stderr := bytes.NewBuffer([]byte{}) + + packCmd.Stdout = stdout + packCmd.Stderr = stderr + + p.logger.Info("") + if err := packCmd.Run(); err != nil { + return "", "", err + } + return stdout.String(), stderr.String(), nil +} + + diff --git a/vendor/github.com/cloudfoundry/dagger/go.mod b/vendor/github.com/cloudfoundry/dagger/go.mod index a6d1dfe7..320b63b3 100644 --- a/vendor/github.com/cloudfoundry/dagger/go.mod +++ b/vendor/github.com/cloudfoundry/dagger/go.mod @@ -1,11 +1,15 @@ module github.com/cloudfoundry/dagger require ( + code.cloudfoundry.org/lager v2.0.0+incompatible + github.com/buildpack/libbuildpack v1.24.3 + github.com/cloudfoundry/libbuildpack v0.0.0-20191007182113-c10f57166e5b github.com/cloudfoundry/libcfbuildpack v1.76.0 github.com/google/go-github v17.0.0+incompatible github.com/google/go-querystring v1.0.0 // indirect + github.com/onsi/gomega v1.7.0 github.com/pkg/errors v0.8.1 - golang.org/x/net v0.0.0-20190628185345-da137c7871d7 // indirect + github.com/sclevine/spec v1.2.0 golang.org/x/oauth2 v0.0.0-20190319182350-c85d3e98c914 ) diff --git a/vendor/github.com/cloudfoundry/dagger/go.sum b/vendor/github.com/cloudfoundry/dagger/go.sum index ce24c36a..f5ae2363 100644 --- a/vendor/github.com/cloudfoundry/dagger/go.sum +++ b/vendor/github.com/cloudfoundry/dagger/go.sum @@ -1,26 +1,45 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +code.cloudfoundry.org/lager v2.0.0+incompatible h1:WZwDKDB2PLd/oL+USK4b4aEjUymIej9My2nUQ9oWEwQ= +code.cloudfoundry.org/lager v2.0.0+incompatible/go.mod h1:O2sS7gKP3HM2iemG+EnwvyNQK7pTSC6Foi4QiMp9sSk= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/buildpack/libbuildpack v1.19.0 h1:HUkaIwuGmPbQhujBjYNpd+E4f0NdAgAgHq7skydiL5s= github.com/buildpack/libbuildpack v1.19.0/go.mod h1:oxgSTzPbWscHs27iuYrctEZpSak2m/qPThA+9JM0Boo= +github.com/buildpack/libbuildpack v1.24.3 h1:bhAxazWrAZkxPSnpEzxc4a8Nc8FZfl1A76Va8r978/A= +github.com/buildpack/libbuildpack v1.24.3/go.mod h1:16+PwmWtgcwzIVcCzwxwc9yi1g/NwqF+ji9IU0deBpg= +github.com/cloudfoundry/libbuildpack v0.0.0-20191007182113-c10f57166e5b h1:W/ieO8SAZfeRlxpla9WF4INqBCWXTELoa12+akON6mI= +github.com/cloudfoundry/libbuildpack v0.0.0-20191007182113-c10f57166e5b/go.mod h1:F89xsc6s04sSmwubA99WA9m5uvcLBFeNln17bT8xap0= github.com/cloudfoundry/libcfbuildpack v1.76.0 h1:oMTv35mjk5Jogzy2sshVXHyolDWnWHMfANQ0UooXJq0= github.com/cloudfoundry/libcfbuildpack v1.76.0/go.mod h1:QGm+nzixn579dvQNlS7ZQET541y2hEpZ0/5uNxkQ04Y= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/elazarl/goproxy v0.0.0-20190911111923-ecfe977594f1/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= +github.com/elazarl/goproxy/ext v0.0.0-20190911111923-ecfe977594f1/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jarcoal/httpmock v1.0.4/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -36,41 +55,58 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/sclevine/spec v1.2.0 h1:1Jwdf9jSfDl9NVmt8ndHqbTZ7XCCPbh1jI3hkDBHVYA= github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/tidwall/gjson v1.3.2/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= +github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7 h1:rTIdg5QFRR7XCaK4LCjBiPbx8j4DQRpdYMnGn/bJUEU= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190916140828-c8589233b77d h1:mCMDWKhNO37A7GAhOpHPbIw1cjd0V86kX1/WA9c7FZ8= +golang.org/x/net v0.0.0-20190916140828-c8589233b77d/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20190319182350-c85d3e98c914 h1:jIOcLT9BZzyJ9ce+IwwZ+aF9yeCqzrR+NrD68a/SHKw= golang.org/x/oauth2 v0.0.0-20190319182350-c85d3e98c914/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb h1:fgwFCsaw9buMuxNd6+DQfAuSFqbNiQZpcgJQAgJsK6k= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916165910-8a69140bde95/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/vendor/github.com/cloudfoundry/dagger/pack.go b/vendor/github.com/cloudfoundry/dagger/pack.go index 0bb9882e..5ca192d3 100644 --- a/vendor/github.com/cloudfoundry/dagger/pack.go +++ b/vendor/github.com/cloudfoundry/dagger/pack.go @@ -2,14 +2,17 @@ package dagger import ( "bytes" + "code.cloudfoundry.org/lager" "crypto/sha256" "fmt" + "github.com/buildpack/libbuildpack/logger" + "github.com/cloudfoundry/dagger/utils" + "github.com/cloudfoundry/libbuildpack/cutlass/docker" + "github.com/pkg/errors" "io" "os" - "os/exec" + "sort" "sync" - - "github.com/pkg/errors" ) const ( @@ -29,32 +32,79 @@ var ( queueIsInitializedMutex sync.Mutex ) -// This returns the build logs as part of the error case +type Pack struct { + dir string + image string + env map[string]string + buildpacks []string + offline bool + executable PackExecutable +} + +type PackOption func(Pack) Pack + func PackBuild(appDir string, buildpacks ...string) (*App, error) { - return PackBuildNamedImage(RandStringRunes(16), appDir, buildpacks...) + return NewPack( + appDir, + RandomImage(), + SetBuildpacks(buildpacks...), + ).Build() } func PackBuildWithEnv(appDir string, env map[string]string, buildpacks ...string) (*App, error) { - return PackBuildNamedImageWithEnv(RandStringRunes(16), appDir, env, buildpacks...) + return NewPack( + appDir, + RandomImage(), + SetEnv(env), + SetBuildpacks(buildpacks...), + ).Build() } // This pack builds an app from appDir into appImageName, to allow specifying an image name in a test -func PackBuildNamedImage(appImage, appDir string, bpPaths ...string) (*App, error) { - return PackBuildNamedImageWithEnv(appImage, appDir, nil, bpPaths...) +func PackBuildNamedImage(appImage, appDir string, buildpacks ...string) (*App, error) { + return NewPack( + appDir, + SetImage(appImage), + SetBuildpacks(buildpacks...), + ).Build() } -func PackBuildNamedImageWithEnv(appImage, appDir string, env map[string]string, bpPaths ...string) (*App, error) { - buildLogs := &bytes.Buffer{} +func SetImage(image string) PackOption { + return func(pack Pack) Pack { + pack.image = image + return pack + } +} - cmd := exec.Command("pack", "build", appImage, "--builder", TestBuilderImage) - for _, bp := range bpPaths { - cmd.Args = append(cmd.Args, "--buildpack", bp) +func RandomImage() PackOption { + return func(pack Pack) Pack { + pack.image = utils.RandStringRunes(16) + return pack } +} - for key, val := range env { - cmd.Args = append(cmd.Args, "-e", fmt.Sprintf("%s=%s", key, val)) +func SetEnv(env map[string]string) PackOption { + return func(pack Pack) Pack { + pack.env = env + return pack } +} +func SetBuildpacks(buildpacks ...string) PackOption { + return func(pack Pack) Pack { + pack.buildpacks = append(pack.buildpacks, buildpacks...) + return pack + } +} + +func SetOffline() PackOption { + return func(pack Pack) Pack { + pack.offline = true + return pack + } +} + +func NewPack(dir string, options ...PackOption) Pack { var w io.Writer queueIsInitializedMutex.Lock() if queueIsInitialized { @@ -68,24 +118,62 @@ func PackBuildNamedImageWithEnv(appImage, appDir string, env map[string]string, } queueIsInitializedMutex.Unlock() - cmd.Dir = appDir - cmd.Stdout = io.MultiWriter(w, buildLogs) - cmd.Stderr = io.MultiWriter(w, buildLogs) - if err := cmd.Run(); err != nil { - return nil, errors.Wrap(err, buildLogs.String()) + buildLogs := &bytes.Buffer{} + + logger.NewLogger(io.MultiWriter(w, buildLogs), io.MultiWriter(w, buildLogs)) + + pack := Pack{ + dir: dir, + executable: NewPackExecutable(logger.NewLogger(os.Stdout, os.Stdout)), } - sum := sha256.Sum256([]byte(fmt.Sprintf("index.docker.io/library/%s:latest", appImage))) //This is how pack makes cache image names - cacheImage := fmt.Sprintf("pack-cache-%x", sum[:6]) + for _, option := range options { + pack = option(pack) + } + + return pack +} + +func (p Pack) Build() (*App, error) { + packArgs := []string{"build", p.image, "--builder", TestBuilderImage} + for _, bp := range p.buildpacks { + packArgs = append(packArgs, "--buildpack", bp) + } + + keys := []string{} + for key, _ := range p.env { + keys = append(keys, key) + } + + sort.Strings(keys) - app := &App{ - ImageName: appImage, - CacheImage: cacheImage, - buildLogs: buildLogs, - Env: make(map[string]string), - fixtureName: appDir, + for _, key := range keys { + packArgs = append(packArgs, "-e", fmt.Sprintf("%s=%s", key, p.env[key])) } - return app, nil + + if p.offline { + // probably want to pull here? + dockerLogger := lager.NewLogger("docker") + dockerExec := docker.NewDockerExecutable(dockerLogger) + + stdout, stderr, err := dockerExec.Execute(docker.ExecuteOptions{}, "pull", TestBuilderImage) + if err != nil { + return nil, fmt.Errorf("failed to pull %s\n with stdout %s\n stderr %s\n%s", TestBuilderImage, stdout, stderr, err.Error()) + } + packArgs = append(packArgs, "--network", "none", "--no-pull") + } + + buildLogs, _, err := p.executable.Execute(docker.ExecuteOptions{Dir: p.dir}, packArgs...) + + if err != nil { + return nil, errors.Wrap(err, buildLogs) + } + + sum := sha256.Sum256([]byte(fmt.Sprintf("index.docker.io/library/%s:latest", p.image))) //This is how pack makes cache image names + cacheImage := fmt.Sprintf("pack-cache-%x", sum[:6]) + + app := NewApp(p.dir, p.image, cacheImage, bytes.NewBufferString(buildLogs), make(map[string]string)) + return &app, nil } type chanWriter struct { diff --git a/vendor/github.com/cloudfoundry/dagger/utils.go b/vendor/github.com/cloudfoundry/dagger/utils/utils.go similarity index 98% rename from vendor/github.com/cloudfoundry/dagger/utils.go rename to vendor/github.com/cloudfoundry/dagger/utils/utils.go index bd2ec6f8..1ad581ec 100644 --- a/vendor/github.com/cloudfoundry/dagger/utils.go +++ b/vendor/github.com/cloudfoundry/dagger/utils/utils.go @@ -1,4 +1,4 @@ -package dagger +package utils import ( "context" diff --git a/vendor/github.com/cloudfoundry/libbuildpack/LICENSE b/vendor/github.com/cloudfoundry/libbuildpack/LICENSE new file mode 100644 index 00000000..d9a10c0d --- /dev/null +++ b/vendor/github.com/cloudfoundry/libbuildpack/LICENSE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/vendor/github.com/cloudfoundry/libbuildpack/NOTICE b/vendor/github.com/cloudfoundry/libbuildpack/NOTICE new file mode 100644 index 00000000..c021616d --- /dev/null +++ b/vendor/github.com/cloudfoundry/libbuildpack/NOTICE @@ -0,0 +1,11 @@ +Copyright (c) 2017-Present CloudFoundry.org Foundation, Inc. All Rights Reserved. + +This project contains software that is Copyright (c) 2017 Pivotal Software, Inc. + +This project is licensed to you under the Apache License, Version 2.0 (the "License"). + +You may not use this project except in compliance with the License. + +This project may include a number of subcomponents with separate copyright notices +and license terms. Your use of these subcomponents is subject to the terms and +conditions of the subcomponent's license, as noted in the LICENSE file. diff --git a/vendor/github.com/cloudfoundry/libbuildpack/cutlass/docker/cli.go b/vendor/github.com/cloudfoundry/libbuildpack/cutlass/docker/cli.go new file mode 100644 index 00000000..520ae88e --- /dev/null +++ b/vendor/github.com/cloudfoundry/libbuildpack/cutlass/docker/cli.go @@ -0,0 +1,112 @@ +package docker + +type CLI struct { + executable Executable +} + +func NewCLI(executable Executable) CLI { + return CLI{ + executable: executable, + } +} + +type BuildOptions struct { + Remove bool + NoCache bool + Tag string + File string + Context string +} + +func (c CLI) Build(options BuildOptions) (string, string, error) { + args := []string{"build"} + var execOptions ExecuteOptions + + if options.Remove { + args = append(args, "--rm") + } + + if options.NoCache { + args = append(args, "--no-cache") + } + + if options.Tag != "" { + args = append(args, "--tag", options.Tag) + } + + if options.File != "" { + args = append(args, "--file", options.File) + } + + if options.Context == "" { + options.Context = "." + } else { + execOptions.Dir = options.Context + } + + args = append(args, options.Context) + + stdout, stderr, err := c.executable.Execute(execOptions, args...) + if err != nil { + return stdout, stderr, err + } + + return stdout, stderr, nil +} + +type RunOptions struct { + Network string + Remove bool + TTY bool + Command string +} + +func (c CLI) Run(image string, options RunOptions) (string, string, error) { + args := []string{"run"} + + if options.Network != "" { + args = append(args, "--network", options.Network) + } + + if options.Remove { + args = append(args, "--rm") + } + + if options.TTY { + args = append(args, "--tty") + } + + args = append(args, image) + + if options.Command != "" { + args = append(args, "bash", "-c", options.Command) + } + + stdout, stderr, err := c.executable.Execute(ExecuteOptions{}, args...) + if err != nil { + return stdout, stderr, err + } + + return stdout, stderr, nil +} + +type RemoveImageOptions struct { + Force bool +} + +func (c CLI) RemoveImage(image string, options RemoveImageOptions) (string, string, error) { + args := []string{"image", "rm"} + + if options.Force { + args = append(args, "--force") + } + + args = append(args, image) + + stdout, stderr, err := c.executable.Execute(ExecuteOptions{}, args...) + if err != nil { + return stdout, stderr, err + } + + return stdout, stderr, nil +} diff --git a/vendor/github.com/cloudfoundry/libbuildpack/cutlass/docker/dockerfile.go b/vendor/github.com/cloudfoundry/libbuildpack/cutlass/docker/dockerfile.go new file mode 100644 index 00000000..58dadfa4 --- /dev/null +++ b/vendor/github.com/cloudfoundry/libbuildpack/cutlass/docker/dockerfile.go @@ -0,0 +1,111 @@ +package docker + +import ( + "bytes" + "fmt" + "os" + "path/filepath" + + "code.cloudfoundry.org/lager" +) + +func BuildStagingDockerfile(logger lager.Logger, fixturePath, buildpackPath string, envs []string) Dockerfile { + data := lager.Data{"fixture": fixturePath, "buildpack": buildpackPath, "envs": envs} + session := logger.Session("build-staging-dockerfile", data) + session.Debug("building") + + stack := os.Getenv("CF_STACK") + baseImage := os.Getenv("CF_STACK_DOCKER_IMAGE") + + if stack == "" { + stack = "cflinuxfs3" + } + + if baseImage == "" { + baseImage = fmt.Sprintf("cloudfoundry/%s", stack) + } + + instructions := []DockerfileInstruction{ + NewDockerfileENV(fmt.Sprintf("CF_STACK %s", stack)), + NewDockerfileENV("VCAP_APPLICATION {}"), + } + + for _, env := range envs { + instructions = append(instructions, NewDockerfileENV(env)) + } + + instructions = append(instructions, NewDockerfileADD(fmt.Sprintf("%s /tmp/staged/", fixturePath))) + instructions = append(instructions, NewDockerfileADD(fmt.Sprintf("%s /tmp/", buildpackPath))) + instructions = append(instructions, NewDockerfileRUN("mkdir -p /buildpack/0")) + instructions = append(instructions, NewDockerfileRUN("mkdir -p /tmp/cache")) + instructions = append(instructions, NewDockerfileRUN(fmt.Sprintf("unzip /tmp/%s -d /buildpack", filepath.Base(buildpackPath)))) + + // HACK around https://github.com/dotcloud/docker/issues/5490 + instructions = append(instructions, NewDockerfileRUN("mv /usr/sbin/tcpdump /usr/bin/tcpdump")) + + return NewDockerfile(baseImage, instructions...) +} + +type DockerfileInstructionType string + +const ( + DockerfileInstructionTypeFROM DockerfileInstructionType = "FROM" + DockerfileInstructionTypeADD DockerfileInstructionType = "ADD" + DockerfileInstructionTypeRUN DockerfileInstructionType = "RUN" + DockerfileInstructionTypeENV DockerfileInstructionType = "ENV" +) + +type DockerfileInstruction struct { + Type DockerfileInstructionType + Content string +} + +func NewDockerfileFROM(content string) DockerfileInstruction { + return DockerfileInstruction{ + Type: DockerfileInstructionTypeFROM, + Content: content, + } +} + +func NewDockerfileENV(content string) DockerfileInstruction { + return DockerfileInstruction{ + Type: DockerfileInstructionTypeENV, + Content: content, + } +} + +func NewDockerfileADD(content string) DockerfileInstruction { + return DockerfileInstruction{ + Type: DockerfileInstructionTypeADD, + Content: content, + } +} + +func NewDockerfileRUN(content string) DockerfileInstruction { + return DockerfileInstruction{ + Type: DockerfileInstructionTypeRUN, + Content: content, + } +} + +func (di DockerfileInstruction) String() string { + return fmt.Sprintf("%s %s", di.Type, di.Content) +} + +type Dockerfile struct { + *bytes.Buffer +} + +func NewDockerfile(baseImage string, instructions ...DockerfileInstruction) Dockerfile { + instructions = append([]DockerfileInstruction{NewDockerfileFROM(baseImage)}, instructions...) + + buffer := bytes.NewBuffer(nil) + for _, instruction := range instructions { + buffer.WriteString(instruction.String()) + buffer.WriteRune('\n') + } + + return Dockerfile{ + Buffer: buffer, + } +} diff --git a/vendor/github.com/cloudfoundry/libbuildpack/cutlass/docker/executable.go b/vendor/github.com/cloudfoundry/libbuildpack/cutlass/docker/executable.go new file mode 100644 index 00000000..e5da9c5e --- /dev/null +++ b/vendor/github.com/cloudfoundry/libbuildpack/cutlass/docker/executable.go @@ -0,0 +1,55 @@ +package docker + +import ( + "bytes" + "os/exec" + + "code.cloudfoundry.org/lager" +) + +//go:generate faux --interface Executable --output fakes/executable.go +type Executable interface { + Execute(options ExecuteOptions, args ...string) (stdout, stderr string, err error) +} + +type DockerExecutable struct { + name string + logger lager.Logger +} + +func NewDockerExecutable(logger lager.Logger) DockerExecutable { + logger = logger.Session("docker.executable") + + return DockerExecutable{ + name: "docker", + logger: logger, + } +} + +type ExecuteOptions struct { + Dir string +} + +func (de DockerExecutable) Execute(options ExecuteOptions, args ...string) (string, string, error) { + data := lager.Data{"options": options, "args": args} + session := de.logger.Session("execute", data) + + stdout := bytes.NewBuffer([]byte{}) + stderr := bytes.NewBuffer([]byte{}) + + command := exec.Command(de.name, args...) + command.Stdout = stdout + command.Stderr = stderr + + if options.Dir != "" { + command.Dir = options.Dir + } + + session.Debug("running", lager.Data{"path": de.name}) + err := command.Run() + if err != nil { + return "", "", err + } + + return stdout.String(), stderr.String(), nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index ce50acaa..937f65f4 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,5 +1,7 @@ # cloud.google.com/go v0.46.3 cloud.google.com/go/compute/metadata +# code.cloudfoundry.org/lager v2.0.0+incompatible +code.cloudfoundry.org/lager # github.com/BurntSushi/toml v0.3.1 github.com/BurntSushi/toml # github.com/Masterminds/semver v1.5.0 @@ -17,8 +19,11 @@ github.com/buildpack/libbuildpack/logger github.com/buildpack/libbuildpack/platform github.com/buildpack/libbuildpack/services github.com/buildpack/libbuildpack/stack -# github.com/cloudfoundry/dagger v0.0.0-20191001184736-b0f1e98b53b2 +# github.com/cloudfoundry/dagger v0.0.0-20191008210309-499f8aacb425 github.com/cloudfoundry/dagger +github.com/cloudfoundry/dagger/utils +# github.com/cloudfoundry/libbuildpack v0.0.0-20191007182113-c10f57166e5b +github.com/cloudfoundry/libbuildpack/cutlass/docker # github.com/cloudfoundry/libcfbuildpack v1.89.0 github.com/cloudfoundry/libcfbuildpack/build github.com/cloudfoundry/libcfbuildpack/buildpackplan