diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 603c01cd1fa..4116b30d626 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1,6 +1,6 @@ { "ImportPath": "k8s.io/kubernetes", - "GoVersion": "go1.5", + "GoVersion": "go1.6", "Packages": [ "./..." ], @@ -149,170 +149,180 @@ "Comment": "v0.1-62-g8d75e11", "Rev": "8d75e11374a1928608c906fe745b538483e7aeb2" }, + { + "ImportPath": "github.com/coreos/etcd/alarm", + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + }, { "ImportPath": "github.com/coreos/etcd/auth", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/client", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/clientv3", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/compactor", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/discovery", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/error", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/etcdserver", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/integration", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/lease", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/adt", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/contention", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/crc", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/fileutil", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/httputil", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/idutil", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/ioutil", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/logutil", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/netutil", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/pathutil", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/pbutil", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/runtime", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/schedule", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/testutil", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" + }, + { + "ImportPath": "github.com/coreos/etcd/pkg/tlsutil", + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/transport", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/types", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/pkg/wait", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/raft", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/rafthttp", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/snap", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/storage", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/store", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/version", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/etcd/wal", - "Comment": "v2.3.0", - "Rev": "5e6eb7e19d6385adfabb1f1caea03e732f9348ad" + "Comment": "v2.3.0-282-g8b320e7", + "Rev": "8b320e7c550067b1dfb37bd1682e8067023e0751" }, { "ImportPath": "github.com/coreos/go-etcd/etcd", @@ -353,11 +363,6 @@ "Comment": "v4", "Rev": "b4a58d95188dd092ae20072bac14cece0e67c388" }, - { - "ImportPath": "github.com/coreos/go-systemd/journal", - "Comment": "v4", - "Rev": "b4a58d95188dd092ae20072bac14cece0e67c388" - }, { "ImportPath": "github.com/coreos/go-systemd/unit", "Comment": "v4", diff --git a/Godeps/LICENSES b/Godeps/LICENSES index c877856cb39..012d5712357 100644 --- a/Godeps/LICENSES +++ b/Godeps/LICENSES @@ -4270,27 +4270,6 @@ Copyright 2014-2015 Stripe, Inc. Copyright (C) 2013 Blake Mizerany -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Copyright (C) 2013 Blake Mizerany - Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -4775,6 +4754,217 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +================================================================================ += Godeps/_workspace/src/github.com/coreos/etcd/alarm licensed under: = + + + 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. + +Copyright 2014 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). + ================================================================================ = Godeps/_workspace/src/github.com/coreos/etcd/auth licensed under: = @@ -9628,6 +9818,217 @@ Copyright 2014 CoreOS, Inc This product includes software developed at CoreOS, Inc. (http://www.coreos.com/). +================================================================================ += Godeps/_workspace/src/github.com/coreos/etcd/pkg/tlsutil licensed under: = + + + 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. + +Copyright 2014 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). + ================================================================================ = Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport licensed under: = @@ -13594,202 +13995,6 @@ third-party archives. limitations under the License. -================================================================================ -= Godeps/_workspace/src/github.com/coreos/go-systemd/journal licensed under: = - -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: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -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 -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. - - ================================================================================ = Godeps/_workspace/src/github.com/coreos/go-systemd/unit licensed under: = diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/alarm/alarms.go b/Godeps/_workspace/src/github.com/coreos/etcd/alarm/alarms.go new file mode 100644 index 00000000000..5d5a1bcec9d --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/alarm/alarms.go @@ -0,0 +1,152 @@ +// Copyright 2016 CoreOS, 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. + +// Package alarm manages health status alarms in etcd. +package alarm + +import ( + "sync" + + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/pkg/types" + "github.com/coreos/etcd/storage/backend" + "github.com/coreos/pkg/capnslog" +) + +var ( + alarmBucketName = []byte("alarm") + plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "alarm") +) + +type BackendGetter interface { + Backend() backend.Backend +} + +type alarmSet map[types.ID]*pb.AlarmMember + +// AlarmStore persists alarms to the backend. +type AlarmStore struct { + mu sync.Mutex + types map[pb.AlarmType]alarmSet + + bg BackendGetter +} + +func NewAlarmStore(bg BackendGetter) (*AlarmStore, error) { + ret := &AlarmStore{types: make(map[pb.AlarmType]alarmSet), bg: bg} + err := ret.restore() + return ret, err +} + +func (a *AlarmStore) Activate(id types.ID, at pb.AlarmType) *pb.AlarmMember { + a.mu.Lock() + defer a.mu.Unlock() + + newAlarm := &pb.AlarmMember{MemberID: uint64(id), Alarm: at} + if m := a.addToMap(newAlarm); m != newAlarm { + return m + } + + v, err := newAlarm.Marshal() + if err != nil { + plog.Panicf("failed to marshal alarm member") + } + + b := a.bg.Backend() + b.BatchTx().Lock() + b.BatchTx().UnsafePut(alarmBucketName, v, nil) + b.BatchTx().Unlock() + + return newAlarm +} + +func (a *AlarmStore) Deactivate(id types.ID, at pb.AlarmType) *pb.AlarmMember { + a.mu.Lock() + defer a.mu.Unlock() + + t := a.types[at] + if t == nil { + t = make(alarmSet) + a.types[at] = t + } + m := t[id] + if m == nil { + return nil + } + + delete(t, id) + + v, err := m.Marshal() + if err != nil { + plog.Panicf("failed to marshal alarm member") + } + + b := a.bg.Backend() + b.BatchTx().Lock() + b.BatchTx().UnsafeDelete(alarmBucketName, v) + b.BatchTx().Unlock() + + return m +} + +func (a *AlarmStore) Get(at pb.AlarmType) (ret []*pb.AlarmMember) { + a.mu.Lock() + defer a.mu.Unlock() + if at == pb.AlarmType_NONE { + for _, t := range a.types { + for _, m := range t { + ret = append(ret, m) + } + } + return ret + } + for _, m := range a.types[at] { + ret = append(ret, m) + } + return ret +} + +func (a *AlarmStore) restore() error { + b := a.bg.Backend() + tx := b.BatchTx() + + tx.Lock() + tx.UnsafeCreateBucket(alarmBucketName) + err := tx.UnsafeForEach(alarmBucketName, func(k, v []byte) error { + var m pb.AlarmMember + if err := m.Unmarshal(k); err != nil { + return err + } + a.addToMap(&m) + return nil + }) + tx.Unlock() + + b.ForceCommit() + return err +} + +func (a *AlarmStore) addToMap(newAlarm *pb.AlarmMember) *pb.AlarmMember { + t := a.types[newAlarm.Alarm] + if t == nil { + t = make(alarmSet) + a.types[newAlarm.Alarm] = t + } + m := t[types.ID(newAlarm.MemberID)] + if m != nil { + return m + } + t[types.ID(newAlarm.MemberID)] = newAlarm + return newAlarm +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/auth/authpb/auth.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/auth/authpb/auth.pb.go new file mode 100644 index 00000000000..6f37933006e --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/auth/authpb/auth.pb.go @@ -0,0 +1,509 @@ +// Code generated by protoc-gen-gogo. +// source: auth.proto +// DO NOT EDIT! + +/* + Package authpb is a generated protocol buffer package. + + It is generated from these files: + auth.proto + + It has these top-level messages: + User + Role +*/ +package authpb + +import ( + "fmt" + + proto "github.com/gogo/protobuf/proto" + + math "math" +) + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// User is a single entry in the bucket authUsers +type User struct { + Name []byte `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Password []byte `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + Tombstone int64 `protobuf:"varint,3,opt,name=tombstone,proto3" json:"tombstone,omitempty"` +} + +func (m *User) Reset() { *m = User{} } +func (m *User) String() string { return proto.CompactTextString(m) } +func (*User) ProtoMessage() {} + +// Role is a single entry in the bucket authRoles +type Role struct { + Name []byte `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` +} + +func (m *Role) Reset() { *m = Role{} } +func (m *Role) String() string { return proto.CompactTextString(m) } +func (*Role) ProtoMessage() {} + +func init() { + proto.RegisterType((*User)(nil), "authpb.User") + proto.RegisterType((*Role)(nil), "authpb.Role") +} +func (m *User) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *User) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Name != nil { + if len(m.Name) > 0 { + data[i] = 0xa + i++ + i = encodeVarintAuth(data, i, uint64(len(m.Name))) + i += copy(data[i:], m.Name) + } + } + if m.Password != nil { + if len(m.Password) > 0 { + data[i] = 0x12 + i++ + i = encodeVarintAuth(data, i, uint64(len(m.Password))) + i += copy(data[i:], m.Password) + } + } + if m.Tombstone != 0 { + data[i] = 0x18 + i++ + i = encodeVarintAuth(data, i, uint64(m.Tombstone)) + } + return i, nil +} + +func (m *Role) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *Role) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Name != nil { + if len(m.Name) > 0 { + data[i] = 0x12 + i++ + i = encodeVarintAuth(data, i, uint64(len(m.Name))) + i += copy(data[i:], m.Name) + } + } + return i, nil +} + +func encodeFixed64Auth(data []byte, offset int, v uint64) int { + data[offset] = uint8(v) + data[offset+1] = uint8(v >> 8) + data[offset+2] = uint8(v >> 16) + data[offset+3] = uint8(v >> 24) + data[offset+4] = uint8(v >> 32) + data[offset+5] = uint8(v >> 40) + data[offset+6] = uint8(v >> 48) + data[offset+7] = uint8(v >> 56) + return offset + 8 +} +func encodeFixed32Auth(data []byte, offset int, v uint32) int { + data[offset] = uint8(v) + data[offset+1] = uint8(v >> 8) + data[offset+2] = uint8(v >> 16) + data[offset+3] = uint8(v >> 24) + return offset + 4 +} +func encodeVarintAuth(data []byte, offset int, v uint64) int { + for v >= 1<<7 { + data[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + data[offset] = uint8(v) + return offset + 1 +} +func (m *User) Size() (n int) { + var l int + _ = l + if m.Name != nil { + l = len(m.Name) + if l > 0 { + n += 1 + l + sovAuth(uint64(l)) + } + } + if m.Password != nil { + l = len(m.Password) + if l > 0 { + n += 1 + l + sovAuth(uint64(l)) + } + } + if m.Tombstone != 0 { + n += 1 + sovAuth(uint64(m.Tombstone)) + } + return n +} + +func (m *Role) Size() (n int) { + var l int + _ = l + if m.Name != nil { + l = len(m.Name) + if l > 0 { + n += 1 + l + sovAuth(uint64(l)) + } + } + return n +} + +func sovAuth(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozAuth(x uint64) (n int) { + return sovAuth(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *User) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: User: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: User: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAuth + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = append(m.Name[:0], data[iNdEx:postIndex]...) + if m.Name == nil { + m.Name = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAuth + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Password = append(m.Password[:0], data[iNdEx:postIndex]...) + if m.Password == nil { + m.Password = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Tombstone", wireType) + } + m.Tombstone = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.Tombstone |= (int64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipAuth(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthAuth + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Role) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Role: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Role: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAuth + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthAuth + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = append(m.Name[:0], data[iNdEx:postIndex]...) + if m.Name == nil { + m.Name = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAuth(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthAuth + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipAuth(data []byte) (n int, err error) { + l := len(data) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAuth + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAuth + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if data[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAuth + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthAuth + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowAuth + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipAuth(data[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthAuth = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowAuth = fmt.Errorf("proto: integer overflow") +) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/auth/authpb/auth.proto b/Godeps/_workspace/src/github.com/coreos/etcd/auth/authpb/auth.proto new file mode 100644 index 00000000000..00f94e71d03 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/auth/authpb/auth.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package authpb; + +import "gogoproto/gogo.proto"; + +option (gogoproto.marshaler_all) = true; +option (gogoproto.sizer_all) = true; +option (gogoproto.unmarshaler_all) = true; +option (gogoproto.goproto_getters_all) = false; +option (gogoproto.goproto_enum_prefix_all) = false; + +// User is a single entry in the bucket authUsers +message User { + bytes name = 1; + bytes password = 2; + int64 tombstone = 3; +} + +// Role is a single entry in the bucket authRoles +message Role { + bytes name = 2; +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/auth/store.go b/Godeps/_workspace/src/github.com/coreos/etcd/auth/store.go index 913c7405c1d..39cf96bb8e3 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/auth/store.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/auth/store.go @@ -15,34 +15,57 @@ package auth import ( + "errors" + + "github.com/coreos/etcd/auth/authpb" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/storage/backend" "github.com/coreos/pkg/capnslog" + "golang.org/x/crypto/bcrypt" ) -type backendGetter interface { - Backend() backend.Backend -} - var ( - enableFlagKey = []byte("authEnabled") - authBucketName = []byte("auth") + enableFlagKey = []byte("authEnabled") + + authBucketName = []byte("auth") + authUsersBucketName = []byte("authUsers") + authRolesBucketName = []byte("authRoles") plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "auth") + + ErrUserAlreadyExist = errors.New("auth: user already exists") + ErrUserNotFound = errors.New("auth: user not found") + ErrRoleAlreadyExist = errors.New("auth: role already exists") ) type AuthStore interface { // AuthEnable() turns on the authentication feature AuthEnable() + + // Recover recovers the state of auth store from the given backend + Recover(b backend.Backend) + + // UserAdd adds a new user + UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) + + // UserDelete deletes a user + UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) + + // UserChangePassword changes a password of a user + UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) + + // RoleAdd adds a new role + RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) } type authStore struct { - bgetter backendGetter + be backend.Backend } func (as *authStore) AuthEnable() { value := []byte{1} - b := as.bgetter.Backend() + b := as.be tx := b.BatchTx() tx.Lock() tx.UnsafePut(authBucketName, enableFlagKey, value) @@ -52,15 +75,138 @@ func (as *authStore) AuthEnable() { plog.Noticef("Authentication enabled") } -func NewAuthStore(bgetter backendGetter) *authStore { - b := bgetter.Backend() - tx := b.BatchTx() +func (as *authStore) Recover(be backend.Backend) { + as.be = be + // TODO(mitake): recovery process +} + +func (as *authStore) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) { + plog.Noticef("adding a new user: %s", r.Name) + + hashed, err := bcrypt.GenerateFromPassword([]byte(r.Password), bcrypt.DefaultCost) + if err != nil { + plog.Errorf("failed to hash password: %s", err) + return nil, err + } + + tx := as.be.BatchTx() tx.Lock() + defer tx.Unlock() + + _, vs := tx.UnsafeRange(authUsersBucketName, []byte(r.Name), nil, 0) + if len(vs) != 0 { + return &pb.AuthUserAddResponse{}, ErrUserAlreadyExist + } + + newUser := authpb.User{ + Name: []byte(r.Name), + Password: hashed, + } + + marshaledUser, merr := newUser.Marshal() + if merr != nil { + plog.Errorf("failed to marshal a new user data: %s", merr) + return nil, merr + } + + tx.UnsafePut(authUsersBucketName, []byte(r.Name), marshaledUser) + + plog.Noticef("added a new user: %s", r.Name) + + return &pb.AuthUserAddResponse{}, nil +} + +func (as *authStore) UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) { + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + _, vs := tx.UnsafeRange(authUsersBucketName, []byte(r.Name), nil, 0) + if len(vs) != 1 { + return &pb.AuthUserDeleteResponse{}, ErrUserNotFound + } + + tx.UnsafeDelete(authUsersBucketName, []byte(r.Name)) + + plog.Noticef("deleted a user: %s", r.Name) + + return &pb.AuthUserDeleteResponse{}, nil +} + +func (as *authStore) UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) { + // TODO(mitake): measure the cost of bcrypt.GenerateFromPassword() + // If the cost is too high, we should move the encryption to outside of the raft + hashed, err := bcrypt.GenerateFromPassword([]byte(r.Password), bcrypt.DefaultCost) + if err != nil { + plog.Errorf("failed to hash password: %s", err) + return nil, err + } + + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + _, vs := tx.UnsafeRange(authUsersBucketName, []byte(r.Name), nil, 0) + if len(vs) != 1 { + return &pb.AuthUserChangePasswordResponse{}, ErrUserNotFound + } + + updatedUser := authpb.User{ + Name: []byte(r.Name), + Password: hashed, + } + + marshaledUser, merr := updatedUser.Marshal() + if merr != nil { + plog.Errorf("failed to marshal a new user data: %s", merr) + return nil, merr + } + + tx.UnsafePut(authUsersBucketName, []byte(r.Name), marshaledUser) + + plog.Noticef("changed a password of a user: %s", r.Name) + + return &pb.AuthUserChangePasswordResponse{}, nil +} + +func (as *authStore) RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) { + tx := as.be.BatchTx() + tx.Lock() + defer tx.Unlock() + + _, vs := tx.UnsafeRange(authRolesBucketName, []byte(r.Name), nil, 0) + if len(vs) != 0 { + return nil, ErrRoleAlreadyExist + } + + newRole := &authpb.Role{ + Name: []byte(r.Name), + } + + marshaledRole, err := newRole.Marshal() + if err != nil { + return nil, err + } + + tx.UnsafePut(authRolesBucketName, []byte(r.Name), marshaledRole) + + plog.Noticef("Role %s is created", r.Name) + + return &pb.AuthRoleAddResponse{}, nil +} + +func NewAuthStore(be backend.Backend) *authStore { + tx := be.BatchTx() + tx.Lock() + tx.UnsafeCreateBucket(authBucketName) + tx.UnsafeCreateBucket(authUsersBucketName) + tx.UnsafeCreateBucket(authRolesBucketName) + tx.Unlock() - b.ForceCommit() + be.ForceCommit() return &authStore{ - bgetter: bgetter, + be: be, } } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/client/README.md b/Godeps/_workspace/src/github.com/coreos/etcd/client/README.md index e9e4be468eb..16f7f9d19f6 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/client/README.md +++ b/Godeps/_workspace/src/github.com/coreos/etcd/client/README.md @@ -4,6 +4,11 @@ etcd/client is the Go client library for etcd. [![GoDoc](https://godoc.org/github.com/coreos/etcd/client?status.png)](https://godoc.org/github.com/coreos/etcd/client) +etcd uses go's `vendor` directory to manage external dependencies. If `client` is imported +outside of etcd, simply copy `client` to the `vendor` directory or use tools like godep to +manage your own dependency, as in [vendor directories](https://golang.org/cmd/go/#hdr-Vendor_Directories). +For more detail, please read [Go vendor design](https://golang.org/s/go15vendor). + ## Install ```bash @@ -19,7 +24,7 @@ import ( "log" "time" - "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context" + "golang.org/x/net/context" "github.com/coreos/etcd/client" ) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/client/auth_user.go b/Godeps/_workspace/src/github.com/coreos/etcd/client/auth_user.go index 3eb3cd164d1..6af1c2886a9 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/client/auth_user.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/client/auth_user.go @@ -41,10 +41,6 @@ type UserRoles struct { Roles []Role `json:"roles"` } -type userName struct { - User string `json:"user"` -} - func v2AuthURL(ep url.URL, action string, name string) *url.URL { if name != "" { ep.Path = path.Join(ep.Path, defaultV2AuthPrefix, action, name) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/client/cancelreq.go b/Godeps/_workspace/src/github.com/coreos/etcd/client/cancelreq.go index fefdb40e426..76d1f040198 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/client/cancelreq.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/client/cancelreq.go @@ -4,8 +4,6 @@ // borrowed from golang/net/context/ctxhttp/cancelreq.go -// +build go1.5 - package client import "net/http" diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/client/cancelreq_go14.go b/Godeps/_workspace/src/github.com/coreos/etcd/client/cancelreq_go14.go deleted file mode 100644 index 2bed38a4181..00000000000 --- a/Godeps/_workspace/src/github.com/coreos/etcd/client/cancelreq_go14.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// borrowed from golang/net/context/ctxhttp/cancelreq_go14.go - -// +build !go1.5 - -package client - -import "net/http" - -func requestCanceler(tr CancelableTransport, req *http.Request) func() { - return func() { - tr.CancelRequest(req) - } -} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/client/client.go b/Godeps/_workspace/src/github.com/coreos/etcd/client/client.go index 0bef131f647..2aaa112ed30 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/client/client.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/client/client.go @@ -342,7 +342,9 @@ func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*http.Respo resp, body, err = hc.Do(ctx, action) if err != nil { cerr.Errors = append(cerr.Errors, err) - // mask previous errors with context error, which is controlled by user + if err == ctx.Err() { + return nil, nil, ctx.Err() + } if err == context.Canceled || err == context.DeadlineExceeded { return nil, nil, err } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/client/doc.go b/Godeps/_workspace/src/github.com/coreos/etcd/client/doc.go index 70111caceb9..36c3d8c9dc3 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/client/doc.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/client/doc.go @@ -34,6 +34,8 @@ Create a Config and exchange it for a Client: // handle error } +Clients are safe for concurrent use by multiple goroutines. + Create a KeysAPI using the Client, then use it to interact with etcd: kAPI := client.NewKeysAPI(c) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/README.md b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/README.md index 6b9735d0338..e67d68a1117 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/README.md +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/README.md @@ -16,7 +16,7 @@ Create client using `clientv3.New`: ```go cli, err := clientv3.New(clientv3.Config{ - Endpoints: []string{"localhost:12378", "localhost:22378", "localhost:32378"}, + Endpoints: []string{"localhost:2379", "localhost:22379", "localhost:32379"}, DialTimeout: 5 * time.Second, }) if err != nil { @@ -40,6 +40,11 @@ if err != nil { // use the response ``` +etcd uses go's `vendor` directory to manage external dependencies. If `clientv3` is imported +outside of etcd, simply copy `clientv3` to the `vendor` directory or use tools like godep to +manage your own dependency, as in [vendor directories](https://golang.org/cmd/go/#hdr-Vendor_Directories). +For more detail, please read [Go vendor design](https://golang.org/s/go15vendor). + ## Error Handling etcd client returns 2 types of errors: diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/auth.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/auth.go index 5c681972029..fceea770be7 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/auth.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/auth.go @@ -21,12 +21,28 @@ import ( ) type ( - AuthEnableResponse pb.AuthEnableResponse + AuthEnableResponse pb.AuthEnableResponse + AuthUserAddResponse pb.AuthUserAddResponse + AuthUserDeleteResponse pb.AuthUserDeleteResponse + AuthUserChangePasswordResponse pb.AuthUserChangePasswordResponse + AuthRoleAddResponse pb.AuthRoleAddResponse ) type Auth interface { - // AuthEnable enables auth of a etcd cluster. + // AuthEnable enables auth of an etcd cluster. AuthEnable(ctx context.Context) (*AuthEnableResponse, error) + + // UserAdd adds a new user to an etcd cluster. + UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) + + // UserDelete deletes a user from an etcd cluster. + UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) + + // UserChangePassword changes a password of a user. + UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error) + + // RoleAdd adds a new user to an etcd cluster. + RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) } type auth struct { @@ -49,3 +65,23 @@ func (auth *auth) AuthEnable(ctx context.Context) (*AuthEnableResponse, error) { resp, err := auth.remote.AuthEnable(ctx, &pb.AuthEnableRequest{}) return (*AuthEnableResponse)(resp), err } + +func (auth *auth) UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) { + resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password}) + return (*AuthUserAddResponse)(resp), err +} + +func (auth *auth) UserDelete(ctx context.Context, name string) (*AuthUserDeleteResponse, error) { + resp, err := auth.remote.UserDelete(ctx, &pb.AuthUserDeleteRequest{Name: name}) + return (*AuthUserDeleteResponse)(resp), err +} + +func (auth *auth) UserChangePassword(ctx context.Context, name string, password string) (*AuthUserChangePasswordResponse, error) { + resp, err := auth.remote.UserChangePassword(ctx, &pb.AuthUserChangePasswordRequest{Name: name, Password: password}) + return (*AuthUserChangePasswordResponse)(resp), err +} + +func (auth *auth) RoleAdd(ctx context.Context, name string) (*AuthRoleAddResponse, error) { + resp, err := auth.remote.RoleAdd(ctx, &pb.AuthRoleAddRequest{Name: name}) + return (*AuthRoleAddResponse)(resp), err +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/client.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/client.go index 94832cbca0f..71c64ef0fad 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/client.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/client.go @@ -15,8 +15,9 @@ package clientv3 import ( - "crypto/tls" "errors" + "io/ioutil" + "log" "net" "net/url" "strings" @@ -51,23 +52,6 @@ type Client struct { cancel context.CancelFunc } -// EndpointDialer is a policy for choosing which endpoint to dial next -type EndpointDialer func(*Client) (*grpc.ClientConn, error) - -type Config struct { - // Endpoints is a list of URLs - Endpoints []string - - // RetryDialer chooses the next endpoint to use - RetryDialer EndpointDialer - - // DialTimeout is the timeout for failing to establish a connection. - DialTimeout time.Duration - - // TLS holds the client secure credentials, if any. - TLS *tls.Config -} - // New creates a new etcdv3 client from a given configuration. func New(cfg Config) (*Client, error) { if cfg.RetryDialer == nil { @@ -85,6 +69,15 @@ func NewFromURL(url string) (*Client, error) { return New(Config{Endpoints: []string{url}}) } +// NewFromConfigFile creates a new etcdv3 client from a configuration file. +func NewFromConfigFile(path string) (*Client, error) { + cfg, err := configFromFile(path) + if err != nil { + return nil, err + } + return New(*cfg) +} + // Close shuts down the client's etcd connections. func (c *Client) Close() error { c.mu.Lock() @@ -179,7 +172,13 @@ func newClient(cfg *Config) (*Client, error) { client.Lease = NewLease(client) client.Watcher = NewWatcher(client) client.Auth = NewAuth(client) - client.Maintenance = &maintenance{c: client} + client.Maintenance = NewMaintenance(client) + if cfg.Logger != nil { + logger.Set(cfg.Logger) + } else { + // disable client side grpc by default + logger.Set(log.New(ioutil.Discard, "", 0)) + } return client, nil } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/compare.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/compare.go index 411f8667633..d74db77958f 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/compare.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/compare.go @@ -72,11 +72,11 @@ func Version(key string) Cmp { return Cmp{Key: []byte(key), Target: pb.Compare_VERSION} } -func CreatedRevision(key string) Cmp { +func CreateRevision(key string) Cmp { return Cmp{Key: []byte(key), Target: pb.Compare_CREATE} } -func ModifiedRevision(key string) Cmp { +func ModRevision(key string) Cmp { return Cmp{Key: []byte(key), Target: pb.Compare_MOD} } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/doc.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/doc.go new file mode 100644 index 00000000000..ad4b653ad71 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/doc.go @@ -0,0 +1,17 @@ +// Copyright 2016 CoreOS, 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. + +// Package concurrency implements concurrency operations on top of +// etcd such as distributed locks, barriers, and elections. +package concurrency diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/election.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/election.go index d74d19be4f2..991bd2628c1 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/election.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/election.go @@ -74,7 +74,7 @@ func (e *Election) Proclaim(ctx context.Context, val string) error { if e.leaderSession == nil { return ErrElectionNotLeader } - cmp := v3.Compare(v3.CreatedRevision(e.leaderKey), "=", e.leaderRev) + cmp := v3.Compare(v3.CreateRevision(e.leaderKey), "=", e.leaderRev) txn := e.client.Txn(ctx).If(cmp) txn = txn.Then(v3.OpPut(e.leaderKey, val, v3.WithLease(e.leaderSession.Lease()))) tresp, terr := txn.Commit() diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/key.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/key.go index c08a5b5eb25..f2c6a3329f1 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/key.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/key.go @@ -11,6 +11,7 @@ // 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. + package concurrency import ( @@ -32,7 +33,7 @@ func NewUniqueKV(ctx context.Context, kv v3.KV, pfx, val string, opts ...v3.OpOp for { newKey := fmt.Sprintf("%s/%v", pfx, time.Now().UnixNano()) put := v3.OpPut(newKey, val, opts...) - cmp := v3.Compare(v3.ModifiedRevision(newKey), "=", 0) + cmp := v3.Compare(v3.ModRevision(newKey), "=", 0) resp, err := kv.Txn(ctx).If(cmp).Then(put).Commit() if err != nil { return "", 0, err @@ -73,7 +74,7 @@ func waitDelete(ctx context.Context, client *v3.Client, key string, rev int64) e // waitDeletes efficiently waits until all keys matched by Get(key, opts...) are deleted func waitDeletes(ctx context.Context, client *v3.Client, key string, opts ...v3.OpOption) error { - getOpts := []v3.OpOption{v3.WithSort(v3.SortByCreatedRev, v3.SortAscend)} + getOpts := []v3.OpOption{v3.WithSort(v3.SortByCreateRevision, v3.SortAscend)} getOpts = append(getOpts, opts...) resp, err := client.Get(ctx, key, getOpts...) maxRev := int64(math.MaxInt64) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/mutex.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/mutex.go index b378058ee3a..8ea8acd52d8 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/mutex.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/mutex.go @@ -64,7 +64,7 @@ func (m *Mutex) Unlock() error { } func (m *Mutex) IsOwner() v3.Cmp { - return v3.Compare(v3.CreatedRevision(m.myKey), "=", m.myRev) + return v3.Compare(v3.CreateRevision(m.myKey), "=", m.myRev) } func (m *Mutex) Key() string { return m.myKey } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/session.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/session.go index e8a68f0617d..b348a4b3cc7 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/session.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/session.go @@ -11,6 +11,7 @@ // 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. + package concurrency import ( @@ -48,7 +49,7 @@ func NewSession(client *v3.Client) (*Session, error) { return s, nil } - resp, err := client.Create(client.Ctx(), sessionTTL) + resp, err := client.Grant(client.Ctx(), sessionTTL) if err != nil { return nil, err } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/stm.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/stm.go index b4eb5545a97..7f3f9bcc782 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/stm.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/concurrency/stm.go @@ -235,7 +235,7 @@ func isKeyCurrent(k string, r *v3.GetResponse) v3.Cmp { if len(r.Kvs) != 0 { rev = r.Kvs[0].ModRevision + 1 } - return v3.Compare(v3.ModifiedRevision(k), "<", rev) + return v3.Compare(v3.ModRevision(k), "<", rev) } func respToValue(resp *v3.GetResponse) string { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/config.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/config.go new file mode 100644 index 00000000000..34cec6d642a --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/config.go @@ -0,0 +1,111 @@ +// Copyright 2016 CoreOS, 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. + +package clientv3 + +import ( + "crypto/tls" + "crypto/x509" + "io/ioutil" + "time" + + "github.com/coreos/etcd/pkg/tlsutil" + "github.com/ghodss/yaml" + "google.golang.org/grpc" +) + +// EndpointDialer is a policy for choosing which endpoint to dial next +type EndpointDialer func(*Client) (*grpc.ClientConn, error) + +type Config struct { + // Endpoints is a list of URLs + Endpoints []string + + // RetryDialer chooses the next endpoint to use + RetryDialer EndpointDialer + + // DialTimeout is the timeout for failing to establish a connection. + DialTimeout time.Duration + + // TLS holds the client secure credentials, if any. + TLS *tls.Config + + // Logger is the logger used by client library. + Logger Logger +} + +type YamlConfig struct { + Endpoints []string `json:"endpoints"` + DialTimeout time.Duration `json:"dial-timeout"` + InsecureTransport bool `json:"insecure-transport"` + InsecureSkipTLSVerify bool `json:"insecure-skip-tls-verify"` + Certfile string `json:"cert-file"` + Keyfile string `json:"key-file"` + CAfile string `json:"ca-file"` +} + +func configFromFile(fpath string) (*Config, error) { + b, err := ioutil.ReadFile(fpath) + if err != nil { + return nil, err + } + + yc := &YamlConfig{} + + err = yaml.Unmarshal(b, yc) + if err != nil { + return nil, err + } + + cfg := &Config{ + Endpoints: yc.Endpoints, + DialTimeout: yc.DialTimeout, + } + + if yc.InsecureTransport { + cfg.TLS = nil + return cfg, nil + } + + var ( + cert *tls.Certificate + cp *x509.CertPool + ) + + if yc.Certfile != "" && yc.Keyfile != "" { + cert, err = tlsutil.NewCert(yc.Certfile, yc.Keyfile, nil) + if err != nil { + return nil, err + } + } + + if yc.CAfile != "" { + cp, err = tlsutil.NewCertPool([]string{yc.CAfile}) + if err != nil { + return nil, err + } + } + + tlscfg := &tls.Config{ + MinVersion: tls.VersionTLS10, + InsecureSkipVerify: yc.InsecureSkipTLSVerify, + RootCAs: cp, + } + if cert != nil { + tlscfg.Certificates = []tls.Certificate{*cert} + } + cfg.TLS = tlscfg + + return cfg, nil +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/doc.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/doc.go index abd340e588d..641dea3516e 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/doc.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/doc.go @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -// clientv3 is the official Go etcd client for v3. +// Package clientv3 implements the official Go etcd client for v3. // // Create client using `clientv3.New`: // // cli, err := clientv3.New(clientv3.Config{ -// Endpoints: []string{"localhost:12378", "localhost:22378", "localhost:32378"}, +// Endpoints: []string{"localhost:2379", "localhost:22379", "localhost:32379"}, // DialTimeout: 5 * time.Second, // }) // if err != nil { @@ -38,6 +38,9 @@ // } // // use the response // +// The Client has internal state (watchers and leases), so Clients should be reused instead of created as needed. +// Clients are safe for concurrent use by multiple goroutines. +// // etcd client returns 2 types of errors: // // 1. context error: canceled or deadline exceeded. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/kv.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/kv.go index a381026e478..04e33688b4c 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/kv.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/kv.go @@ -138,7 +138,7 @@ func (kv *kv) Do(ctx context.Context, op Op) (OpResponse, error) { // TODO: handle other ops case tRange: var resp *pb.RangeResponse - r := &pb.RangeRequest{Key: op.key, RangeEnd: op.end, Limit: op.limit, Revision: op.rev} + r := &pb.RangeRequest{Key: op.key, RangeEnd: op.end, Limit: op.limit, Revision: op.rev, Serializable: op.serializable} if op.sort != nil { r.SortOrder = pb.RangeRequest_SortOrder(op.sort.Order) r.SortTarget = pb.RangeRequest_SortTarget(op.sort.Target) @@ -183,14 +183,18 @@ func (kv *kv) Do(ctx context.Context, op Op) (OpResponse, error) { } func (kv *kv) switchRemote(prevErr error) error { + // Usually it's a bad idea to lock on network i/o but here it's OK + // since the link is down and new requests can't be processed anyway. + // Likewise, if connecting stalls, closing the Client can break the + // lock via context cancelation. + kv.mu.Lock() + defer kv.mu.Unlock() + newConn, err := kv.c.retryConnection(kv.conn, prevErr) if err != nil { return err } - kv.mu.Lock() - defer kv.mu.Unlock() - kv.conn = newConn kv.remote = pb.NewKVClient(kv.conn) return nil diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/lease.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/lease.go index e9a568f93a4..e719de6c737 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/lease.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/lease.go @@ -24,7 +24,7 @@ import ( ) type ( - LeaseCreateResponse pb.LeaseCreateResponse + LeaseGrantResponse pb.LeaseGrantResponse LeaseRevokeResponse pb.LeaseRevokeResponse LeaseKeepAliveResponse pb.LeaseKeepAliveResponse LeaseID int64 @@ -38,8 +38,8 @@ const ( ) type Lease interface { - // Create creates a new lease. - Create(ctx context.Context, ttl int64) (*LeaseCreateResponse, error) + // Grant creates a new lease. + Grant(ctx context.Context, ttl int64) (*LeaseGrantResponse, error) // Revoke revokes the given lease. Revoke(ctx context.Context, id LeaseID) (*LeaseRevokeResponse, error) @@ -103,16 +103,16 @@ func NewLease(c *Client) Lease { return l } -func (l *lessor) Create(ctx context.Context, ttl int64) (*LeaseCreateResponse, error) { +func (l *lessor) Grant(ctx context.Context, ttl int64) (*LeaseGrantResponse, error) { cctx, cancel := context.WithCancel(ctx) done := cancelWhenStop(cancel, l.stopCtx.Done()) defer close(done) for { - r := &pb.LeaseCreateRequest{TTL: ttl} - resp, err := l.getRemote().LeaseCreate(cctx, r) + r := &pb.LeaseGrantRequest{TTL: ttl} + resp, err := l.getRemote().LeaseGrant(cctx, r) if err == nil { - return (*LeaseCreateResponse)(resp), nil + return (*LeaseGrantResponse)(resp), nil } if isHalted(cctx, err) { return nil, err diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/logger.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/logger.go new file mode 100644 index 00000000000..47a31ff05eb --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/logger.go @@ -0,0 +1,64 @@ +// Copyright 2016 CoreOS, 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. + +package clientv3 + +import ( + "log" + "os" + "sync" + + "google.golang.org/grpc/grpclog" +) + +type Logger grpclog.Logger + +var ( + logger settableLogger +) + +type settableLogger struct { + l grpclog.Logger + mu sync.RWMutex +} + +func init() { + // use go's standard logger by default like grpc + logger.mu.Lock() + logger.l = log.New(os.Stderr, "", log.LstdFlags) + grpclog.SetLogger(&logger) + logger.mu.Unlock() +} + +func (s *settableLogger) Set(l Logger) { + s.mu.Lock() + logger.l = l + s.mu.Unlock() +} + +func (s *settableLogger) Get() Logger { + s.mu.RLock() + l := logger.l + s.mu.RUnlock() + return l +} + +// implement the grpclog.Logger interface + +func (s *settableLogger) Fatal(args ...interface{}) { s.Get().Fatal(args...) } +func (s *settableLogger) Fatalf(format string, args ...interface{}) { s.Get().Fatalf(format, args...) } +func (s *settableLogger) Fatalln(args ...interface{}) { s.Get().Fatalln(args...) } +func (s *settableLogger) Print(args ...interface{}) { s.Get().Print(args...) } +func (s *settableLogger) Printf(format string, args ...interface{}) { s.Get().Printf(format, args...) } +func (s *settableLogger) Println(args ...interface{}) { s.Get().Println(args...) } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/maintenance.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/maintenance.go index 158293ebd6f..f200cc3b580 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/maintenance.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/maintenance.go @@ -15,15 +15,27 @@ package clientv3 import ( + "sync" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "golang.org/x/net/context" + "google.golang.org/grpc" ) type ( DefragmentResponse pb.DefragmentResponse + AlarmResponse pb.AlarmResponse + AlarmMember pb.AlarmMember + StatusResponse pb.StatusResponse ) type Maintenance interface { + // AlarmList gets all active alarms. + AlarmList(ctx context.Context) (*AlarmResponse, error) + + // AlarmDisarm disarms a given alarm. + AlarmDisarm(ctx context.Context, m *AlarmMember) (*AlarmResponse, error) + // Defragment defragments storage backend of the etcd member with given endpoint. // Defragment is only needed when deleting a large number of keys and want to reclaim // the resources. @@ -32,10 +44,79 @@ type Maintenance interface { // To defragment multiple members in the cluster, user need to call defragment multiple // times with different endpoints. Defragment(ctx context.Context, endpoint string) (*DefragmentResponse, error) + + // Status gets the status of the member. + Status(ctx context.Context, endpoint string) (*StatusResponse, error) } type maintenance struct { c *Client + + mu sync.Mutex + conn *grpc.ClientConn // conn in-use + remote pb.MaintenanceClient +} + +func NewMaintenance(c *Client) Maintenance { + conn := c.ActiveConnection() + return &maintenance{ + c: c, + conn: conn, + remote: pb.NewMaintenanceClient(conn), + } +} + +func (m *maintenance) AlarmList(ctx context.Context) (*AlarmResponse, error) { + req := &pb.AlarmRequest{ + Action: pb.AlarmRequest_GET, + MemberID: 0, // all + Alarm: pb.AlarmType_NONE, // all + } + for { + resp, err := m.getRemote().Alarm(ctx, req) + if err == nil { + return (*AlarmResponse)(resp), nil + } + if isHalted(ctx, err) { + return nil, err + } + if err = m.switchRemote(err); err != nil { + return nil, err + } + } +} + +func (m *maintenance) AlarmDisarm(ctx context.Context, am *AlarmMember) (*AlarmResponse, error) { + req := &pb.AlarmRequest{ + Action: pb.AlarmRequest_DEACTIVATE, + MemberID: am.MemberID, + Alarm: am.Alarm, + } + + if req.MemberID == 0 && req.Alarm == pb.AlarmType_NONE { + ar, err := m.AlarmList(ctx) + if err != nil { + return nil, err + } + ret := AlarmResponse{} + for _, am := range ar.Alarms { + dresp, derr := m.AlarmDisarm(ctx, (*AlarmMember)(am)) + if derr != nil { + return nil, derr + } + ret.Alarms = append(ret.Alarms, dresp.Alarms...) + } + return &ret, nil + } + + resp, err := m.getRemote().Alarm(ctx, req) + if err == nil { + return (*AlarmResponse)(resp), nil + } + if !isHalted(ctx, err) { + go m.switchRemote(err) + } + return nil, err } func (m *maintenance) Defragment(ctx context.Context, endpoint string) (*DefragmentResponse, error) { @@ -50,3 +131,34 @@ func (m *maintenance) Defragment(ctx context.Context, endpoint string) (*Defragm } return (*DefragmentResponse)(resp), nil } + +func (m *maintenance) Status(ctx context.Context, endpoint string) (*StatusResponse, error) { + conn, err := m.c.Dial(endpoint) + if err != nil { + return nil, err + } + remote := pb.NewMaintenanceClient(conn) + resp, err := remote.Status(ctx, &pb.StatusRequest{}) + if err != nil { + return nil, err + } + return (*StatusResponse)(resp), nil +} + +func (m *maintenance) getRemote() pb.MaintenanceClient { + m.mu.Lock() + defer m.mu.Unlock() + return m.remote +} + +func (m *maintenance) switchRemote(prevErr error) error { + m.mu.Lock() + defer m.mu.Unlock() + newConn, err := m.c.retryConnection(m.conn, prevErr) + if err != nil { + return err + } + m.conn = newConn + m.remote = pb.NewMaintenanceClient(m.conn) + return nil +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/mirror/syncer.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/mirror/syncer.go index d1911800193..cb2cf64a2b6 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/mirror/syncer.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/mirror/syncer.go @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package mirror implements etcd mirroring operations. package mirror import ( diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/op.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/op.go index 0af89dfc20e..fb29f47c02e 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/op.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/op.go @@ -56,7 +56,7 @@ type Op struct { func (op Op) toRequestUnion() *pb.RequestUnion { switch op.t { case tRange: - r := &pb.RangeRequest{Key: op.key, RangeEnd: op.end, Limit: op.limit, Revision: op.rev} + r := &pb.RangeRequest{Key: op.key, RangeEnd: op.end, Limit: op.limit, Revision: op.rev, Serializable: op.serializable} if op.sort != nil { r.SortOrder = pb.RangeRequest_SortOrder(op.sort.Order) r.SortTarget = pb.RangeRequest_SortTarget(op.sort.Target) @@ -95,7 +95,7 @@ func OpDelete(key string, opts ...OpOption) Op { panic("unexpected revision in delete") case ret.sort != nil: panic("unexpected sort in delete") - case ret.serializable != false: + case ret.serializable: panic("unexpected serializable in delete") } return ret @@ -113,7 +113,7 @@ func OpPut(key, val string, opts ...OpOption) Op { panic("unexpected revision in put") case ret.sort != nil: panic("unexpected sort in put") - case ret.serializable != false: + case ret.serializable: panic("unexpected serializable in delete") } return ret @@ -129,7 +129,7 @@ func opWatch(key string, opts ...OpOption) Op { panic("unexpected limit in watch") case ret.sort != nil: panic("unexpected sort in watch") - case ret.serializable != false: + case ret.serializable: panic("unexpected serializable in watch") } return ret @@ -209,10 +209,10 @@ func WithSerializable() OpOption { } // WithFirstCreate gets the key with the oldest creation revision in the request range. -func WithFirstCreate() []OpOption { return withTop(SortByCreatedRev, SortAscend) } +func WithFirstCreate() []OpOption { return withTop(SortByCreateRevision, SortAscend) } // WithLastCreate gets the key with the latest creation revision in the request range. -func WithLastCreate() []OpOption { return withTop(SortByCreatedRev, SortDescend) } +func WithLastCreate() []OpOption { return withTop(SortByCreateRevision, SortDescend) } // WithFirstKey gets the lexically first key in the request range. func WithFirstKey() []OpOption { return withTop(SortByKey, SortAscend) } @@ -221,10 +221,10 @@ func WithFirstKey() []OpOption { return withTop(SortByKey, SortAscend) } func WithLastKey() []OpOption { return withTop(SortByKey, SortDescend) } // WithFirstRev gets the key with the oldest modification revision in the request range. -func WithFirstRev() []OpOption { return withTop(SortByModifiedRev, SortAscend) } +func WithFirstRev() []OpOption { return withTop(SortByModRevision, SortAscend) } // WithLastRev gets the key with the latest modification revision in the request range. -func WithLastRev() []OpOption { return withTop(SortByModifiedRev, SortDescend) } +func WithLastRev() []OpOption { return withTop(SortByModRevision, SortDescend) } // withTop gets the first key over the get's prefix given a sort order func withTop(target SortTarget, order SortOrder) []OpOption { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/sort.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/sort.go index e5ba1e95511..06a23be7bb2 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/sort.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/sort.go @@ -26,8 +26,8 @@ const ( const ( SortByKey SortTarget = iota SortByVersion - SortByCreatedRev - SortByModifiedRev + SortByCreateRevision + SortByModRevision SortByValue ) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/watch.go b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/watch.go index 17b1bc9d1d3..f9bdaff547b 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/watch.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/clientv3/watch.go @@ -25,6 +25,13 @@ import ( "google.golang.org/grpc" ) +const ( + EventTypeDelete = storagepb.DELETE + EventTypePut = storagepb.PUT +) + +type Event storagepb.Event + type WatchChan <-chan WatchResponse type Watcher interface { @@ -41,7 +48,7 @@ type Watcher interface { type WatchResponse struct { Header pb.ResponseHeader - Events []*storagepb.Event + Events []*Event // CompactRevision is the minimum revision the watcher may receive. CompactRevision int64 @@ -52,6 +59,16 @@ type WatchResponse struct { Canceled bool } +// IsCreate returns true if the event tells that the key is newly created. +func (e *Event) IsCreate() bool { + return e.Type == EventTypePut && e.Kv.CreateRevision == e.Kv.ModRevision +} + +// IsModify returns true if the event tells that a new value is put on existing key. +func (e *Event) IsModify() bool { + return e.Type == EventTypePut && e.Kv.CreateRevision != e.Kv.ModRevision +} + // Err is the error value if this WatchResponse holds an error. func (wr *WatchResponse) Err() error { if wr.CompactRevision != 0 { @@ -240,11 +257,11 @@ func (w *watcher) addStream(resp *pb.WatchResponse, pendingReq *watchRequest) { w.streams[ws.id] = ws w.mu.Unlock() - // send messages to subscriber - go w.serveStream(ws) - // pass back the subscriber channel for the watcher pendingReq.retc <- ret + + // send messages to subscriber + go w.serveStream(ws) } // closeStream closes the watcher resources and removes it @@ -352,10 +369,14 @@ func (w *watcher) dispatchEvent(pbresp *pb.WatchResponse) bool { w.mu.RLock() defer w.mu.RUnlock() ws, ok := w.streams[pbresp.WatchId] + events := make([]*Event, len(pbresp.Events)) + for i, ev := range pbresp.Events { + events[i] = (*Event)(ev) + } if ok { wr := &WatchResponse{ Header: *pbresp.Header, - Events: pbresp.Events, + Events: events, CompactRevision: pbresp.CompactRevision, Canceled: pbresp.Canceled} ws.recvc <- wr @@ -436,11 +457,15 @@ func (w *watcher) serveStream(ws *watcherStream) { // TODO don't keep buffering if subscriber stops reading wrs = append(wrs, wr) case resumeRev := <-ws.resumec: + wrs = nil + resuming = true + if resumeRev == -1 { + // pause serving stream while resume gets set up + break + } if resumeRev != ws.lastRev { panic("unexpected resume revision") } - wrs = nil - resuming = true case <-w.donec: closing = true case <-ws.initReq.ctx.Done(): @@ -502,6 +527,9 @@ func (w *watcher) resumeWatchers(wc pb.Watch_WatchClient) error { w.mu.RUnlock() for _, ws := range streams { + // pause serveStream + ws.resumec <- -1 + // reconstruct watcher from initial request if ws.lastRev != 0 { ws.initReq.rev = ws.lastRev @@ -514,7 +542,7 @@ func (w *watcher) resumeWatchers(wc pb.Watch_WatchClient) error { resp, err := wc.Recv() if err != nil { return err - } else if len(resp.Events) != 0 || resp.Created != true { + } else if len(resp.Events) != 0 || !resp.Created { return fmt.Errorf("watcher: unexpected response (%+v)", resp) } @@ -525,6 +553,7 @@ func (w *watcher) resumeWatchers(wc pb.Watch_WatchClient) error { w.streams[ws.id] = ws w.mu.Unlock() + // unpause serveStream ws.resumec <- ws.lastRev } return nil diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/akrennmair/gopcap/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/akrennmair/gopcap/LICENSE new file mode 100644 index 00000000000..385fac9f26d --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/akrennmair/gopcap/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009-2011 Andreas Krennmair. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Andreas Krennmair nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/bgentry/speakeasy/LICENSE_WINDOWS b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/bgentry/speakeasy/LICENSE_WINDOWS new file mode 100644 index 00000000000..ff177f61243 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/bgentry/speakeasy/LICENSE_WINDOWS @@ -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 [2013] [the CloudFoundry Authors] + +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. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/boltdb/bolt/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/boltdb/bolt/LICENSE new file mode 100644 index 00000000000..004e77fe5d2 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/boltdb/bolt/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Ben Johnson + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/cockroachdb/cmux/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/cockroachdb/cmux/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/cockroachdb/cmux/LICENSE @@ -0,0 +1,202 @@ + + 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. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/codegangsta/cli/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/codegangsta/cli/LICENSE new file mode 100644 index 00000000000..5515ccfb716 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/codegangsta/cli/LICENSE @@ -0,0 +1,21 @@ +Copyright (C) 2013 Jeremy Saenz +All Rights Reserved. + +MIT LICENSE + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/coreos/go-semver/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/coreos/go-semver/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/coreos/go-semver/LICENSE @@ -0,0 +1,202 @@ + + 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. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/coreos/go-systemd/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/coreos/go-systemd/LICENSE new file mode 100644 index 00000000000..37ec93a14fd --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/coreos/go-systemd/LICENSE @@ -0,0 +1,191 @@ +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: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +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 +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. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/coreos/pkg/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/coreos/pkg/LICENSE new file mode 100644 index 00000000000..e06d2081865 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/coreos/pkg/LICENSE @@ -0,0 +1,202 @@ +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. + diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/coreos/pkg/NOTICE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/coreos/pkg/NOTICE new file mode 100644 index 00000000000..b39ddfa5cbd --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/coreos/pkg/NOTICE @@ -0,0 +1,5 @@ +CoreOS Project +Copyright 2014 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). diff --git a/Godeps/_workspace_aux/src/github.com/stretchr/objx/LICENSE.md b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/cpuguy83/go-md2man/LICENSE.md similarity index 93% rename from Godeps/_workspace_aux/src/github.com/stretchr/objx/LICENSE.md rename to Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/cpuguy83/go-md2man/LICENSE.md index 2199945813c..1cade6cef6a 100644 --- a/Godeps/_workspace_aux/src/github.com/stretchr/objx/LICENSE.md +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/cpuguy83/go-md2man/LICENSE.md @@ -1,8 +1,6 @@ -objx - by Mat Ryer and Tyler Bunnell - The MIT License (MIT) -Copyright (c) 2014 Stretchr, Inc. +Copyright (c) 2014 Brian Goff Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/ghodss/yaml/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/ghodss/yaml/LICENSE new file mode 100644 index 00000000000..7805d36de73 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/ghodss/yaml/LICENSE @@ -0,0 +1,50 @@ +The MIT License (MIT) + +Copyright (c) 2014 Sam Ghods + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/gogo/protobuf/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/gogo/protobuf/LICENSE new file mode 100644 index 00000000000..335e38e19b9 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/gogo/protobuf/LICENSE @@ -0,0 +1,36 @@ +Extensions for Protocol Buffers to create more go like structures. + +Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved. +http://github.com/gogo/protobuf/gogoproto + +Go support for Protocol Buffers - Google's data interchange format + +Copyright 2010 The Go Authors. All rights reserved. +https://github.com/golang/protobuf + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/golang/glog/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/golang/glog/LICENSE new file mode 100644 index 00000000000..37ec93a14fd --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/golang/glog/LICENSE @@ -0,0 +1,191 @@ +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: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +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 +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. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/golang/protobuf/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/golang/protobuf/LICENSE new file mode 100644 index 00000000000..1b1b1921efa --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/golang/protobuf/LICENSE @@ -0,0 +1,31 @@ +Go support for Protocol Buffers - Google's data interchange format + +Copyright 2010 The Go Authors. All rights reserved. +https://github.com/golang/protobuf + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/google/btree/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/google/btree/LICENSE new file mode 100644 index 00000000000..d6456956733 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/google/btree/LICENSE @@ -0,0 +1,202 @@ + + 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. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/inconshreveable/mousetrap/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/inconshreveable/mousetrap/LICENSE new file mode 100644 index 00000000000..5f0d1fb6a7b --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/inconshreveable/mousetrap/LICENSE @@ -0,0 +1,13 @@ +Copyright 2014 Alan Shreve + +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. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/jonboulle/clockwork/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/jonboulle/clockwork/LICENSE new file mode 100644 index 00000000000..5c304d1a4a7 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/jonboulle/clockwork/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. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/kballard/go-shellquote/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/kballard/go-shellquote/LICENSE new file mode 100644 index 00000000000..a6d77312e10 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/kballard/go-shellquote/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2014 Kevin Ballard + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/kr/pty/License b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/kr/pty/License new file mode 100644 index 00000000000..6b7558b6b42 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/kr/pty/License @@ -0,0 +1,23 @@ +Copyright (c) 2011 Keith Rarick + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall +be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/matttproud/golang_protobuf_extensions/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/matttproud/golang_protobuf_extensions/LICENSE new file mode 100644 index 00000000000..13f15dfce0c --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/matttproud/golang_protobuf_extensions/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 2013 Matt T. Proud + + 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. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/olekukonko/tablewriter/LICENCE.md b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/olekukonko/tablewriter/LICENCE.md new file mode 100644 index 00000000000..1fd8484253f --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/olekukonko/tablewriter/LICENCE.md @@ -0,0 +1,19 @@ +Copyright (C) 2014 by Oleku Konko + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/Godeps/_workspace_aux/src/github.com/prometheus/common/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/client_golang/LICENSE similarity index 100% rename from Godeps/_workspace_aux/src/github.com/prometheus/common/LICENSE rename to Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/client_golang/LICENSE diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/client_golang/NOTICE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/client_golang/NOTICE new file mode 100644 index 00000000000..37e4a7d410e --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/client_golang/NOTICE @@ -0,0 +1,28 @@ +Prometheus instrumentation library for Go applications +Copyright 2012-2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). + + +The following components are included in this product: + +goautoneg +http://bitbucket.org/ww/goautoneg +Copyright 2011, Open Knowledge Foundation Ltd. +See README.txt for license details. + +perks - a fork of https://github.com/bmizerany/perks +https://github.com/beorn7/perks +Copyright 2013-2015 Blake Mizerany, Björn Rabenstein +See https://github.com/beorn7/perks/blob/master/README.md for license details. + +Go support for Protocol Buffers - Google's data interchange format +http://github.com/golang/protobuf/ +Copyright 2010 The Go Authors +See source code for license details. + +Support for streaming Protocol Buffer messages for the Go language (golang). +https://github.com/matttproud/golang_protobuf_extensions +Copyright 2013 Matt T. Proud +Licensed under the Apache License, Version 2.0 diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/client_model/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/client_model/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/client_model/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. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/client_model/NOTICE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/client_model/NOTICE new file mode 100644 index 00000000000..20110e410e5 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/client_model/NOTICE @@ -0,0 +1,5 @@ +Data model artifacts for Prometheus. +Copyright 2012-2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/common/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/common/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/common/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. diff --git a/Godeps/_workspace_aux/src/github.com/prometheus/common/NOTICE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/common/NOTICE similarity index 100% rename from Godeps/_workspace_aux/src/github.com/prometheus/common/NOTICE rename to Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/common/NOTICE diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/procfs/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/procfs/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/procfs/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. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/procfs/NOTICE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/procfs/NOTICE new file mode 100644 index 00000000000..53c5e9aa111 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/prometheus/procfs/NOTICE @@ -0,0 +1,7 @@ +procfs provides functions to retrieve system, kernel and process +metrics from the pseudo-filesystem proc. + +Copyright 2014-2015 The Prometheus Authors + +This product includes software developed at +SoundCloud Ltd. (http://soundcloud.com/). diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/russross/blackfriday/LICENSE.txt b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/russross/blackfriday/LICENSE.txt new file mode 100644 index 00000000000..2885af3602d --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/russross/blackfriday/LICENSE.txt @@ -0,0 +1,29 @@ +Blackfriday is distributed under the Simplified BSD License: + +> Copyright © 2011 Russ Ross +> All rights reserved. +> +> Redistribution and use in source and binary forms, with or without +> modification, are permitted provided that the following conditions +> are met: +> +> 1. Redistributions of source code must retain the above copyright +> notice, this list of conditions and the following disclaimer. +> +> 2. Redistributions in binary form must reproduce the above +> copyright notice, this list of conditions and the following +> disclaimer in the documentation and/or other materials provided with +> the distribution. +> +> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +> "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +> LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +> FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +> COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +> INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +> BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +> LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +> LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +> ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +> POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace_aux/src/github.com/shurcooL/sanitized_anchor_name/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/shurcooL/sanitized_anchor_name/LICENSE similarity index 100% rename from Godeps/_workspace_aux/src/github.com/shurcooL/sanitized_anchor_name/LICENSE rename to Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/shurcooL/sanitized_anchor_name/LICENSE diff --git a/Godeps/_workspace_aux/src/github.com/garyburd/redigo/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/spf13/cobra/LICENSE.txt similarity index 99% rename from Godeps/_workspace_aux/src/github.com/garyburd/redigo/LICENSE rename to Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/spf13/cobra/LICENSE.txt index 67db8588217..298f0e2665e 100644 --- a/Godeps/_workspace_aux/src/github.com/garyburd/redigo/LICENSE +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/spf13/cobra/LICENSE.txt @@ -1,5 +1,4 @@ - - Apache License + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/spf13/pflag/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/spf13/pflag/LICENSE new file mode 100644 index 00000000000..63ed1cfea1f --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/spf13/pflag/LICENSE @@ -0,0 +1,28 @@ +Copyright (c) 2012 Alex Ogier. All rights reserved. +Copyright (c) 2012 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace_aux/src/github.com/beorn7/perks/README.md b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/stretchr/testify/LICENCE.txt similarity index 53% rename from Godeps/_workspace_aux/src/github.com/beorn7/perks/README.md rename to Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/stretchr/testify/LICENCE.txt index fc05777701a..a009ba467ce 100644 --- a/Godeps/_workspace_aux/src/github.com/beorn7/perks/README.md +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/stretchr/testify/LICENCE.txt @@ -1,31 +1,9 @@ -# Perks for Go (golang.org) +Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell -Perks contains the Go package quantile that computes approximate quantiles over -an unbounded data stream within low memory and CPU bounds. - -For more information and examples, see: -http://godoc.org/github.com/bmizerany/perks - -A very special thank you and shout out to Graham Cormode (Rutgers University), -Flip Korn (AT&T Labs–Research), S. Muthukrishnan (Rutgers University), and -Divesh Srivastava (AT&T Labs–Research) for their research and publication of -[Effective Computation of Biased Quantiles over Data Streams](http://www.cs.rutgers.edu/~muthu/bquant.pdf) - -Thank you, also: -* Armon Dadgar (@armon) -* Andrew Gerrand (@nf) -* Brad Fitzpatrick (@bradfitz) -* Keith Rarick (@kr) - -FAQ: - -Q: Why not move the quantile package into the project root? -A: I want to add more packages to perks later. - -Copyright (C) 2013 Blake Mizerany +Please consider promoting this project if you find it useful. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/ugorji/go/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/ugorji/go/LICENSE new file mode 100644 index 00000000000..95a0f0541cd --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/ugorji/go/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2012-2015 Ugorji Nwoke. +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/xiang90/probing/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/xiang90/probing/LICENSE new file mode 100644 index 00000000000..cde8b8b05f5 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/github.com/xiang90/probing/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Xiang Li + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/crypto/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/crypto/LICENSE new file mode 100644 index 00000000000..6a66aea5eaf --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/crypto/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/crypto/PATENTS b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/crypto/PATENTS new file mode 100644 index 00000000000..733099041f8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/crypto/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google 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, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/net/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/net/LICENSE new file mode 100644 index 00000000000..6a66aea5eaf --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/net/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/net/PATENTS b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/net/PATENTS new file mode 100644 index 00000000000..733099041f8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/net/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google 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, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/sys/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/sys/LICENSE new file mode 100644 index 00000000000..6a66aea5eaf --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/sys/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/sys/PATENTS b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/sys/PATENTS new file mode 100644 index 00000000000..733099041f8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/golang.org/x/sys/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google 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, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/google.golang.org/grpc/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/google.golang.org/grpc/LICENSE new file mode 100644 index 00000000000..f4988b45079 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/google.golang.org/grpc/LICENSE @@ -0,0 +1,28 @@ +Copyright 2014, Google Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/google.golang.org/grpc/PATENTS b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/google.golang.org/grpc/PATENTS new file mode 100644 index 00000000000..619f9dbfe63 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/google.golang.org/grpc/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the GRPC project. + +Google 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, +transfer and otherwise run, modify and propagate the contents of this +implementation of GRPC, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of GRPC. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of GRPC or any code incorporated within this +implementation of GRPC constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of GRPC +shall terminate as of the date such litigation is filed. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/gopkg.in/cheggaaa/pb.v1/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/gopkg.in/cheggaaa/pb.v1/LICENSE new file mode 100644 index 00000000000..51197033392 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/gopkg.in/cheggaaa/pb.v1/LICENSE @@ -0,0 +1,12 @@ +Copyright (c) 2012-2015, Sergey Cherepanov +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/gopkg.in/yaml.v2/LICENSE b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/gopkg.in/yaml.v2/LICENSE new file mode 100644 index 00000000000..a68e67f01b0 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/gopkg.in/yaml.v2/LICENSE @@ -0,0 +1,188 @@ + +Copyright (c) 2011-2014 - Canonical Inc. + +This software is licensed under the LGPLv3, included below. + +As a special exception to the GNU Lesser General Public License version 3 +("LGPL3"), the copyright holders of this Library give you permission to +convey to a third party a Combined Work that links statically or dynamically +to this Library without providing any Minimal Corresponding Source or +Minimal Application Code as set out in 4d or providing the installation +information set out in section 4e, provided that you comply with the other +provisions of LGPL3 and provided that you meet, for the Application the +terms and conditions of the license(s) which apply to the Application. + +Except as stated in this special exception, the provisions of LGPL3 will +continue to comply in full to this Library. If you modify this Library, you +may apply this exception to your version of this Library, but you are not +obliged to do so. If you do not wish to do so, delete this exception +statement from your version. This exception does not (and cannot) modify any +license terms which apply to the Application, with which you must still +comply. + + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/gopkg.in/yaml.v2/LICENSE.libyaml b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/gopkg.in/yaml.v2/LICENSE.libyaml new file mode 100644 index 00000000000..8da58fbf6f8 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/cmd/vendor/gopkg.in/yaml.v2/LICENSE.libyaml @@ -0,0 +1,31 @@ +The following files were ported to Go from C files of libyaml, and thus +are still covered by their original copyright and license: + + apic.go + emitterc.go + parserc.go + readerc.go + scannerc.go + writerc.go + yamlh.go + yamlprivateh.go + +Copyright (c) 2006 Kirill Simonov + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/error/error.go b/Godeps/_workspace/src/github.com/coreos/etcd/error/error.go index 6304ad85115..c5cf8ffb482 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/error/error.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/error/error.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// error package describes errors in etcd project. When any change happens, +// Package error describes errors in etcd project. When any change happens, // Documentation/errorcode.md needs to be updated correspondingly. package error diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/cluster.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/cluster.go new file mode 100644 index 00000000000..c21eccba316 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/cluster.go @@ -0,0 +1,41 @@ +// Copyright 2016 CoreOS, 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. + +package api + +import ( + "github.com/coreos/etcd/etcdserver/membership" + "github.com/coreos/etcd/pkg/types" + + "github.com/coreos/go-semver/semver" +) + +// Cluster is an interface representing a collection of members in one etcd cluster. +type Cluster interface { + // ID returns the cluster ID + ID() types.ID + // ClientURLs returns an aggregate set of all URLs on which this + // cluster is listening for client requests + ClientURLs() []string + // Members returns a slice of members sorted by their ID + Members() []*membership.Member + // Member retrieves a particular member based on ID, or nil if the + // member does not exist in the cluster + Member(id types.ID) *membership.Member + // IsIDRemoved checks whether the given ID has been removed from this + // cluster at some point in the past + IsIDRemoved(id types.ID) bool + // Version is the cluster-wide minimum major.minor version. + Version() *semver.Version +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/capability.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/capability.go similarity index 95% rename from Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/capability.go rename to Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/capability.go index cc99cf718dd..40477cac09a 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/capability.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/capability.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package etcdhttp +package v2http import ( "fmt" @@ -21,7 +21,7 @@ import ( "time" "github.com/coreos/etcd/etcdserver" - "github.com/coreos/etcd/etcdserver/etcdhttp/httptypes" + "github.com/coreos/etcd/etcdserver/api/v2http/httptypes" "github.com/coreos/go-semver/semver" ) @@ -63,6 +63,7 @@ func capabilityLoop(s *etcdserver.EtcdServer) { enableMapMu.Lock() enabledMap = capabilityMaps[pv.String()] enableMapMu.Unlock() + plog.Infof("enabled capabilities for version %s", pv) } select { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/client.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/client.go similarity index 96% rename from Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/client.go rename to Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/client.go index b3828abbd04..9f6e3b5e4de 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/client.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/client.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package etcdhttp +package v2http import ( "encoding/json" @@ -30,9 +30,11 @@ import ( etcdErr "github.com/coreos/etcd/error" "github.com/coreos/etcd/etcdserver" + "github.com/coreos/etcd/etcdserver/api" + "github.com/coreos/etcd/etcdserver/api/v2http/httptypes" "github.com/coreos/etcd/etcdserver/auth" - "github.com/coreos/etcd/etcdserver/etcdhttp/httptypes" "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/etcdserver/membership" "github.com/coreos/etcd/etcdserver/stats" "github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/raft" @@ -133,7 +135,7 @@ func NewClientHandler(server *etcdserver.EtcdServer, timeout time.Duration) http type keysHandler struct { sec auth.Store server etcdserver.Server - cluster etcdserver.Cluster + cluster api.Cluster timer etcdserver.RaftTimer timeout time.Duration } @@ -186,7 +188,7 @@ func (h *keysHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } type deprecatedMachinesHandler struct { - cluster etcdserver.Cluster + cluster api.Cluster } func (h *deprecatedMachinesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { @@ -200,7 +202,7 @@ func (h *deprecatedMachinesHandler) ServeHTTP(w http.ResponseWriter, r *http.Req type membersHandler struct { sec auth.Store server etcdserver.Server - cluster etcdserver.Cluster + cluster api.Cluster timeout time.Duration clock clockwork.Clock } @@ -247,10 +249,10 @@ func (h *membersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } now := h.clock.Now() - m := etcdserver.NewMember("", req.PeerURLs, "", &now) + m := membership.NewMember("", req.PeerURLs, "", &now) err := h.server.AddMember(ctx, *m) switch { - case err == etcdserver.ErrIDExists || err == etcdserver.ErrPeerURLexists: + case err == membership.ErrIDExists || err == membership.ErrPeerURLexists: writeError(w, r, httptypes.NewHTTPError(http.StatusConflict, err.Error())) return case err != nil: @@ -271,9 +273,9 @@ func (h *membersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } err := h.server.RemoveMember(ctx, uint64(id)) switch { - case err == etcdserver.ErrIDRemoved: + case err == membership.ErrIDRemoved: writeError(w, r, httptypes.NewHTTPError(http.StatusGone, fmt.Sprintf("Member permanently removed: %s", id))) - case err == etcdserver.ErrIDNotFound: + case err == membership.ErrIDNotFound: writeError(w, r, httptypes.NewHTTPError(http.StatusNotFound, fmt.Sprintf("No such member: %s", id))) case err != nil: plog.Errorf("error removing member %s (%v)", id, err) @@ -290,15 +292,15 @@ func (h *membersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if ok := unmarshalRequest(r, &req, w); !ok { return } - m := etcdserver.Member{ + m := membership.Member{ ID: id, - RaftAttributes: etcdserver.RaftAttributes{PeerURLs: req.PeerURLs.StringSlice()}, + RaftAttributes: membership.RaftAttributes{PeerURLs: req.PeerURLs.StringSlice()}, } err := h.server.UpdateMember(ctx, m) switch { - case err == etcdserver.ErrPeerURLexists: + case err == membership.ErrPeerURLexists: writeError(w, r, httptypes.NewHTTPError(http.StatusConflict, err.Error())) - case err == etcdserver.ErrIDNotFound: + case err == membership.ErrIDNotFound: writeError(w, r, httptypes.NewHTTPError(http.StatusNotFound, fmt.Sprintf("No such member: %s", id))) case err != nil: plog.Errorf("error updating member %s (%v)", m.ID, err) @@ -389,7 +391,7 @@ func healthHandler(server *etcdserver.EtcdServer) http.HandlerFunc { } } -func versionHandler(c etcdserver.Cluster, fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc { +func versionHandler(c api.Cluster, fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { v := c.Version() if v != nil { @@ -803,7 +805,7 @@ func trimPrefix(p, prefix string) (s string) { return } -func newMemberCollection(ms []*etcdserver.Member) *httptypes.MemberCollection { +func newMemberCollection(ms []*membership.Member) *httptypes.MemberCollection { c := httptypes.MemberCollection(make([]httptypes.Member, len(ms))) for i, m := range ms { @@ -813,7 +815,7 @@ func newMemberCollection(ms []*etcdserver.Member) *httptypes.MemberCollection { return &c } -func newMember(m *etcdserver.Member) httptypes.Member { +func newMember(m *membership.Member) httptypes.Member { tm := httptypes.Member{ ID: m.ID.String(), Name: m.Name, diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/client_auth.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/client_auth.go similarity index 98% rename from Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/client_auth.go rename to Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/client_auth.go index c5678ad00ac..83706f04fe9 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/client_auth.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/client_auth.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package etcdhttp +package v2http import ( "encoding/json" @@ -20,14 +20,14 @@ import ( "path" "strings" - "github.com/coreos/etcd/etcdserver" + "github.com/coreos/etcd/etcdserver/api" + "github.com/coreos/etcd/etcdserver/api/v2http/httptypes" "github.com/coreos/etcd/etcdserver/auth" - "github.com/coreos/etcd/etcdserver/etcdhttp/httptypes" ) type authHandler struct { sec auth.Store - cluster etcdserver.Cluster + cluster api.Cluster } func hasWriteRootAccess(sec auth.Store, r *http.Request) bool { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/doc.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/doc.go similarity index 87% rename from Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/doc.go rename to Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/doc.go index 84883aaf1dd..3b306ef076b 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/doc.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/doc.go @@ -12,5 +12,5 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package etcdhttp provides etcd client and server implementations. -package etcdhttp +// Package v2http provides etcd client and server implementations. +package v2http diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/http.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/http.go similarity index 91% rename from Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/http.go rename to Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/http.go index ea22bdfa18a..ba44d95142f 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/http.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/http.go @@ -12,10 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -package etcdhttp +package v2http import ( - "errors" "math" "net/http" "strings" @@ -23,8 +22,9 @@ import ( etcdErr "github.com/coreos/etcd/error" "github.com/coreos/etcd/etcdserver" + "github.com/coreos/etcd/etcdserver/api/v2http/httptypes" + "github.com/coreos/etcd/etcdserver/auth" - "github.com/coreos/etcd/etcdserver/etcdhttp/httptypes" "github.com/coreos/etcd/pkg/logutil" "github.com/coreos/pkg/capnslog" ) @@ -35,9 +35,8 @@ const ( ) var ( - plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdhttp") - mlog = logutil.NewMergeLogger(plog) - errClosed = errors.New("etcdhttp: client closed connection") + plog = capnslog.NewPackageLogger("github.com/coreos/etcd/etcdserver/api", "v2http") + mlog = logutil.NewMergeLogger(plog) ) // writeError logs and writes the given Error to the ResponseWriter diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/httptypes/errors.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/errors.go similarity index 97% rename from Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/httptypes/errors.go rename to Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/errors.go index 870c148f374..396dc59a31b 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/httptypes/errors.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/errors.go @@ -22,7 +22,7 @@ import ( ) var ( - plog = capnslog.NewPackageLogger("github.com/coreos/etcd/etcdserver/etcdhttp", "httptypes") + plog = capnslog.NewPackageLogger("github.com/coreos/etcd/etcdserver/api/v2http", "httptypes") ) type HTTPError struct { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/httptypes/member.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/member.go similarity index 100% rename from Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/httptypes/member.go rename to Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/httptypes/member.go diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/metrics.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/metrics.go similarity index 97% rename from Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/metrics.go rename to Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/metrics.go index 8e55500bd51..c6b4a5378be 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/metrics.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/metrics.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package etcdhttp +package v2http import ( "strconv" @@ -22,7 +22,7 @@ import ( etcdErr "github.com/coreos/etcd/error" "github.com/coreos/etcd/etcdserver" - "github.com/coreos/etcd/etcdserver/etcdhttp/httptypes" + "github.com/coreos/etcd/etcdserver/api/v2http/httptypes" "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/prometheus/client_golang/prometheus" ) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/peer.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/peer.go similarity index 91% rename from Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/peer.go rename to Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/peer.go index f142f708941..fe5857a3970 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdhttp/peer.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v2http/peer.go @@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -package etcdhttp +package v2http import ( "encoding/json" "net/http" "github.com/coreos/etcd/etcdserver" + "github.com/coreos/etcd/etcdserver/api" "github.com/coreos/etcd/lease/leasehttp" "github.com/coreos/etcd/rafthttp" ) @@ -37,7 +38,7 @@ func NewPeerHandler(s *etcdserver.EtcdServer) http.Handler { return newPeerHandler(s.Cluster(), s.RaftHandler(), lh) } -func newPeerHandler(cluster etcdserver.Cluster, raftHandler http.Handler, leaseHandler http.Handler) http.Handler { +func newPeerHandler(cluster api.Cluster, raftHandler http.Handler, leaseHandler http.Handler) http.Handler { mh := &peerMembersHandler{ cluster: cluster, } @@ -55,7 +56,7 @@ func newPeerHandler(cluster etcdserver.Cluster, raftHandler http.Handler, leaseH } type peerMembersHandler struct { - cluster etcdserver.Cluster + cluster api.Cluster } func (h *peerMembersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/auth.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/auth.go index 47d60f757d6..b07112f3fdb 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/auth.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/auth.go @@ -29,7 +29,11 @@ func NewAuthServer(s *etcdserver.EtcdServer) *AuthServer { } func (as *AuthServer) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) { - return as.authenticator.AuthEnable(ctx, r) + resp, err := as.authenticator.AuthEnable(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil } func (as *AuthServer) AuthDisable(ctx context.Context, r *pb.AuthDisableRequest) (*pb.AuthDisableResponse, error) { @@ -42,57 +46,69 @@ func (as *AuthServer) Authenticate(ctx context.Context, r *pb.AuthenticateReques return nil, nil } -func (as *AuthServer) RoleAdd(ctx context.Context, r *pb.RoleAddRequest) (*pb.RoleAddResponse, error) { +func (as *AuthServer) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) { + resp, err := as.authenticator.RoleAdd(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil +} + +func (as *AuthServer) RoleDelete(ctx context.Context, r *pb.AuthRoleDeleteRequest) (*pb.AuthRoleDeleteResponse, error) { plog.Info("not implemented yet") return nil, nil } -func (as *AuthServer) RoleDelete(ctx context.Context, r *pb.RoleDeleteRequest) (*pb.RoleDeleteResponse, error) { +func (as *AuthServer) RoleGet(ctx context.Context, r *pb.AuthRoleGetRequest) (*pb.AuthRoleGetResponse, error) { plog.Info("not implemented yet") return nil, nil } -func (as *AuthServer) RoleGet(ctx context.Context, r *pb.RoleGetRequest) (*pb.RoleGetResponse, error) { +func (as *AuthServer) RoleRevoke(ctx context.Context, r *pb.AuthRoleRevokeRequest) (*pb.AuthRoleRevokeResponse, error) { plog.Info("not implemented yet") return nil, nil } -func (as *AuthServer) RoleRevoke(ctx context.Context, r *pb.RoleRevokeRequest) (*pb.RoleRevokeResponse, error) { +func (as *AuthServer) RoleGrant(ctx context.Context, r *pb.AuthRoleGrantRequest) (*pb.AuthRoleGrantResponse, error) { plog.Info("not implemented yet") return nil, nil } -func (as *AuthServer) RoleGrant(ctx context.Context, r *pb.RoleGrantRequest) (*pb.RoleGrantResponse, error) { +func (as *AuthServer) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) { + resp, err := as.authenticator.UserAdd(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil +} + +func (as *AuthServer) UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) { + resp, err := as.authenticator.UserDelete(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil +} + +func (as *AuthServer) UserGet(ctx context.Context, r *pb.AuthUserGetRequest) (*pb.AuthUserGetResponse, error) { plog.Info("not implemented yet") return nil, nil } -func (as *AuthServer) UserAdd(ctx context.Context, r *pb.UserAddRequest) (*pb.UserAddResponse, error) { +func (as *AuthServer) UserGrant(ctx context.Context, r *pb.AuthUserGrantRequest) (*pb.AuthUserGrantResponse, error) { plog.Info("not implemented yet") return nil, nil } -func (as *AuthServer) UserDelete(ctx context.Context, r *pb.UserDeleteRequest) (*pb.UserDeleteResponse, error) { +func (as *AuthServer) UserRevoke(ctx context.Context, r *pb.AuthUserRevokeRequest) (*pb.AuthUserRevokeResponse, error) { plog.Info("not implemented yet") return nil, nil } -func (as *AuthServer) UserGet(ctx context.Context, r *pb.UserGetRequest) (*pb.UserGetResponse, error) { - plog.Info("not implemented yet") - return nil, nil -} - -func (as *AuthServer) UserGrant(ctx context.Context, r *pb.UserGrantRequest) (*pb.UserGrantResponse, error) { - plog.Info("not implemented yet") - return nil, nil -} - -func (as *AuthServer) UserRevoke(ctx context.Context, r *pb.UserRevokeRequest) (*pb.UserRevokeResponse, error) { - plog.Info("not implemented yet") - return nil, nil -} - -func (as *AuthServer) UserChangePassword(ctx context.Context, r *pb.UserChangePasswordRequest) (*pb.UserChangePasswordResponse, error) { - plog.Info("not implemented yet") - return nil, nil +func (as *AuthServer) UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) { + resp, err := as.authenticator.UserChangePassword(ctx, r) + if err != nil { + return nil, togRPCError(err) + } + return resp, nil } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go index c16d58ccfa6..7515363ab28 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/grpc.go @@ -11,32 +11,30 @@ // 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. + package v3rpc import ( + "crypto/tls" + "github.com/coreos/etcd/etcdserver" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "github.com/coreos/etcd/pkg/transport" "google.golang.org/grpc" "google.golang.org/grpc/credentials" ) -func Server(s *etcdserver.EtcdServer, tls *transport.TLSInfo) (*grpc.Server, error) { +func Server(s *etcdserver.EtcdServer, tls *tls.Config) *grpc.Server { var opts []grpc.ServerOption if tls != nil { - creds, err := credentials.NewServerTLSFromFile(tls.CertFile, tls.KeyFile) - if err != nil { - return nil, err - } - opts = append(opts, grpc.Creds(creds)) + opts = append(opts, grpc.Creds(credentials.NewTLS(tls))) } grpcServer := grpc.NewServer(opts...) - pb.RegisterKVServer(grpcServer, NewKVServer(s)) + pb.RegisterKVServer(grpcServer, NewQuotaKVServer(s)) pb.RegisterWatchServer(grpcServer, NewWatchServer(s)) - pb.RegisterLeaseServer(grpcServer, NewLeaseServer(s)) + pb.RegisterLeaseServer(grpcServer, NewQuotaLeaseServer(s)) pb.RegisterClusterServer(grpcServer, NewClusterServer(s)) pb.RegisterAuthServer(grpcServer, NewAuthServer(s)) pb.RegisterMaintenanceServer(grpcServer, NewMaintenanceServer(s)) - return grpcServer, nil + return grpcServer } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/header.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/header.go new file mode 100644 index 00000000000..dcb559219f7 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/header.go @@ -0,0 +1,43 @@ +// Copyright 2016 CoreOS, 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. + +package v3rpc + +import ( + "github.com/coreos/etcd/etcdserver" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" +) + +type header struct { + clusterID int64 + memberID int64 + raftTimer etcdserver.RaftTimer + rev func() int64 +} + +func newHeader(s *etcdserver.EtcdServer) header { + return header{ + clusterID: int64(s.Cluster().ID()), + memberID: int64(s.ID()), + raftTimer: s, + rev: func() int64 { return s.KV().Rev() }, + } +} + +// fill populates pb.ResponseHeader using etcdserver information +func (h *header) fill(rh *pb.ResponseHeader) { + rh.ClusterId = uint64(h.clusterID) + rh.MemberId = uint64(h.memberID) + rh.RaftTerm = h.raftTimer.Term() +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/key.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/key.go index e802744d943..c7f2f9d563d 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/key.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/key.go @@ -21,12 +21,8 @@ import ( "github.com/coreos/etcd/etcdserver" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" - "github.com/coreos/etcd/lease" - "github.com/coreos/etcd/storage" "github.com/coreos/pkg/capnslog" "golang.org/x/net/context" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" ) var ( @@ -38,20 +34,12 @@ var ( ) type kvServer struct { - clusterID int64 - memberID int64 - raftTimer etcdserver.RaftTimer - - kv etcdserver.RaftKV + hdr header + kv etcdserver.RaftKV } func NewKVServer(s *etcdserver.EtcdServer) pb.KVServer { - return &kvServer{ - clusterID: int64(s.Cluster().ID()), - memberID: int64(s.ID()), - raftTimer: s, - kv: s, - } + return &kvServer{hdr: newHeader(s), kv: s} } func (s *kvServer) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) { @@ -67,7 +55,7 @@ func (s *kvServer) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResp if resp.Header == nil { plog.Panic("unexpected nil resp.Header") } - s.fillInHeader(resp.Header) + s.hdr.fill(resp.Header) return resp, err } @@ -84,7 +72,7 @@ func (s *kvServer) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, if resp.Header == nil { plog.Panic("unexpected nil resp.Header") } - s.fillInHeader(resp.Header) + s.hdr.fill(resp.Header) return resp, err } @@ -101,7 +89,7 @@ func (s *kvServer) DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (* if resp.Header == nil { plog.Panic("unexpected nil resp.Header") } - s.fillInHeader(resp.Header) + s.hdr.fill(resp.Header) return resp, err } @@ -118,7 +106,7 @@ func (s *kvServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, if resp.Header == nil { plog.Panic("unexpected nil resp.Header") } - s.fillInHeader(resp.Header) + s.hdr.fill(resp.Header) return resp, err } @@ -131,26 +119,10 @@ func (s *kvServer) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.Co if resp.Header == nil { plog.Panic("unexpected nil resp.Header") } - s.fillInHeader(resp.Header) + s.hdr.fill(resp.Header) return resp, nil } -func (s *kvServer) Hash(ctx context.Context, r *pb.HashRequest) (*pb.HashResponse, error) { - resp, err := s.kv.Hash(ctx, r) - if err != nil { - return nil, togRPCError(err) - } - s.fillInHeader(resp.Header) - return resp, nil -} - -// fillInHeader populates pb.ResponseHeader from kvServer, except Revision. -func (s *kvServer) fillInHeader(h *pb.ResponseHeader) { - h.ClusterId = uint64(s.clusterID) - h.MemberId = uint64(s.memberID) - h.RaftTerm = s.raftTimer.Term() -} - func checkRangeRequest(r *pb.RangeRequest) error { if len(r.Key) == 0 { return rpctypes.ErrEmptyKey @@ -285,19 +257,3 @@ func checkRequestUnion(u *pb.RequestUnion) error { } return nil } - -func togRPCError(err error) error { - switch err { - case storage.ErrCompacted: - return rpctypes.ErrCompacted - case storage.ErrFutureRev: - return rpctypes.ErrFutureRev - case lease.ErrLeaseNotFound: - return rpctypes.ErrLeaseNotFound - // TODO: handle error from raft and timeout - case etcdserver.ErrRequestTooLarge: - return rpctypes.ErrRequestTooLarge - default: - return grpc.Errorf(codes.Internal, err.Error()) - } -} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/lease.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/lease.go index 373f8a0fe84..b21b1d1112c 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/lease.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/lease.go @@ -32,8 +32,8 @@ func NewLeaseServer(le etcdserver.Lessor) pb.LeaseServer { return &LeaseServer{le: le} } -func (ls *LeaseServer) LeaseCreate(ctx context.Context, cr *pb.LeaseCreateRequest) (*pb.LeaseCreateResponse, error) { - resp, err := ls.le.LeaseCreate(ctx, cr) +func (ls *LeaseServer) LeaseGrant(ctx context.Context, cr *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) { + resp, err := ls.le.LeaseGrant(ctx, cr) if err == lease.ErrLeaseExists { return nil, rpctypes.ErrLeaseExist } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/maintenance.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/maintenance.go index 6fa54113ad5..5dae0c45279 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/maintenance.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/maintenance.go @@ -18,6 +18,7 @@ import ( "github.com/coreos/etcd/etcdserver" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/storage/backend" + "github.com/coreos/etcd/version" "golang.org/x/net/context" ) @@ -25,12 +26,18 @@ type BackendGetter interface { Backend() backend.Backend } +type Alarmer interface { + Alarm(ctx context.Context, ar *pb.AlarmRequest) (*pb.AlarmResponse, error) +} + type maintenanceServer struct { - bg BackendGetter + bg BackendGetter + a Alarmer + hdr header } func NewMaintenanceServer(s *etcdserver.EtcdServer) pb.MaintenanceServer { - return &maintenanceServer{bg: s} + return &maintenanceServer{bg: s, a: s, hdr: newHeader(s)} } func (ms *maintenanceServer) Defragment(ctx context.Context, sr *pb.DefragmentRequest) (*pb.DefragmentResponse, error) { @@ -43,3 +50,23 @@ func (ms *maintenanceServer) Defragment(ctx context.Context, sr *pb.DefragmentRe plog.Noticef("finished defragmenting the storage backend") return &pb.DefragmentResponse{}, nil } + +func (ms *maintenanceServer) Hash(ctx context.Context, r *pb.HashRequest) (*pb.HashResponse, error) { + h, err := ms.bg.Backend().Hash() + if err != nil { + return nil, togRPCError(err) + } + resp := &pb.HashResponse{Header: &pb.ResponseHeader{Revision: ms.hdr.rev()}, Hash: h} + ms.hdr.fill(resp.Header) + return resp, nil +} + +func (ms *maintenanceServer) Alarm(ctx context.Context, ar *pb.AlarmRequest) (*pb.AlarmResponse, error) { + return ms.a.Alarm(ctx, ar) +} + +func (ms *maintenanceServer) Status(ctx context.Context, ar *pb.StatusRequest) (*pb.StatusResponse, error) { + resp := &pb.StatusResponse{Header: &pb.ResponseHeader{Revision: ms.hdr.rev()}, Version: version.Version} + ms.hdr.fill(resp.Header) + return resp, nil +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/member.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/member.go index d7813d37135..351a998c265 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/member.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/member.go @@ -18,8 +18,10 @@ import ( "time" "github.com/coreos/etcd/etcdserver" + "github.com/coreos/etcd/etcdserver/api" "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/etcdserver/membership" "github.com/coreos/etcd/pkg/types" "golang.org/x/net/context" "google.golang.org/grpc" @@ -27,7 +29,7 @@ import ( ) type ClusterServer struct { - cluster etcdserver.Cluster + cluster api.Cluster server etcdserver.Server raftTimer etcdserver.RaftTimer } @@ -47,12 +49,12 @@ func (cs *ClusterServer) MemberAdd(ctx context.Context, r *pb.MemberAddRequest) } now := time.Now() - m := etcdserver.NewMember("", urls, "", &now) + m := membership.NewMember("", urls, "", &now) err = cs.server.AddMember(ctx, *m) switch { - case err == etcdserver.ErrIDExists: + case err == membership.ErrIDExists: return nil, rpctypes.ErrMemberExist - case err == etcdserver.ErrPeerURLexists: + case err == membership.ErrPeerURLexists: return nil, rpctypes.ErrPeerURLExist case err != nil: return nil, grpc.Errorf(codes.Internal, err.Error()) @@ -67,9 +69,9 @@ func (cs *ClusterServer) MemberAdd(ctx context.Context, r *pb.MemberAddRequest) func (cs *ClusterServer) MemberRemove(ctx context.Context, r *pb.MemberRemoveRequest) (*pb.MemberRemoveResponse, error) { err := cs.server.RemoveMember(ctx, r.ID) switch { - case err == etcdserver.ErrIDRemoved: + case err == membership.ErrIDRemoved: fallthrough - case err == etcdserver.ErrIDNotFound: + case err == membership.ErrIDNotFound: return nil, rpctypes.ErrMemberNotFound case err != nil: return nil, grpc.Errorf(codes.Internal, err.Error()) @@ -79,15 +81,15 @@ func (cs *ClusterServer) MemberRemove(ctx context.Context, r *pb.MemberRemoveReq } func (cs *ClusterServer) MemberUpdate(ctx context.Context, r *pb.MemberUpdateRequest) (*pb.MemberUpdateResponse, error) { - m := etcdserver.Member{ + m := membership.Member{ ID: types.ID(r.ID), - RaftAttributes: etcdserver.RaftAttributes{PeerURLs: r.PeerURLs}, + RaftAttributes: membership.RaftAttributes{PeerURLs: r.PeerURLs}, } err := cs.server.UpdateMember(ctx, m) switch { - case err == etcdserver.ErrPeerURLexists: + case err == membership.ErrPeerURLexists: return nil, rpctypes.ErrPeerURLExist - case err == etcdserver.ErrIDNotFound: + case err == membership.ErrIDNotFound: return nil, rpctypes.ErrMemberNotFound case err != nil: return nil, grpc.Errorf(codes.Internal, err.Error()) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/quota.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/quota.go new file mode 100644 index 00000000000..aa7794f967a --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/quota.go @@ -0,0 +1,89 @@ +// Copyright 2016 CoreOS, 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. + +package v3rpc + +import ( + "github.com/coreos/etcd/etcdserver" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/pkg/types" + "golang.org/x/net/context" +) + +type quotaKVServer struct { + pb.KVServer + qa quotaAlarmer +} + +type quotaAlarmer struct { + q etcdserver.Quota + a Alarmer + id types.ID +} + +// check whether request satisfies the quota. If there is not enough space, +// ignore request and raise the free space alarm. +func (qa *quotaAlarmer) check(ctx context.Context, r interface{}) error { + if qa.q.Available(r) { + return nil + } + req := &pb.AlarmRequest{ + MemberID: uint64(qa.id), + Action: pb.AlarmRequest_ACTIVATE, + Alarm: pb.AlarmType_NOSPACE, + } + qa.a.Alarm(ctx, req) + return rpctypes.ErrNoSpace +} + +func NewQuotaKVServer(s *etcdserver.EtcdServer) pb.KVServer { + return "aKVServer{ + NewKVServer(s), + quotaAlarmer{etcdserver.NewBackendQuota(s), s, s.ID()}, + } +} + +func (s *quotaKVServer) Put(ctx context.Context, r *pb.PutRequest) (*pb.PutResponse, error) { + if err := s.qa.check(ctx, r); err != nil { + return nil, err + } + return s.KVServer.Put(ctx, r) +} + +func (s *quotaKVServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) { + if err := s.qa.check(ctx, r); err != nil { + return nil, err + } + return s.KVServer.Txn(ctx, r) +} + +type quotaLeaseServer struct { + pb.LeaseServer + qa quotaAlarmer +} + +func (s *quotaLeaseServer) LeaseGrant(ctx context.Context, cr *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) { + if err := s.qa.check(ctx, cr); err != nil { + return nil, err + } + return s.LeaseServer.LeaseGrant(ctx, cr) +} + +func NewQuotaLeaseServer(s *etcdserver.EtcdServer) pb.LeaseServer { + return "aLeaseServer{ + NewLeaseServer(s), + quotaAlarmer{etcdserver.NewBackendQuota(s), s, s.ID()}, + } +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/error.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/error.go index 3b95cc42295..5e174b4b3de 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/error.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes/error.go @@ -25,6 +25,7 @@ var ( ErrDuplicateKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: duplicate key given in txn request") ErrCompacted = grpc.Errorf(codes.OutOfRange, "etcdserver: storage: required revision has been compacted") ErrFutureRev = grpc.Errorf(codes.OutOfRange, "etcdserver: storage: required revision is a future revision") + ErrNoSpace = grpc.Errorf(codes.ResourceExhausted, "etcdserver: storage: database space exceeded") ErrLeaseNotFound = grpc.Errorf(codes.NotFound, "etcdserver: requested lease not found") ErrLeaseExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: lease already exists") @@ -35,4 +36,8 @@ var ( ErrMemberNotFound = grpc.Errorf(codes.NotFound, "etcdserver: member not found") ErrRequestTooLarge = grpc.Errorf(codes.InvalidArgument, "etcdserver: request is too large") + + ErrUserAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name already exists") + ErrUserNotFound = grpc.Errorf(codes.FailedPrecondition, "etcdserver: user name not found") + ErrRoleAlreadyExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role name already exists") ) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/util.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/util.go new file mode 100644 index 00000000000..982627a008b --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/util.go @@ -0,0 +1,49 @@ +// Copyright 2016 Nippon Telegraph and Telephone Corporation. +// +// 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. + +package v3rpc + +import ( + "github.com/coreos/etcd/auth" + "github.com/coreos/etcd/etcdserver" + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" + "github.com/coreos/etcd/lease" + "github.com/coreos/etcd/storage" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" +) + +func togRPCError(err error) error { + switch err { + case storage.ErrCompacted: + return rpctypes.ErrCompacted + case storage.ErrFutureRev: + return rpctypes.ErrFutureRev + case lease.ErrLeaseNotFound: + return rpctypes.ErrLeaseNotFound + // TODO: handle error from raft and timeout + case etcdserver.ErrRequestTooLarge: + return rpctypes.ErrRequestTooLarge + case etcdserver.ErrNoSpace: + return rpctypes.ErrNoSpace + case auth.ErrUserAlreadyExist: + return rpctypes.ErrUserAlreadyExist + case auth.ErrUserNotFound: + return rpctypes.ErrUserNotFound + case auth.ErrRoleAlreadyExist: + return rpctypes.ErrRoleAlreadyExist + default: + return grpc.Errorf(codes.Internal, err.Error()) + } +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go index f89be8fe54c..2f380a58db4 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/api/v3rpc/watch.go @@ -16,6 +16,7 @@ package v3rpc import ( "io" + "sync" "time" "github.com/coreos/etcd/etcdserver" @@ -41,11 +42,25 @@ func NewWatchServer(s *etcdserver.EtcdServer) pb.WatchServer { } var ( - // expose for testing purpose. External test can change this to a - // small value to finish fast. - ProgressReportInterval = 10 * time.Minute + // External test can read this with GetProgressReportInterval() + // and change this to a small value to finish fast with + // SetProgressReportInterval(). + progressReportInterval = 10 * time.Minute + progressReportIntervalMu sync.RWMutex ) +func GetProgressReportInterval() time.Duration { + progressReportIntervalMu.RLock() + defer progressReportIntervalMu.RUnlock() + return progressReportInterval +} + +func SetProgressReportInterval(newTimeout time.Duration) { + progressReportIntervalMu.Lock() + defer progressReportIntervalMu.Unlock() + progressReportInterval = newTimeout +} + const ( // We send ctrl response inside the read loop. We do not want // send to block read, but we still want ctrl response we sent to @@ -71,6 +86,8 @@ type serverWatchStream struct { // progress tracks the watchID that stream might need to send // progress to. progress map[storage.WatchID]bool + // mu protects progress + mu sync.Mutex // closec indicates the stream is closed. closec chan struct{} @@ -144,7 +161,9 @@ func (sws *serverWatchStream) recvLoop() error { WatchId: id, Canceled: true, } + sws.mu.Lock() delete(sws.progress, storage.WatchID(id)) + sws.mu.Unlock() } } // TODO: do we need to return error back to client? @@ -160,7 +179,8 @@ func (sws *serverWatchStream) sendLoop() { // watch responses pending on a watch id creation message pending := make(map[storage.WatchID][]*pb.WatchResponse) - progressTicker := time.NewTicker(ProgressReportInterval) + interval := GetProgressReportInterval() + progressTicker := time.NewTicker(interval) defer progressTicker.Stop() for { @@ -198,9 +218,11 @@ func (sws *serverWatchStream) sendLoop() { return } + sws.mu.Lock() if _, ok := sws.progress[wresp.WatchID]; ok { sws.progress[wresp.WatchID] = false } + sws.mu.Unlock() case c, ok := <-sws.ctrlStream: if !ok { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/apply.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/apply.go new file mode 100644 index 00000000000..da327985192 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/apply.go @@ -0,0 +1,627 @@ +// Copyright 2016 CoreOS, 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. + +package etcdserver + +import ( + "bytes" + "fmt" + "sort" + + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/lease" + "github.com/coreos/etcd/pkg/types" + dstorage "github.com/coreos/etcd/storage" + "github.com/coreos/etcd/storage/storagepb" + "github.com/gogo/protobuf/proto" +) + +const ( + // noTxn is an invalid txn ID. + // To apply with independent Range, Put, Delete, you can pass noTxn + // to apply functions instead of a valid txn ID. + noTxn = -1 +) + +type applyResult struct { + resp proto.Message + err error + // physc signals the physical effect of the request has completed in addition + // to being logically reflected by the node. Currently only used for + // Compaction requests. + physc <-chan struct{} +} + +// applierV3 is the interface for processing V3 raft messages +type applierV3 interface { + Put(txnID int64, p *pb.PutRequest) (*pb.PutResponse, error) + Range(txnID int64, r *pb.RangeRequest) (*pb.RangeResponse, error) + DeleteRange(txnID int64, dr *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) + Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) + Compaction(compaction *pb.CompactionRequest) (*pb.CompactionResponse, <-chan struct{}, error) + LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) + LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) + Alarm(*pb.AlarmRequest) (*pb.AlarmResponse, error) + AuthEnable() (*pb.AuthEnableResponse, error) + UserAdd(ua *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) + UserDelete(ua *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) + UserChangePassword(ua *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) + RoleAdd(ua *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) +} + +type applierV3backend struct { + s *EtcdServer +} + +func (s *EtcdServer) applyV3Request(r *pb.InternalRaftRequest) *applyResult { + ar := &applyResult{} + switch { + case r.Range != nil: + ar.resp, ar.err = s.applyV3.Range(noTxn, r.Range) + case r.Put != nil: + ar.resp, ar.err = s.applyV3.Put(noTxn, r.Put) + case r.DeleteRange != nil: + ar.resp, ar.err = s.applyV3.DeleteRange(noTxn, r.DeleteRange) + case r.Txn != nil: + ar.resp, ar.err = s.applyV3.Txn(r.Txn) + case r.Compaction != nil: + ar.resp, ar.physc, ar.err = s.applyV3.Compaction(r.Compaction) + case r.LeaseGrant != nil: + ar.resp, ar.err = s.applyV3.LeaseGrant(r.LeaseGrant) + case r.LeaseRevoke != nil: + ar.resp, ar.err = s.applyV3.LeaseRevoke(r.LeaseRevoke) + case r.Alarm != nil: + ar.resp, ar.err = s.applyV3.Alarm(r.Alarm) + case r.AuthEnable != nil: + ar.resp, ar.err = s.applyV3.AuthEnable() + case r.AuthUserAdd != nil: + ar.resp, ar.err = s.applyV3.UserAdd(r.AuthUserAdd) + case r.AuthUserDelete != nil: + ar.resp, ar.err = s.applyV3.UserDelete(r.AuthUserDelete) + case r.AuthUserChangePassword != nil: + ar.resp, ar.err = s.applyV3.UserChangePassword(r.AuthUserChangePassword) + case r.AuthRoleAdd != nil: + ar.resp, ar.err = s.applyV3.RoleAdd(r.AuthRoleAdd) + default: + panic("not implemented") + } + return ar +} + +func (a *applierV3backend) Put(txnID int64, p *pb.PutRequest) (*pb.PutResponse, error) { + resp := &pb.PutResponse{} + resp.Header = &pb.ResponseHeader{} + var ( + rev int64 + err error + ) + if txnID != noTxn { + rev, err = a.s.KV().TxnPut(txnID, p.Key, p.Value, lease.LeaseID(p.Lease)) + if err != nil { + return nil, err + } + } else { + leaseID := lease.LeaseID(p.Lease) + if leaseID != lease.NoLease { + if l := a.s.lessor.Lookup(leaseID); l == nil { + return nil, lease.ErrLeaseNotFound + } + } + rev = a.s.KV().Put(p.Key, p.Value, leaseID) + } + resp.Header.Revision = rev + return resp, nil +} + +func (a *applierV3backend) DeleteRange(txnID int64, dr *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) { + resp := &pb.DeleteRangeResponse{} + resp.Header = &pb.ResponseHeader{} + + var ( + n int64 + rev int64 + err error + ) + + if isGteRange(dr.RangeEnd) { + dr.RangeEnd = []byte{} + } + + if txnID != noTxn { + n, rev, err = a.s.KV().TxnDeleteRange(txnID, dr.Key, dr.RangeEnd) + if err != nil { + return nil, err + } + } else { + n, rev = a.s.KV().DeleteRange(dr.Key, dr.RangeEnd) + } + + resp.Deleted = n + resp.Header.Revision = rev + return resp, nil +} + +func (a *applierV3backend) Range(txnID int64, r *pb.RangeRequest) (*pb.RangeResponse, error) { + resp := &pb.RangeResponse{} + resp.Header = &pb.ResponseHeader{} + + var ( + kvs []storagepb.KeyValue + rev int64 + err error + ) + + if isGteRange(r.RangeEnd) { + r.RangeEnd = []byte{} + } + + limit := r.Limit + if r.SortOrder != pb.RangeRequest_NONE { + // fetch everything; sort and truncate afterwards + limit = 0 + } + if limit > 0 { + // fetch one extra for 'more' flag + limit = limit + 1 + } + + if txnID != noTxn { + kvs, rev, err = a.s.KV().TxnRange(txnID, r.Key, r.RangeEnd, limit, r.Revision) + if err != nil { + return nil, err + } + } else { + kvs, rev, err = a.s.KV().Range(r.Key, r.RangeEnd, limit, r.Revision) + if err != nil { + return nil, err + } + } + + if r.SortOrder != pb.RangeRequest_NONE { + var sorter sort.Interface + switch { + case r.SortTarget == pb.RangeRequest_KEY: + sorter = &kvSortByKey{&kvSort{kvs}} + case r.SortTarget == pb.RangeRequest_VERSION: + sorter = &kvSortByVersion{&kvSort{kvs}} + case r.SortTarget == pb.RangeRequest_CREATE: + sorter = &kvSortByCreate{&kvSort{kvs}} + case r.SortTarget == pb.RangeRequest_MOD: + sorter = &kvSortByMod{&kvSort{kvs}} + case r.SortTarget == pb.RangeRequest_VALUE: + sorter = &kvSortByValue{&kvSort{kvs}} + } + switch { + case r.SortOrder == pb.RangeRequest_ASCEND: + sort.Sort(sorter) + case r.SortOrder == pb.RangeRequest_DESCEND: + sort.Sort(sort.Reverse(sorter)) + } + } + + if r.Limit > 0 && len(kvs) > int(r.Limit) { + kvs = kvs[:r.Limit] + resp.More = true + } + + resp.Header.Revision = rev + for i := range kvs { + resp.Kvs = append(resp.Kvs, &kvs[i]) + } + return resp, nil +} + +func (a *applierV3backend) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) { + var revision int64 + + ok := true + for _, c := range rt.Compare { + if revision, ok = a.applyCompare(c); !ok { + break + } + } + + var reqs []*pb.RequestUnion + if ok { + reqs = rt.Success + } else { + reqs = rt.Failure + } + + if err := a.checkRequestLeases(reqs); err != nil { + return nil, err + } + if err := a.checkRequestRange(reqs); err != nil { + return nil, err + } + + // When executing the operations of txn, we need to hold the txn lock. + // So the reader will not see any intermediate results. + txnID := a.s.KV().TxnBegin() + defer func() { + err := a.s.KV().TxnEnd(txnID) + if err != nil { + panic(fmt.Sprint("unexpected error when closing txn", txnID)) + } + }() + + resps := make([]*pb.ResponseUnion, len(reqs)) + for i := range reqs { + resps[i] = a.applyUnion(txnID, reqs[i]) + } + + if len(resps) != 0 { + revision += 1 + } + + txnResp := &pb.TxnResponse{} + txnResp.Header = &pb.ResponseHeader{} + txnResp.Header.Revision = revision + txnResp.Responses = resps + txnResp.Succeeded = ok + return txnResp, nil +} + +// applyCompare applies the compare request. +// It returns the revision at which the comparison happens. If the comparison +// succeeds, the it returns true. Otherwise it returns false. +func (a *applierV3backend) applyCompare(c *pb.Compare) (int64, bool) { + ckvs, rev, err := a.s.KV().Range(c.Key, nil, 1, 0) + if err != nil { + if err == dstorage.ErrTxnIDMismatch { + panic("unexpected txn ID mismatch error") + } + return rev, false + } + var ckv storagepb.KeyValue + if len(ckvs) != 0 { + ckv = ckvs[0] + } else { + // Use the zero value of ckv normally. However... + if c.Target == pb.Compare_VALUE { + // Always fail if we're comparing a value on a key that doesn't exist. + // We can treat non-existence as the empty set explicitly, such that + // even a key with a value of length 0 bytes is still a real key + // that was written that way + return rev, false + } + } + + // -1 is less, 0 is equal, 1 is greater + var result int + switch c.Target { + case pb.Compare_VALUE: + tv, _ := c.TargetUnion.(*pb.Compare_Value) + if tv != nil { + result = bytes.Compare(ckv.Value, tv.Value) + } + case pb.Compare_CREATE: + tv, _ := c.TargetUnion.(*pb.Compare_CreateRevision) + if tv != nil { + result = compareInt64(ckv.CreateRevision, tv.CreateRevision) + } + + case pb.Compare_MOD: + tv, _ := c.TargetUnion.(*pb.Compare_ModRevision) + if tv != nil { + result = compareInt64(ckv.ModRevision, tv.ModRevision) + } + case pb.Compare_VERSION: + tv, _ := c.TargetUnion.(*pb.Compare_Version) + if tv != nil { + result = compareInt64(ckv.Version, tv.Version) + } + } + + switch c.Result { + case pb.Compare_EQUAL: + if result != 0 { + return rev, false + } + case pb.Compare_GREATER: + if result != 1 { + return rev, false + } + case pb.Compare_LESS: + if result != -1 { + return rev, false + } + } + return rev, true +} + +func (a *applierV3backend) applyUnion(txnID int64, union *pb.RequestUnion) *pb.ResponseUnion { + switch tv := union.Request.(type) { + case *pb.RequestUnion_RequestRange: + if tv.RequestRange != nil { + resp, err := a.Range(txnID, tv.RequestRange) + if err != nil { + panic("unexpected error during txn") + } + return &pb.ResponseUnion{Response: &pb.ResponseUnion_ResponseRange{ResponseRange: resp}} + } + case *pb.RequestUnion_RequestPut: + if tv.RequestPut != nil { + resp, err := a.Put(txnID, tv.RequestPut) + if err != nil { + panic("unexpected error during txn") + } + return &pb.ResponseUnion{Response: &pb.ResponseUnion_ResponsePut{ResponsePut: resp}} + } + case *pb.RequestUnion_RequestDeleteRange: + if tv.RequestDeleteRange != nil { + resp, err := a.DeleteRange(txnID, tv.RequestDeleteRange) + if err != nil { + panic("unexpected error during txn") + } + return &pb.ResponseUnion{Response: &pb.ResponseUnion_ResponseDeleteRange{ResponseDeleteRange: resp}} + } + default: + // empty union + return nil + } + return nil + +} + +func (a *applierV3backend) Compaction(compaction *pb.CompactionRequest) (*pb.CompactionResponse, <-chan struct{}, error) { + resp := &pb.CompactionResponse{} + resp.Header = &pb.ResponseHeader{} + ch, err := a.s.KV().Compact(compaction.Revision) + if err != nil { + return nil, ch, err + } + // get the current revision. which key to get is not important. + _, resp.Header.Revision, _ = a.s.KV().Range([]byte("compaction"), nil, 1, 0) + return resp, ch, err +} + +func (a *applierV3backend) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) { + l, err := a.s.lessor.Grant(lease.LeaseID(lc.ID), lc.TTL) + resp := &pb.LeaseGrantResponse{} + if err == nil { + resp.ID = int64(l.ID) + resp.TTL = l.TTL + } + return resp, err +} + +func (a *applierV3backend) LeaseRevoke(lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) { + err := a.s.lessor.Revoke(lease.LeaseID(lc.ID)) + return &pb.LeaseRevokeResponse{}, err +} + +func (a *applierV3backend) Alarm(ar *pb.AlarmRequest) (*pb.AlarmResponse, error) { + resp := &pb.AlarmResponse{} + oldCount := len(a.s.alarmStore.Get(ar.Alarm)) + + switch ar.Action { + case pb.AlarmRequest_GET: + resp.Alarms = a.s.alarmStore.Get(ar.Alarm) + case pb.AlarmRequest_ACTIVATE: + m := a.s.alarmStore.Activate(types.ID(ar.MemberID), ar.Alarm) + if m == nil { + break + } + resp.Alarms = append(resp.Alarms, m) + activated := oldCount == 0 && len(a.s.alarmStore.Get(m.Alarm)) == 1 + if !activated { + break + } + + switch m.Alarm { + case pb.AlarmType_NOSPACE: + plog.Warningf("alarm raised %+v", m) + a.s.applyV3 = newApplierV3Capped(a) + default: + plog.Errorf("unimplemented alarm activation (%+v)", m) + } + case pb.AlarmRequest_DEACTIVATE: + m := a.s.alarmStore.Deactivate(types.ID(ar.MemberID), ar.Alarm) + if m == nil { + break + } + resp.Alarms = append(resp.Alarms, m) + deactivated := oldCount > 0 && len(a.s.alarmStore.Get(ar.Alarm)) == 0 + if !deactivated { + break + } + + switch m.Alarm { + case pb.AlarmType_NOSPACE: + plog.Infof("alarm disarmed %+v", ar) + a.s.applyV3 = newQuotaApplierV3(a.s, &applierV3backend{a.s}) + default: + plog.Errorf("unimplemented alarm deactivation (%+v)", m) + } + default: + return nil, nil + } + return resp, nil +} + +type applierV3Capped struct { + applierV3 + q backendQuota +} + +// newApplierV3Capped creates an applyV3 that will reject Puts and transactions +// with Puts so that the number of keys in the store is capped. +func newApplierV3Capped(base applierV3) applierV3 { return &applierV3Capped{applierV3: base} } + +func (a *applierV3Capped) Put(txnID int64, p *pb.PutRequest) (*pb.PutResponse, error) { + return nil, ErrNoSpace +} + +func (a *applierV3Capped) Txn(r *pb.TxnRequest) (*pb.TxnResponse, error) { + if a.q.Cost(r) > 0 { + return nil, ErrNoSpace + } + return a.applierV3.Txn(r) +} + +func (a *applierV3Capped) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) { + return nil, ErrNoSpace +} + +func (a *applierV3backend) AuthEnable() (*pb.AuthEnableResponse, error) { + a.s.AuthStore().AuthEnable() + return &pb.AuthEnableResponse{}, nil +} + +func (a *applierV3backend) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) { + return a.s.AuthStore().UserAdd(r) +} + +func (a *applierV3backend) UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) { + return a.s.AuthStore().UserDelete(r) +} + +func (a *applierV3backend) UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) { + return a.s.AuthStore().UserChangePassword(r) +} + +func (a *applierV3backend) RoleAdd(r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) { + return a.s.AuthStore().RoleAdd(r) +} + +type quotaApplierV3 struct { + applierV3 + q Quota +} + +func newQuotaApplierV3(s *EtcdServer, app applierV3) applierV3 { + return "aApplierV3{app, NewBackendQuota(s)} +} + +func (a *quotaApplierV3) Put(txnID int64, p *pb.PutRequest) (*pb.PutResponse, error) { + ok := a.q.Available(p) + resp, err := a.applierV3.Put(txnID, p) + if err == nil && !ok { + err = ErrNoSpace + } + return resp, err +} + +func (a *quotaApplierV3) Txn(rt *pb.TxnRequest) (*pb.TxnResponse, error) { + ok := a.q.Available(rt) + resp, err := a.applierV3.Txn(rt) + if err == nil && !ok { + err = ErrNoSpace + } + return resp, err +} + +func (a *quotaApplierV3) LeaseGrant(lc *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) { + ok := a.q.Available(lc) + resp, err := a.applierV3.LeaseGrant(lc) + if err == nil && !ok { + err = ErrNoSpace + } + return resp, err +} + +type kvSort struct{ kvs []storagepb.KeyValue } + +func (s *kvSort) Swap(i, j int) { + t := s.kvs[i] + s.kvs[i] = s.kvs[j] + s.kvs[j] = t +} +func (s *kvSort) Len() int { return len(s.kvs) } + +type kvSortByKey struct{ *kvSort } + +func (s *kvSortByKey) Less(i, j int) bool { + return bytes.Compare(s.kvs[i].Key, s.kvs[j].Key) < 0 +} + +type kvSortByVersion struct{ *kvSort } + +func (s *kvSortByVersion) Less(i, j int) bool { + return (s.kvs[i].Version - s.kvs[j].Version) < 0 +} + +type kvSortByCreate struct{ *kvSort } + +func (s *kvSortByCreate) Less(i, j int) bool { + return (s.kvs[i].CreateRevision - s.kvs[j].CreateRevision) < 0 +} + +type kvSortByMod struct{ *kvSort } + +func (s *kvSortByMod) Less(i, j int) bool { + return (s.kvs[i].ModRevision - s.kvs[j].ModRevision) < 0 +} + +type kvSortByValue struct{ *kvSort } + +func (s *kvSortByValue) Less(i, j int) bool { + return bytes.Compare(s.kvs[i].Value, s.kvs[j].Value) < 0 +} + +func (a *applierV3backend) checkRequestLeases(reqs []*pb.RequestUnion) error { + for _, requ := range reqs { + tv, ok := requ.Request.(*pb.RequestUnion_RequestPut) + if !ok { + continue + } + preq := tv.RequestPut + if preq == nil || lease.LeaseID(preq.Lease) == lease.NoLease { + continue + } + if l := a.s.lessor.Lookup(lease.LeaseID(preq.Lease)); l == nil { + return lease.ErrLeaseNotFound + } + } + return nil +} + +func (a *applierV3backend) checkRequestRange(reqs []*pb.RequestUnion) error { + for _, requ := range reqs { + tv, ok := requ.Request.(*pb.RequestUnion_RequestRange) + if !ok { + continue + } + greq := tv.RequestRange + if greq == nil || greq.Revision == 0 { + continue + } + + if greq.Revision > a.s.KV().Rev() { + return dstorage.ErrFutureRev + } + if greq.Revision < a.s.KV().FirstRev() { + return dstorage.ErrCompacted + } + } + return nil +} + +func compareInt64(a, b int64) int { + switch { + case a < b: + return -1 + case a > b: + return 1 + default: + return 0 + } +} + +// isGteRange determines if the range end is a >= range. This works around grpc +// sending empty byte strings as nil; >= is encoded in the range end as '\0'. +func isGteRange(rangeEnd []byte) bool { + return len(rangeEnd) == 1 && rangeEnd[0] == 0 +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/cluster_util.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/cluster_util.go index 5f3ffdce513..cd456f92e03 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/cluster_util.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/cluster_util.go @@ -22,6 +22,8 @@ import ( "sort" "time" + "github.com/coreos/etcd/etcdserver/membership" + "github.com/coreos/etcd/pkg/httputil" "github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/version" "github.com/coreos/go-semver/semver" @@ -29,7 +31,7 @@ import ( // isMemberBootstrapped tries to check if the given member has been bootstrapped // in the given cluster. -func isMemberBootstrapped(cl *cluster, member string, rt http.RoundTripper, timeout time.Duration) bool { +func isMemberBootstrapped(cl *membership.RaftCluster, member string, rt http.RoundTripper, timeout time.Duration) bool { rcl, err := getClusterFromRemotePeers(getRemotePeerURLs(cl, member), timeout, false, rt) if err != nil { return false @@ -52,12 +54,12 @@ func isMemberBootstrapped(cl *cluster, member string, rt http.RoundTripper, time // response, an error is returned. // Each request has a 10-second timeout. Because the upper limit of TTL is 5s, // 10 second is enough for building connection and finishing request. -func GetClusterFromRemotePeers(urls []string, rt http.RoundTripper) (*cluster, error) { +func GetClusterFromRemotePeers(urls []string, rt http.RoundTripper) (*membership.RaftCluster, error) { return getClusterFromRemotePeers(urls, 10*time.Second, true, rt) } // If logerr is true, it prints out more error messages. -func getClusterFromRemotePeers(urls []string, timeout time.Duration, logerr bool, rt http.RoundTripper) (*cluster, error) { +func getClusterFromRemotePeers(urls []string, timeout time.Duration, logerr bool, rt http.RoundTripper) (*membership.RaftCluster, error) { cc := &http.Client{ Transport: rt, Timeout: timeout, @@ -77,7 +79,7 @@ func getClusterFromRemotePeers(urls []string, timeout time.Duration, logerr bool } continue } - var membs []*Member + var membs []*membership.Member if err = json.Unmarshal(b, &membs); err != nil { if logerr { plog.Warningf("could not unmarshal cluster response: %v", err) @@ -91,14 +93,14 @@ func getClusterFromRemotePeers(urls []string, timeout time.Duration, logerr bool } continue } - return newClusterFromMembers("", id, membs), nil + return membership.NewClusterFromMembers("", id, membs), nil } return nil, fmt.Errorf("could not retrieve cluster information from the given urls") } // getRemotePeerURLs returns peer urls of remote members in the cluster. The // returned list is sorted in ascending lexicographical order. -func getRemotePeerURLs(cl Cluster, local string) []string { +func getRemotePeerURLs(cl *membership.RaftCluster, local string) []string { us := make([]string, 0) for _, m := range cl.Members() { if m.Name == local { @@ -114,7 +116,7 @@ func getRemotePeerURLs(cl Cluster, local string) []string { // The key of the returned map is the member's ID. The value of the returned map // is the semver versions string, including server and cluster. // If it fails to get the version of a member, the key will be nil. -func getVersions(cl Cluster, local types.ID, rt http.RoundTripper) map[string]*version.Versions { +func getVersions(cl *membership.RaftCluster, local types.ID, rt http.RoundTripper) map[string]*version.Versions { members := cl.Members() vers := make(map[string]*version.Versions) for _, m := range members { @@ -172,7 +174,7 @@ func decideClusterVersion(vers map[string]*version.Versions) *semver.Version { // cluster version in the range of [MinClusterVersion, Version] and no known members has a cluster version // out of the range. // We set this rule since when the local member joins, another member might be offline. -func isCompatibleWithCluster(cl Cluster, local types.ID, rt http.RoundTripper) bool { +func isCompatibleWithCluster(cl *membership.RaftCluster, local types.ID, rt http.RoundTripper) bool { vers := getVersions(cl, local, rt) minV := semver.Must(semver.NewVersion(version.MinClusterVersion)) maxV := semver.Must(semver.NewVersion(version.Version)) @@ -214,7 +216,7 @@ func isCompatibleWithVers(vers map[string]*version.Versions, local types.ID, min // getVersion returns the Versions of the given member via its // peerURLs. Returns the last error if it fails to get the version. -func getVersion(m *Member, rt http.RoundTripper) (*version.Versions, error) { +func getVersion(m *membership.Member, rt http.RoundTripper) (*version.Versions, error) { cc := &http.Client{ Transport: rt, } @@ -231,7 +233,7 @@ func getVersion(m *Member, rt http.RoundTripper) (*version.Versions, error) { } // etcd 2.0 does not have version endpoint on peer url. if resp.StatusCode == http.StatusNotFound { - resp.Body.Close() + httputil.GracefulClose(resp) return &version.Versions{ Server: "2.0.0", Cluster: "2.0.0", @@ -254,12 +256,3 @@ func getVersion(m *Member, rt http.RoundTripper) (*version.Versions, error) { } return nil, err } - -func MustDetectDowngrade(cv *semver.Version) { - lv := semver.Must(semver.NewVersion(version.Version)) - // only keep major.minor version for comparison against cluster version - lv = &semver.Version{Major: lv.Major, Minor: lv.Minor} - if cv != nil && lv.LessThan(*cv) { - plog.Fatalf("cluster cannot be downgraded (current version: %s is lower than determined cluster version: %s).", version.Version, version.Cluster(cv.String())) - } -} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/config.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/config.go index 0a5384182cb..3fc8eea3eff 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/config.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/config.go @@ -50,8 +50,8 @@ type ServerConfig struct { ElectionTicks int BootstrapTimeout time.Duration - V3demo bool AutoCompactionRetention int + QuotaBackendBytes int64 StrictReconfigCheck bool diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/errors.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/errors.go index eef57ccf328..6731c117e44 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/errors.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/errors.go @@ -17,17 +17,11 @@ package etcdserver import ( "errors" "fmt" - - etcdErr "github.com/coreos/etcd/error" ) var ( ErrUnknownMethod = errors.New("etcdserver: unknown method") ErrStopped = errors.New("etcdserver: server stopped") - ErrIDRemoved = errors.New("etcdserver: ID removed") - ErrIDExists = errors.New("etcdserver: ID exists") - ErrIDNotFound = errors.New("etcdserver: ID not found") - ErrPeerURLexists = errors.New("etcdserver: peerURL exists") ErrCanceled = errors.New("etcdserver: request cancelled") ErrTimeout = errors.New("etcdserver: request timed out") ErrTimeoutDueToLeaderFail = errors.New("etcdserver: request timed out, possibly due to previous leader failure") @@ -35,13 +29,9 @@ var ( ErrNotEnoughStartedMembers = errors.New("etcdserver: re-configuration failed due to not enough started members") ErrNoLeader = errors.New("etcdserver: no leader") ErrRequestTooLarge = errors.New("etcdserver: request is too large") + ErrNoSpace = errors.New("etcdserver: no space") ) -func isKeyNotFound(err error) bool { - e, ok := err.(*etcdErr.Error) - return ok && e.ErrorCode == etcdErr.EcodeKeyNotFound -} - type DiscoveryError struct { Op string Err error diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go index 0044a7a57ba..6ab9804c621 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/etcdserver.pb.go @@ -35,8 +35,8 @@ WatchCreateRequest WatchCancelRequest WatchResponse - LeaseCreateRequest - LeaseCreateResponse + LeaseGrantRequest + LeaseGrantResponse LeaseRevokeRequest LeaseRevokeResponse LeaseKeepAliveRequest @@ -52,34 +52,39 @@ MemberListResponse DefragmentRequest DefragmentResponse + AlarmRequest + AlarmMember + AlarmResponse + StatusRequest + StatusResponse AuthEnableRequest AuthDisableRequest AuthenticateRequest - UserAddRequest - UserGetRequest - UserDeleteRequest - UserChangePasswordRequest - UserGrantRequest - UserRevokeRequest - RoleAddRequest - RoleGetRequest - RoleDeleteRequest - RoleGrantRequest - RoleRevokeRequest + AuthUserAddRequest + AuthUserGetRequest + AuthUserDeleteRequest + AuthUserChangePasswordRequest + AuthUserGrantRequest + AuthUserRevokeRequest + AuthRoleAddRequest + AuthRoleGetRequest + AuthRoleDeleteRequest + AuthRoleGrantRequest + AuthRoleRevokeRequest AuthEnableResponse AuthDisableResponse AuthenticateResponse - UserAddResponse - UserGetResponse - UserDeleteResponse - UserChangePasswordResponse - UserGrantResponse - UserRevokeResponse - RoleAddResponse - RoleGetResponse - RoleDeleteResponse - RoleGrantResponse - RoleRevokeResponse + AuthUserAddResponse + AuthUserGetResponse + AuthUserDeleteResponse + AuthUserChangePasswordResponse + AuthUserGrantResponse + AuthUserRevokeResponse + AuthRoleAddResponse + AuthRoleGetResponse + AuthRoleDeleteResponse + AuthRoleGrantResponse + AuthRoleRevokeResponse */ package etcdserverpb @@ -87,9 +92,9 @@ import ( "fmt" proto "github.com/gogo/protobuf/proto" -) -import math "math" + math "math" +) import io "io" diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go index a5c0a315b41..4c66129d785 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.pb.go @@ -8,9 +8,9 @@ import ( "fmt" proto "github.com/gogo/protobuf/proto" -) -import math "math" + math "math" +) import io "io" @@ -22,16 +22,21 @@ var _ = math.Inf // An InternalRaftRequest is the union of all requests which can be // sent via raft. type InternalRaftRequest struct { - ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` - V2 *Request `protobuf:"bytes,2,opt,name=v2" json:"v2,omitempty"` - Range *RangeRequest `protobuf:"bytes,3,opt,name=range" json:"range,omitempty"` - Put *PutRequest `protobuf:"bytes,4,opt,name=put" json:"put,omitempty"` - DeleteRange *DeleteRangeRequest `protobuf:"bytes,5,opt,name=delete_range" json:"delete_range,omitempty"` - Txn *TxnRequest `protobuf:"bytes,6,opt,name=txn" json:"txn,omitempty"` - Compaction *CompactionRequest `protobuf:"bytes,7,opt,name=compaction" json:"compaction,omitempty"` - LeaseCreate *LeaseCreateRequest `protobuf:"bytes,8,opt,name=lease_create" json:"lease_create,omitempty"` - LeaseRevoke *LeaseRevokeRequest `protobuf:"bytes,9,opt,name=lease_revoke" json:"lease_revoke,omitempty"` - AuthEnable *AuthEnableRequest `protobuf:"bytes,10,opt,name=auth_enable" json:"auth_enable,omitempty"` + ID uint64 `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"` + V2 *Request `protobuf:"bytes,2,opt,name=v2" json:"v2,omitempty"` + Range *RangeRequest `protobuf:"bytes,3,opt,name=range" json:"range,omitempty"` + Put *PutRequest `protobuf:"bytes,4,opt,name=put" json:"put,omitempty"` + DeleteRange *DeleteRangeRequest `protobuf:"bytes,5,opt,name=delete_range" json:"delete_range,omitempty"` + Txn *TxnRequest `protobuf:"bytes,6,opt,name=txn" json:"txn,omitempty"` + Compaction *CompactionRequest `protobuf:"bytes,7,opt,name=compaction" json:"compaction,omitempty"` + LeaseGrant *LeaseGrantRequest `protobuf:"bytes,8,opt,name=lease_grant" json:"lease_grant,omitempty"` + LeaseRevoke *LeaseRevokeRequest `protobuf:"bytes,9,opt,name=lease_revoke" json:"lease_revoke,omitempty"` + AuthEnable *AuthEnableRequest `protobuf:"bytes,10,opt,name=auth_enable" json:"auth_enable,omitempty"` + AuthUserAdd *AuthUserAddRequest `protobuf:"bytes,11,opt,name=auth_user_add" json:"auth_user_add,omitempty"` + AuthUserDelete *AuthUserDeleteRequest `protobuf:"bytes,12,opt,name=auth_user_delete" json:"auth_user_delete,omitempty"` + AuthUserChangePassword *AuthUserChangePasswordRequest `protobuf:"bytes,13,opt,name=auth_user_change_password" json:"auth_user_change_password,omitempty"` + AuthRoleAdd *AuthRoleAddRequest `protobuf:"bytes,14,opt,name=auth_role_add" json:"auth_role_add,omitempty"` + Alarm *AlarmRequest `protobuf:"bytes,15,opt,name=alarm" json:"alarm,omitempty"` } func (m *InternalRaftRequest) Reset() { *m = InternalRaftRequest{} } @@ -129,11 +134,11 @@ func (m *InternalRaftRequest) MarshalTo(data []byte) (int, error) { } i += n6 } - if m.LeaseCreate != nil { + if m.LeaseGrant != nil { data[i] = 0x42 i++ - i = encodeVarintRaftInternal(data, i, uint64(m.LeaseCreate.Size())) - n7, err := m.LeaseCreate.MarshalTo(data[i:]) + i = encodeVarintRaftInternal(data, i, uint64(m.LeaseGrant.Size())) + n7, err := m.LeaseGrant.MarshalTo(data[i:]) if err != nil { return 0, err } @@ -159,6 +164,56 @@ func (m *InternalRaftRequest) MarshalTo(data []byte) (int, error) { } i += n9 } + if m.AuthUserAdd != nil { + data[i] = 0x5a + i++ + i = encodeVarintRaftInternal(data, i, uint64(m.AuthUserAdd.Size())) + n10, err := m.AuthUserAdd.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n10 + } + if m.AuthUserDelete != nil { + data[i] = 0x62 + i++ + i = encodeVarintRaftInternal(data, i, uint64(m.AuthUserDelete.Size())) + n11, err := m.AuthUserDelete.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n11 + } + if m.AuthUserChangePassword != nil { + data[i] = 0x6a + i++ + i = encodeVarintRaftInternal(data, i, uint64(m.AuthUserChangePassword.Size())) + n12, err := m.AuthUserChangePassword.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n12 + } + if m.AuthRoleAdd != nil { + data[i] = 0x72 + i++ + i = encodeVarintRaftInternal(data, i, uint64(m.AuthRoleAdd.Size())) + n13, err := m.AuthRoleAdd.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n13 + } + if m.Alarm != nil { + data[i] = 0x7a + i++ + i = encodeVarintRaftInternal(data, i, uint64(m.Alarm.Size())) + n14, err := m.Alarm.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n14 + } return i, nil } @@ -237,8 +292,8 @@ func (m *InternalRaftRequest) Size() (n int) { l = m.Compaction.Size() n += 1 + l + sovRaftInternal(uint64(l)) } - if m.LeaseCreate != nil { - l = m.LeaseCreate.Size() + if m.LeaseGrant != nil { + l = m.LeaseGrant.Size() n += 1 + l + sovRaftInternal(uint64(l)) } if m.LeaseRevoke != nil { @@ -249,6 +304,26 @@ func (m *InternalRaftRequest) Size() (n int) { l = m.AuthEnable.Size() n += 1 + l + sovRaftInternal(uint64(l)) } + if m.AuthUserAdd != nil { + l = m.AuthUserAdd.Size() + n += 1 + l + sovRaftInternal(uint64(l)) + } + if m.AuthUserDelete != nil { + l = m.AuthUserDelete.Size() + n += 1 + l + sovRaftInternal(uint64(l)) + } + if m.AuthUserChangePassword != nil { + l = m.AuthUserChangePassword.Size() + n += 1 + l + sovRaftInternal(uint64(l)) + } + if m.AuthRoleAdd != nil { + l = m.AuthRoleAdd.Size() + n += 1 + l + sovRaftInternal(uint64(l)) + } + if m.Alarm != nil { + l = m.Alarm.Size() + n += 1 + l + sovRaftInternal(uint64(l)) + } return n } @@ -519,7 +594,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { iNdEx = postIndex case 8: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field LeaseCreate", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LeaseGrant", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -543,10 +618,10 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.LeaseCreate == nil { - m.LeaseCreate = &LeaseCreateRequest{} + if m.LeaseGrant == nil { + m.LeaseGrant = &LeaseGrantRequest{} } - if err := m.LeaseCreate.Unmarshal(data[iNdEx:postIndex]); err != nil { + if err := m.LeaseGrant.Unmarshal(data[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -616,6 +691,171 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error { return err } iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthUserAdd", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AuthUserAdd == nil { + m.AuthUserAdd = &AuthUserAddRequest{} + } + if err := m.AuthUserAdd.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthUserDelete", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AuthUserDelete == nil { + m.AuthUserDelete = &AuthUserDeleteRequest{} + } + if err := m.AuthUserDelete.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthUserChangePassword", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AuthUserChangePassword == nil { + m.AuthUserChangePassword = &AuthUserChangePasswordRequest{} + } + if err := m.AuthUserChangePassword.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AuthRoleAdd", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.AuthRoleAdd == nil { + m.AuthRoleAdd = &AuthRoleAddRequest{} + } + if err := m.AuthRoleAdd.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Alarm", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRaftInternal + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRaftInternal + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Alarm == nil { + m.Alarm = &AlarmRequest{} + } + if err := m.Alarm.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipRaftInternal(data[iNdEx:]) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.proto b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.proto index a68cebc82cd..1fe517f5ce4 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.proto +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/raft_internal.proto @@ -22,10 +22,16 @@ message InternalRaftRequest { TxnRequest txn = 6; CompactionRequest compaction = 7; - LeaseCreateRequest lease_create = 8; + LeaseGrantRequest lease_grant = 8; LeaseRevokeRequest lease_revoke = 9; AuthEnableRequest auth_enable = 10; + AuthUserAddRequest auth_user_add = 11; + AuthUserDeleteRequest auth_user_delete = 12; + AuthUserChangePasswordRequest auth_user_change_password = 13; + AuthRoleAddRequest auth_role_add = 14; + + AlarmRequest alarm = 15; } message EmptyResponse { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go index bae92b6eebf..ac5de8cfe68 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.pb.go @@ -8,17 +8,16 @@ import ( "fmt" proto "github.com/gogo/protobuf/proto" -) -import math "math" + math "math" -import storagepb "github.com/coreos/etcd/storage/storagepb" - -import ( context "golang.org/x/net/context" + grpc "google.golang.org/grpc" ) +import storagepb "github.com/coreos/etcd/storage/storagepb" + import io "io" // Reference imports to suppress errors if they are not otherwise used. @@ -26,6 +25,26 @@ var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf +type AlarmType int32 + +const ( + AlarmType_NONE AlarmType = 0 + AlarmType_NOSPACE AlarmType = 1 +) + +var AlarmType_name = map[int32]string{ + 0: "NONE", + 1: "NOSPACE", +} +var AlarmType_value = map[string]int32{ + "NONE": 0, + "NOSPACE": 1, +} + +func (x AlarmType) String() string { + return proto.EnumName(AlarmType_name, int32(x)) +} + type RangeRequest_SortOrder int32 const ( @@ -127,6 +146,29 @@ func (x Compare_CompareTarget) String() string { return proto.EnumName(Compare_CompareTarget_name, int32(x)) } +type AlarmRequest_AlarmAction int32 + +const ( + AlarmRequest_GET AlarmRequest_AlarmAction = 0 + AlarmRequest_ACTIVATE AlarmRequest_AlarmAction = 1 + AlarmRequest_DEACTIVATE AlarmRequest_AlarmAction = 2 +) + +var AlarmRequest_AlarmAction_name = map[int32]string{ + 0: "GET", + 1: "ACTIVATE", + 2: "DEACTIVATE", +} +var AlarmRequest_AlarmAction_value = map[string]int32{ + "GET": 0, + "ACTIVATE": 1, + "DEACTIVATE": 2, +} + +func (x AlarmRequest_AlarmAction) String() string { + return proto.EnumName(AlarmRequest_AlarmAction_name, int32(x)) +} + type ResponseHeader struct { ClusterId uint64 `protobuf:"varint,1,opt,name=cluster_id,proto3" json:"cluster_id,omitempty"` MemberId uint64 `protobuf:"varint,2,opt,name=member_id,proto3" json:"member_id,omitempty"` @@ -722,6 +764,10 @@ func (m *TxnResponse) GetResponses() []*ResponseUnion { // revision. type CompactionRequest struct { Revision int64 `protobuf:"varint,1,opt,name=revision,proto3" json:"revision,omitempty"` + // physical is set so the RPC will wait until the compaction is physically + // applied to the local database such that compacted entries are totally + // removed from the backing store. + Physical bool `protobuf:"varint,2,opt,name=physical,proto3" json:"physical,omitempty"` } func (m *CompactionRequest) Reset() { *m = CompactionRequest{} } @@ -936,18 +982,18 @@ func (m *WatchResponse) GetEvents() []*storagepb.Event { return nil } -type LeaseCreateRequest struct { +type LeaseGrantRequest struct { // advisory ttl in seconds TTL int64 `protobuf:"varint,1,opt,name=TTL,proto3" json:"TTL,omitempty"` // requested ID to create; 0 lets lessor choose ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"` } -func (m *LeaseCreateRequest) Reset() { *m = LeaseCreateRequest{} } -func (m *LeaseCreateRequest) String() string { return proto.CompactTextString(m) } -func (*LeaseCreateRequest) ProtoMessage() {} +func (m *LeaseGrantRequest) Reset() { *m = LeaseGrantRequest{} } +func (m *LeaseGrantRequest) String() string { return proto.CompactTextString(m) } +func (*LeaseGrantRequest) ProtoMessage() {} -type LeaseCreateResponse struct { +type LeaseGrantResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` ID int64 `protobuf:"varint,2,opt,name=ID,proto3" json:"ID,omitempty"` // server decided ttl in second @@ -955,11 +1001,11 @@ type LeaseCreateResponse struct { Error string `protobuf:"bytes,4,opt,name=error,proto3" json:"error,omitempty"` } -func (m *LeaseCreateResponse) Reset() { *m = LeaseCreateResponse{} } -func (m *LeaseCreateResponse) String() string { return proto.CompactTextString(m) } -func (*LeaseCreateResponse) ProtoMessage() {} +func (m *LeaseGrantResponse) Reset() { *m = LeaseGrantResponse{} } +func (m *LeaseGrantResponse) String() string { return proto.CompactTextString(m) } +func (*LeaseGrantResponse) ProtoMessage() {} -func (m *LeaseCreateResponse) GetHeader() *ResponseHeader { +func (m *LeaseGrantResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } @@ -1159,6 +1205,72 @@ func (m *DefragmentResponse) GetHeader() *ResponseHeader { return nil } +type AlarmRequest struct { + Action AlarmRequest_AlarmAction `protobuf:"varint,1,opt,name=action,proto3,enum=etcdserverpb.AlarmRequest_AlarmAction" json:"action,omitempty"` + // MemberID is the member raising the alarm request + MemberID uint64 `protobuf:"varint,2,opt,name=memberID,proto3" json:"memberID,omitempty"` + Alarm AlarmType `protobuf:"varint,3,opt,name=alarm,proto3,enum=etcdserverpb.AlarmType" json:"alarm,omitempty"` +} + +func (m *AlarmRequest) Reset() { *m = AlarmRequest{} } +func (m *AlarmRequest) String() string { return proto.CompactTextString(m) } +func (*AlarmRequest) ProtoMessage() {} + +type AlarmMember struct { + MemberID uint64 `protobuf:"varint,1,opt,name=memberID,proto3" json:"memberID,omitempty"` + Alarm AlarmType `protobuf:"varint,2,opt,name=alarm,proto3,enum=etcdserverpb.AlarmType" json:"alarm,omitempty"` +} + +func (m *AlarmMember) Reset() { *m = AlarmMember{} } +func (m *AlarmMember) String() string { return proto.CompactTextString(m) } +func (*AlarmMember) ProtoMessage() {} + +type AlarmResponse struct { + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + Alarms []*AlarmMember `protobuf:"bytes,2,rep,name=alarms" json:"alarms,omitempty"` +} + +func (m *AlarmResponse) Reset() { *m = AlarmResponse{} } +func (m *AlarmResponse) String() string { return proto.CompactTextString(m) } +func (*AlarmResponse) ProtoMessage() {} + +func (m *AlarmResponse) GetHeader() *ResponseHeader { + if m != nil { + return m.Header + } + return nil +} + +func (m *AlarmResponse) GetAlarms() []*AlarmMember { + if m != nil { + return m.Alarms + } + return nil +} + +type StatusRequest struct { +} + +func (m *StatusRequest) Reset() { *m = StatusRequest{} } +func (m *StatusRequest) String() string { return proto.CompactTextString(m) } +func (*StatusRequest) ProtoMessage() {} + +type StatusResponse struct { + Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` +} + +func (m *StatusResponse) Reset() { *m = StatusResponse{} } +func (m *StatusResponse) String() string { return proto.CompactTextString(m) } +func (*StatusResponse) ProtoMessage() {} + +func (m *StatusResponse) GetHeader() *ResponseHeader { + if m != nil { + return m.Header + } + return nil +} + type AuthEnableRequest struct { } @@ -1180,82 +1292,88 @@ func (m *AuthenticateRequest) Reset() { *m = AuthenticateRequest{} } func (m *AuthenticateRequest) String() string { return proto.CompactTextString(m) } func (*AuthenticateRequest) ProtoMessage() {} -type UserAddRequest struct { +type AuthUserAddRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` } -func (m *UserAddRequest) Reset() { *m = UserAddRequest{} } -func (m *UserAddRequest) String() string { return proto.CompactTextString(m) } -func (*UserAddRequest) ProtoMessage() {} +func (m *AuthUserAddRequest) Reset() { *m = AuthUserAddRequest{} } +func (m *AuthUserAddRequest) String() string { return proto.CompactTextString(m) } +func (*AuthUserAddRequest) ProtoMessage() {} -type UserGetRequest struct { +type AuthUserGetRequest struct { } -func (m *UserGetRequest) Reset() { *m = UserGetRequest{} } -func (m *UserGetRequest) String() string { return proto.CompactTextString(m) } -func (*UserGetRequest) ProtoMessage() {} +func (m *AuthUserGetRequest) Reset() { *m = AuthUserGetRequest{} } +func (m *AuthUserGetRequest) String() string { return proto.CompactTextString(m) } +func (*AuthUserGetRequest) ProtoMessage() {} -type UserDeleteRequest struct { +type AuthUserDeleteRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } -func (m *UserDeleteRequest) Reset() { *m = UserDeleteRequest{} } -func (m *UserDeleteRequest) String() string { return proto.CompactTextString(m) } -func (*UserDeleteRequest) ProtoMessage() {} +func (m *AuthUserDeleteRequest) Reset() { *m = AuthUserDeleteRequest{} } +func (m *AuthUserDeleteRequest) String() string { return proto.CompactTextString(m) } +func (*AuthUserDeleteRequest) ProtoMessage() {} -type UserChangePasswordRequest struct { +type AuthUserChangePasswordRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` } -func (m *UserChangePasswordRequest) Reset() { *m = UserChangePasswordRequest{} } -func (m *UserChangePasswordRequest) String() string { return proto.CompactTextString(m) } -func (*UserChangePasswordRequest) ProtoMessage() {} +func (m *AuthUserChangePasswordRequest) Reset() { *m = AuthUserChangePasswordRequest{} } +func (m *AuthUserChangePasswordRequest) String() string { return proto.CompactTextString(m) } +func (*AuthUserChangePasswordRequest) ProtoMessage() {} -type UserGrantRequest struct { +type AuthUserGrantRequest struct { } -func (m *UserGrantRequest) Reset() { *m = UserGrantRequest{} } -func (m *UserGrantRequest) String() string { return proto.CompactTextString(m) } -func (*UserGrantRequest) ProtoMessage() {} +func (m *AuthUserGrantRequest) Reset() { *m = AuthUserGrantRequest{} } +func (m *AuthUserGrantRequest) String() string { return proto.CompactTextString(m) } +func (*AuthUserGrantRequest) ProtoMessage() {} -type UserRevokeRequest struct { +type AuthUserRevokeRequest struct { } -func (m *UserRevokeRequest) Reset() { *m = UserRevokeRequest{} } -func (m *UserRevokeRequest) String() string { return proto.CompactTextString(m) } -func (*UserRevokeRequest) ProtoMessage() {} +func (m *AuthUserRevokeRequest) Reset() { *m = AuthUserRevokeRequest{} } +func (m *AuthUserRevokeRequest) String() string { return proto.CompactTextString(m) } +func (*AuthUserRevokeRequest) ProtoMessage() {} -type RoleAddRequest struct { +type AuthRoleAddRequest struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` } -func (m *RoleAddRequest) Reset() { *m = RoleAddRequest{} } -func (m *RoleAddRequest) String() string { return proto.CompactTextString(m) } -func (*RoleAddRequest) ProtoMessage() {} +func (m *AuthRoleAddRequest) Reset() { *m = AuthRoleAddRequest{} } +func (m *AuthRoleAddRequest) String() string { return proto.CompactTextString(m) } +func (*AuthRoleAddRequest) ProtoMessage() {} -type RoleGetRequest struct { +type AuthRoleGetRequest struct { } -func (m *RoleGetRequest) Reset() { *m = RoleGetRequest{} } -func (m *RoleGetRequest) String() string { return proto.CompactTextString(m) } -func (*RoleGetRequest) ProtoMessage() {} +func (m *AuthRoleGetRequest) Reset() { *m = AuthRoleGetRequest{} } +func (m *AuthRoleGetRequest) String() string { return proto.CompactTextString(m) } +func (*AuthRoleGetRequest) ProtoMessage() {} -type RoleDeleteRequest struct { +type AuthRoleDeleteRequest struct { } -func (m *RoleDeleteRequest) Reset() { *m = RoleDeleteRequest{} } -func (m *RoleDeleteRequest) String() string { return proto.CompactTextString(m) } -func (*RoleDeleteRequest) ProtoMessage() {} +func (m *AuthRoleDeleteRequest) Reset() { *m = AuthRoleDeleteRequest{} } +func (m *AuthRoleDeleteRequest) String() string { return proto.CompactTextString(m) } +func (*AuthRoleDeleteRequest) ProtoMessage() {} -type RoleGrantRequest struct { +type AuthRoleGrantRequest struct { } -func (m *RoleGrantRequest) Reset() { *m = RoleGrantRequest{} } -func (m *RoleGrantRequest) String() string { return proto.CompactTextString(m) } -func (*RoleGrantRequest) ProtoMessage() {} +func (m *AuthRoleGrantRequest) Reset() { *m = AuthRoleGrantRequest{} } +func (m *AuthRoleGrantRequest) String() string { return proto.CompactTextString(m) } +func (*AuthRoleGrantRequest) ProtoMessage() {} -type RoleRevokeRequest struct { +type AuthRoleRevokeRequest struct { } -func (m *RoleRevokeRequest) Reset() { *m = RoleRevokeRequest{} } -func (m *RoleRevokeRequest) String() string { return proto.CompactTextString(m) } -func (*RoleRevokeRequest) ProtoMessage() {} +func (m *AuthRoleRevokeRequest) Reset() { *m = AuthRoleRevokeRequest{} } +func (m *AuthRoleRevokeRequest) String() string { return proto.CompactTextString(m) } +func (*AuthRoleRevokeRequest) ProtoMessage() {} type AuthEnableResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` @@ -1302,165 +1420,165 @@ func (m *AuthenticateResponse) GetHeader() *ResponseHeader { return nil } -type UserAddResponse struct { +type AuthUserAddResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *UserAddResponse) Reset() { *m = UserAddResponse{} } -func (m *UserAddResponse) String() string { return proto.CompactTextString(m) } -func (*UserAddResponse) ProtoMessage() {} +func (m *AuthUserAddResponse) Reset() { *m = AuthUserAddResponse{} } +func (m *AuthUserAddResponse) String() string { return proto.CompactTextString(m) } +func (*AuthUserAddResponse) ProtoMessage() {} -func (m *UserAddResponse) GetHeader() *ResponseHeader { +func (m *AuthUserAddResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } return nil } -type UserGetResponse struct { +type AuthUserGetResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *UserGetResponse) Reset() { *m = UserGetResponse{} } -func (m *UserGetResponse) String() string { return proto.CompactTextString(m) } -func (*UserGetResponse) ProtoMessage() {} +func (m *AuthUserGetResponse) Reset() { *m = AuthUserGetResponse{} } +func (m *AuthUserGetResponse) String() string { return proto.CompactTextString(m) } +func (*AuthUserGetResponse) ProtoMessage() {} -func (m *UserGetResponse) GetHeader() *ResponseHeader { +func (m *AuthUserGetResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } return nil } -type UserDeleteResponse struct { +type AuthUserDeleteResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *UserDeleteResponse) Reset() { *m = UserDeleteResponse{} } -func (m *UserDeleteResponse) String() string { return proto.CompactTextString(m) } -func (*UserDeleteResponse) ProtoMessage() {} +func (m *AuthUserDeleteResponse) Reset() { *m = AuthUserDeleteResponse{} } +func (m *AuthUserDeleteResponse) String() string { return proto.CompactTextString(m) } +func (*AuthUserDeleteResponse) ProtoMessage() {} -func (m *UserDeleteResponse) GetHeader() *ResponseHeader { +func (m *AuthUserDeleteResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } return nil } -type UserChangePasswordResponse struct { +type AuthUserChangePasswordResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *UserChangePasswordResponse) Reset() { *m = UserChangePasswordResponse{} } -func (m *UserChangePasswordResponse) String() string { return proto.CompactTextString(m) } -func (*UserChangePasswordResponse) ProtoMessage() {} +func (m *AuthUserChangePasswordResponse) Reset() { *m = AuthUserChangePasswordResponse{} } +func (m *AuthUserChangePasswordResponse) String() string { return proto.CompactTextString(m) } +func (*AuthUserChangePasswordResponse) ProtoMessage() {} -func (m *UserChangePasswordResponse) GetHeader() *ResponseHeader { +func (m *AuthUserChangePasswordResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } return nil } -type UserGrantResponse struct { +type AuthUserGrantResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *UserGrantResponse) Reset() { *m = UserGrantResponse{} } -func (m *UserGrantResponse) String() string { return proto.CompactTextString(m) } -func (*UserGrantResponse) ProtoMessage() {} +func (m *AuthUserGrantResponse) Reset() { *m = AuthUserGrantResponse{} } +func (m *AuthUserGrantResponse) String() string { return proto.CompactTextString(m) } +func (*AuthUserGrantResponse) ProtoMessage() {} -func (m *UserGrantResponse) GetHeader() *ResponseHeader { +func (m *AuthUserGrantResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } return nil } -type UserRevokeResponse struct { +type AuthUserRevokeResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *UserRevokeResponse) Reset() { *m = UserRevokeResponse{} } -func (m *UserRevokeResponse) String() string { return proto.CompactTextString(m) } -func (*UserRevokeResponse) ProtoMessage() {} +func (m *AuthUserRevokeResponse) Reset() { *m = AuthUserRevokeResponse{} } +func (m *AuthUserRevokeResponse) String() string { return proto.CompactTextString(m) } +func (*AuthUserRevokeResponse) ProtoMessage() {} -func (m *UserRevokeResponse) GetHeader() *ResponseHeader { +func (m *AuthUserRevokeResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } return nil } -type RoleAddResponse struct { +type AuthRoleAddResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *RoleAddResponse) Reset() { *m = RoleAddResponse{} } -func (m *RoleAddResponse) String() string { return proto.CompactTextString(m) } -func (*RoleAddResponse) ProtoMessage() {} +func (m *AuthRoleAddResponse) Reset() { *m = AuthRoleAddResponse{} } +func (m *AuthRoleAddResponse) String() string { return proto.CompactTextString(m) } +func (*AuthRoleAddResponse) ProtoMessage() {} -func (m *RoleAddResponse) GetHeader() *ResponseHeader { +func (m *AuthRoleAddResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } return nil } -type RoleGetResponse struct { +type AuthRoleGetResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *RoleGetResponse) Reset() { *m = RoleGetResponse{} } -func (m *RoleGetResponse) String() string { return proto.CompactTextString(m) } -func (*RoleGetResponse) ProtoMessage() {} +func (m *AuthRoleGetResponse) Reset() { *m = AuthRoleGetResponse{} } +func (m *AuthRoleGetResponse) String() string { return proto.CompactTextString(m) } +func (*AuthRoleGetResponse) ProtoMessage() {} -func (m *RoleGetResponse) GetHeader() *ResponseHeader { +func (m *AuthRoleGetResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } return nil } -type RoleDeleteResponse struct { +type AuthRoleDeleteResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *RoleDeleteResponse) Reset() { *m = RoleDeleteResponse{} } -func (m *RoleDeleteResponse) String() string { return proto.CompactTextString(m) } -func (*RoleDeleteResponse) ProtoMessage() {} +func (m *AuthRoleDeleteResponse) Reset() { *m = AuthRoleDeleteResponse{} } +func (m *AuthRoleDeleteResponse) String() string { return proto.CompactTextString(m) } +func (*AuthRoleDeleteResponse) ProtoMessage() {} -func (m *RoleDeleteResponse) GetHeader() *ResponseHeader { +func (m *AuthRoleDeleteResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } return nil } -type RoleGrantResponse struct { +type AuthRoleGrantResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *RoleGrantResponse) Reset() { *m = RoleGrantResponse{} } -func (m *RoleGrantResponse) String() string { return proto.CompactTextString(m) } -func (*RoleGrantResponse) ProtoMessage() {} +func (m *AuthRoleGrantResponse) Reset() { *m = AuthRoleGrantResponse{} } +func (m *AuthRoleGrantResponse) String() string { return proto.CompactTextString(m) } +func (*AuthRoleGrantResponse) ProtoMessage() {} -func (m *RoleGrantResponse) GetHeader() *ResponseHeader { +func (m *AuthRoleGrantResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } return nil } -type RoleRevokeResponse struct { +type AuthRoleRevokeResponse struct { Header *ResponseHeader `protobuf:"bytes,1,opt,name=header" json:"header,omitempty"` } -func (m *RoleRevokeResponse) Reset() { *m = RoleRevokeResponse{} } -func (m *RoleRevokeResponse) String() string { return proto.CompactTextString(m) } -func (*RoleRevokeResponse) ProtoMessage() {} +func (m *AuthRoleRevokeResponse) Reset() { *m = AuthRoleRevokeResponse{} } +func (m *AuthRoleRevokeResponse) String() string { return proto.CompactTextString(m) } +func (*AuthRoleRevokeResponse) ProtoMessage() {} -func (m *RoleRevokeResponse) GetHeader() *ResponseHeader { +func (m *AuthRoleRevokeResponse) GetHeader() *ResponseHeader { if m != nil { return m.Header } @@ -1488,8 +1606,8 @@ func init() { proto.RegisterType((*WatchCreateRequest)(nil), "etcdserverpb.WatchCreateRequest") proto.RegisterType((*WatchCancelRequest)(nil), "etcdserverpb.WatchCancelRequest") proto.RegisterType((*WatchResponse)(nil), "etcdserverpb.WatchResponse") - proto.RegisterType((*LeaseCreateRequest)(nil), "etcdserverpb.LeaseCreateRequest") - proto.RegisterType((*LeaseCreateResponse)(nil), "etcdserverpb.LeaseCreateResponse") + proto.RegisterType((*LeaseGrantRequest)(nil), "etcdserverpb.LeaseGrantRequest") + proto.RegisterType((*LeaseGrantResponse)(nil), "etcdserverpb.LeaseGrantResponse") proto.RegisterType((*LeaseRevokeRequest)(nil), "etcdserverpb.LeaseRevokeRequest") proto.RegisterType((*LeaseRevokeResponse)(nil), "etcdserverpb.LeaseRevokeResponse") proto.RegisterType((*LeaseKeepAliveRequest)(nil), "etcdserverpb.LeaseKeepAliveRequest") @@ -1505,38 +1623,45 @@ func init() { proto.RegisterType((*MemberListResponse)(nil), "etcdserverpb.MemberListResponse") proto.RegisterType((*DefragmentRequest)(nil), "etcdserverpb.DefragmentRequest") proto.RegisterType((*DefragmentResponse)(nil), "etcdserverpb.DefragmentResponse") + proto.RegisterType((*AlarmRequest)(nil), "etcdserverpb.AlarmRequest") + proto.RegisterType((*AlarmMember)(nil), "etcdserverpb.AlarmMember") + proto.RegisterType((*AlarmResponse)(nil), "etcdserverpb.AlarmResponse") + proto.RegisterType((*StatusRequest)(nil), "etcdserverpb.StatusRequest") + proto.RegisterType((*StatusResponse)(nil), "etcdserverpb.StatusResponse") proto.RegisterType((*AuthEnableRequest)(nil), "etcdserverpb.AuthEnableRequest") proto.RegisterType((*AuthDisableRequest)(nil), "etcdserverpb.AuthDisableRequest") proto.RegisterType((*AuthenticateRequest)(nil), "etcdserverpb.AuthenticateRequest") - proto.RegisterType((*UserAddRequest)(nil), "etcdserverpb.UserAddRequest") - proto.RegisterType((*UserGetRequest)(nil), "etcdserverpb.UserGetRequest") - proto.RegisterType((*UserDeleteRequest)(nil), "etcdserverpb.UserDeleteRequest") - proto.RegisterType((*UserChangePasswordRequest)(nil), "etcdserverpb.UserChangePasswordRequest") - proto.RegisterType((*UserGrantRequest)(nil), "etcdserverpb.UserGrantRequest") - proto.RegisterType((*UserRevokeRequest)(nil), "etcdserverpb.UserRevokeRequest") - proto.RegisterType((*RoleAddRequest)(nil), "etcdserverpb.RoleAddRequest") - proto.RegisterType((*RoleGetRequest)(nil), "etcdserverpb.RoleGetRequest") - proto.RegisterType((*RoleDeleteRequest)(nil), "etcdserverpb.RoleDeleteRequest") - proto.RegisterType((*RoleGrantRequest)(nil), "etcdserverpb.RoleGrantRequest") - proto.RegisterType((*RoleRevokeRequest)(nil), "etcdserverpb.RoleRevokeRequest") + proto.RegisterType((*AuthUserAddRequest)(nil), "etcdserverpb.AuthUserAddRequest") + proto.RegisterType((*AuthUserGetRequest)(nil), "etcdserverpb.AuthUserGetRequest") + proto.RegisterType((*AuthUserDeleteRequest)(nil), "etcdserverpb.AuthUserDeleteRequest") + proto.RegisterType((*AuthUserChangePasswordRequest)(nil), "etcdserverpb.AuthUserChangePasswordRequest") + proto.RegisterType((*AuthUserGrantRequest)(nil), "etcdserverpb.AuthUserGrantRequest") + proto.RegisterType((*AuthUserRevokeRequest)(nil), "etcdserverpb.AuthUserRevokeRequest") + proto.RegisterType((*AuthRoleAddRequest)(nil), "etcdserverpb.AuthRoleAddRequest") + proto.RegisterType((*AuthRoleGetRequest)(nil), "etcdserverpb.AuthRoleGetRequest") + proto.RegisterType((*AuthRoleDeleteRequest)(nil), "etcdserverpb.AuthRoleDeleteRequest") + proto.RegisterType((*AuthRoleGrantRequest)(nil), "etcdserverpb.AuthRoleGrantRequest") + proto.RegisterType((*AuthRoleRevokeRequest)(nil), "etcdserverpb.AuthRoleRevokeRequest") proto.RegisterType((*AuthEnableResponse)(nil), "etcdserverpb.AuthEnableResponse") proto.RegisterType((*AuthDisableResponse)(nil), "etcdserverpb.AuthDisableResponse") proto.RegisterType((*AuthenticateResponse)(nil), "etcdserverpb.AuthenticateResponse") - proto.RegisterType((*UserAddResponse)(nil), "etcdserverpb.UserAddResponse") - proto.RegisterType((*UserGetResponse)(nil), "etcdserverpb.UserGetResponse") - proto.RegisterType((*UserDeleteResponse)(nil), "etcdserverpb.UserDeleteResponse") - proto.RegisterType((*UserChangePasswordResponse)(nil), "etcdserverpb.UserChangePasswordResponse") - proto.RegisterType((*UserGrantResponse)(nil), "etcdserverpb.UserGrantResponse") - proto.RegisterType((*UserRevokeResponse)(nil), "etcdserverpb.UserRevokeResponse") - proto.RegisterType((*RoleAddResponse)(nil), "etcdserverpb.RoleAddResponse") - proto.RegisterType((*RoleGetResponse)(nil), "etcdserverpb.RoleGetResponse") - proto.RegisterType((*RoleDeleteResponse)(nil), "etcdserverpb.RoleDeleteResponse") - proto.RegisterType((*RoleGrantResponse)(nil), "etcdserverpb.RoleGrantResponse") - proto.RegisterType((*RoleRevokeResponse)(nil), "etcdserverpb.RoleRevokeResponse") + proto.RegisterType((*AuthUserAddResponse)(nil), "etcdserverpb.AuthUserAddResponse") + proto.RegisterType((*AuthUserGetResponse)(nil), "etcdserverpb.AuthUserGetResponse") + proto.RegisterType((*AuthUserDeleteResponse)(nil), "etcdserverpb.AuthUserDeleteResponse") + proto.RegisterType((*AuthUserChangePasswordResponse)(nil), "etcdserverpb.AuthUserChangePasswordResponse") + proto.RegisterType((*AuthUserGrantResponse)(nil), "etcdserverpb.AuthUserGrantResponse") + proto.RegisterType((*AuthUserRevokeResponse)(nil), "etcdserverpb.AuthUserRevokeResponse") + proto.RegisterType((*AuthRoleAddResponse)(nil), "etcdserverpb.AuthRoleAddResponse") + proto.RegisterType((*AuthRoleGetResponse)(nil), "etcdserverpb.AuthRoleGetResponse") + proto.RegisterType((*AuthRoleDeleteResponse)(nil), "etcdserverpb.AuthRoleDeleteResponse") + proto.RegisterType((*AuthRoleGrantResponse)(nil), "etcdserverpb.AuthRoleGrantResponse") + proto.RegisterType((*AuthRoleRevokeResponse)(nil), "etcdserverpb.AuthRoleRevokeResponse") + proto.RegisterEnum("etcdserverpb.AlarmType", AlarmType_name, AlarmType_value) proto.RegisterEnum("etcdserverpb.RangeRequest_SortOrder", RangeRequest_SortOrder_name, RangeRequest_SortOrder_value) proto.RegisterEnum("etcdserverpb.RangeRequest_SortTarget", RangeRequest_SortTarget_name, RangeRequest_SortTarget_value) proto.RegisterEnum("etcdserverpb.Compare_CompareResult", Compare_CompareResult_name, Compare_CompareResult_value) proto.RegisterEnum("etcdserverpb.Compare_CompareTarget", Compare_CompareTarget_name, Compare_CompareTarget_value) + proto.RegisterEnum("etcdserverpb.AlarmRequest_AlarmAction", AlarmRequest_AlarmAction_name, AlarmRequest_AlarmAction_value) } // Reference imports to suppress errors if they are not otherwise used. @@ -1564,10 +1689,6 @@ type KVClient interface { // Compact compacts the event history in etcd. User should compact the // event history periodically, or it will grow infinitely. Compact(ctx context.Context, in *CompactionRequest, opts ...grpc.CallOption) (*CompactionResponse, error) - // Hash returns the hash of local KV state for consistency checking purpose. - // This is designed for testing purpose. Do not use this in production when there - // are ongoing transactions. - Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) } type kVClient struct { @@ -1623,15 +1744,6 @@ func (c *kVClient) Compact(ctx context.Context, in *CompactionRequest, opts ...g return out, nil } -func (c *kVClient) Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) { - out := new(HashResponse) - err := grpc.Invoke(ctx, "/etcdserverpb.KV/Hash", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - // Server API for KV service type KVServer interface { @@ -1653,10 +1765,6 @@ type KVServer interface { // Compact compacts the event history in etcd. User should compact the // event history periodically, or it will grow infinitely. Compact(context.Context, *CompactionRequest) (*CompactionResponse, error) - // Hash returns the hash of local KV state for consistency checking purpose. - // This is designed for testing purpose. Do not use this in production when there - // are ongoing transactions. - Hash(context.Context, *HashRequest) (*HashResponse, error) } func RegisterKVServer(s *grpc.Server, srv KVServer) { @@ -1723,18 +1831,6 @@ func _KV_Compact_Handler(srv interface{}, ctx context.Context, dec func(interfac return out, nil } -func _KV_Hash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(HashRequest) - if err := dec(in); err != nil { - return nil, err - } - out, err := srv.(KVServer).Hash(ctx, in) - if err != nil { - return nil, err - } - return out, nil -} - var _KV_serviceDesc = grpc.ServiceDesc{ ServiceName: "etcdserverpb.KV", HandlerType: (*KVServer)(nil), @@ -1759,10 +1855,6 @@ var _KV_serviceDesc = grpc.ServiceDesc{ MethodName: "Compact", Handler: _KV_Compact_Handler, }, - { - MethodName: "Hash", - Handler: _KV_Hash_Handler, - }, }, Streams: []grpc.StreamDesc{}, } @@ -1873,11 +1965,11 @@ var _Watch_serviceDesc = grpc.ServiceDesc{ // Client API for Lease service type LeaseClient interface { - // LeaseCreate creates a lease. A lease has a TTL. The lease will expire if the + // LeaseGrant creates a lease. A lease has a TTL. The lease will expire if the // server does not receive a keepAlive within TTL from the lease holder. // All keys attached to the lease will be expired and deleted if the lease expires. // The key expiration generates an event in event history. - LeaseCreate(ctx context.Context, in *LeaseCreateRequest, opts ...grpc.CallOption) (*LeaseCreateResponse, error) + LeaseGrant(ctx context.Context, in *LeaseGrantRequest, opts ...grpc.CallOption) (*LeaseGrantResponse, error) // LeaseRevoke revokes a lease. All the key attached to the lease will be expired and deleted. LeaseRevoke(ctx context.Context, in *LeaseRevokeRequest, opts ...grpc.CallOption) (*LeaseRevokeResponse, error) // KeepAlive keeps the lease alive. @@ -1892,9 +1984,9 @@ func NewLeaseClient(cc *grpc.ClientConn) LeaseClient { return &leaseClient{cc} } -func (c *leaseClient) LeaseCreate(ctx context.Context, in *LeaseCreateRequest, opts ...grpc.CallOption) (*LeaseCreateResponse, error) { - out := new(LeaseCreateResponse) - err := grpc.Invoke(ctx, "/etcdserverpb.Lease/LeaseCreate", in, out, c.cc, opts...) +func (c *leaseClient) LeaseGrant(ctx context.Context, in *LeaseGrantRequest, opts ...grpc.CallOption) (*LeaseGrantResponse, error) { + out := new(LeaseGrantResponse) + err := grpc.Invoke(ctx, "/etcdserverpb.Lease/LeaseGrant", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -1944,11 +2036,11 @@ func (x *leaseLeaseKeepAliveClient) Recv() (*LeaseKeepAliveResponse, error) { // Server API for Lease service type LeaseServer interface { - // LeaseCreate creates a lease. A lease has a TTL. The lease will expire if the + // LeaseGrant creates a lease. A lease has a TTL. The lease will expire if the // server does not receive a keepAlive within TTL from the lease holder. // All keys attached to the lease will be expired and deleted if the lease expires. // The key expiration generates an event in event history. - LeaseCreate(context.Context, *LeaseCreateRequest) (*LeaseCreateResponse, error) + LeaseGrant(context.Context, *LeaseGrantRequest) (*LeaseGrantResponse, error) // LeaseRevoke revokes a lease. All the key attached to the lease will be expired and deleted. LeaseRevoke(context.Context, *LeaseRevokeRequest) (*LeaseRevokeResponse, error) // KeepAlive keeps the lease alive. @@ -1959,12 +2051,12 @@ func RegisterLeaseServer(s *grpc.Server, srv LeaseServer) { s.RegisterService(&_Lease_serviceDesc, srv) } -func _Lease_LeaseCreate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(LeaseCreateRequest) +func _Lease_LeaseGrant_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { + in := new(LeaseGrantRequest) if err := dec(in); err != nil { return nil, err } - out, err := srv.(LeaseServer).LeaseCreate(ctx, in) + out, err := srv.(LeaseServer).LeaseGrant(ctx, in) if err != nil { return nil, err } @@ -2014,8 +2106,8 @@ var _Lease_serviceDesc = grpc.ServiceDesc{ HandlerType: (*LeaseServer)(nil), Methods: []grpc.MethodDesc{ { - MethodName: "LeaseCreate", - Handler: _Lease_LeaseCreate_Handler, + MethodName: "LeaseGrant", + Handler: _Lease_LeaseGrant_Handler, }, { MethodName: "LeaseRevoke", @@ -2181,8 +2273,15 @@ var _Cluster_serviceDesc = grpc.ServiceDesc{ // Client API for Maintenance service type MaintenanceClient interface { - // TODO: move Hash from kv to Maintenance + // Alarm activates, deactivates, and queries alarms regarding cluster health. + Alarm(ctx context.Context, in *AlarmRequest, opts ...grpc.CallOption) (*AlarmResponse, error) + // Status gets the status of the member. + Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) Defragment(ctx context.Context, in *DefragmentRequest, opts ...grpc.CallOption) (*DefragmentResponse, error) + // Hash returns the hash of the local KV state for consistency checking purpose. + // This is designed for testing; do not use this in production when there + // are ongoing transactions. + Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) } type maintenanceClient struct { @@ -2193,6 +2292,24 @@ func NewMaintenanceClient(cc *grpc.ClientConn) MaintenanceClient { return &maintenanceClient{cc} } +func (c *maintenanceClient) Alarm(ctx context.Context, in *AlarmRequest, opts ...grpc.CallOption) (*AlarmResponse, error) { + out := new(AlarmResponse) + err := grpc.Invoke(ctx, "/etcdserverpb.Maintenance/Alarm", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *maintenanceClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) { + out := new(StatusResponse) + err := grpc.Invoke(ctx, "/etcdserverpb.Maintenance/Status", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *maintenanceClient) Defragment(ctx context.Context, in *DefragmentRequest, opts ...grpc.CallOption) (*DefragmentResponse, error) { out := new(DefragmentResponse) err := grpc.Invoke(ctx, "/etcdserverpb.Maintenance/Defragment", in, out, c.cc, opts...) @@ -2202,17 +2319,57 @@ func (c *maintenanceClient) Defragment(ctx context.Context, in *DefragmentReques return out, nil } +func (c *maintenanceClient) Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) { + out := new(HashResponse) + err := grpc.Invoke(ctx, "/etcdserverpb.Maintenance/Hash", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for Maintenance service type MaintenanceServer interface { - // TODO: move Hash from kv to Maintenance + // Alarm activates, deactivates, and queries alarms regarding cluster health. + Alarm(context.Context, *AlarmRequest) (*AlarmResponse, error) + // Status gets the status of the member. + Status(context.Context, *StatusRequest) (*StatusResponse, error) Defragment(context.Context, *DefragmentRequest) (*DefragmentResponse, error) + // Hash returns the hash of the local KV state for consistency checking purpose. + // This is designed for testing; do not use this in production when there + // are ongoing transactions. + Hash(context.Context, *HashRequest) (*HashResponse, error) } func RegisterMaintenanceServer(s *grpc.Server, srv MaintenanceServer) { s.RegisterService(&_Maintenance_serviceDesc, srv) } +func _Maintenance_Alarm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { + in := new(AlarmRequest) + if err := dec(in); err != nil { + return nil, err + } + out, err := srv.(MaintenanceServer).Alarm(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + +func _Maintenance_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { + in := new(StatusRequest) + if err := dec(in); err != nil { + return nil, err + } + out, err := srv.(MaintenanceServer).Status(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + func _Maintenance_Defragment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { in := new(DefragmentRequest) if err := dec(in); err != nil { @@ -2225,14 +2382,38 @@ func _Maintenance_Defragment_Handler(srv interface{}, ctx context.Context, dec f return out, nil } +func _Maintenance_Hash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { + in := new(HashRequest) + if err := dec(in); err != nil { + return nil, err + } + out, err := srv.(MaintenanceServer).Hash(ctx, in) + if err != nil { + return nil, err + } + return out, nil +} + var _Maintenance_serviceDesc = grpc.ServiceDesc{ ServiceName: "etcdserverpb.Maintenance", HandlerType: (*MaintenanceServer)(nil), Methods: []grpc.MethodDesc{ + { + MethodName: "Alarm", + Handler: _Maintenance_Alarm_Handler, + }, + { + MethodName: "Status", + Handler: _Maintenance_Status_Handler, + }, { MethodName: "Defragment", Handler: _Maintenance_Defragment_Handler, }, + { + MethodName: "Hash", + Handler: _Maintenance_Hash_Handler, + }, }, Streams: []grpc.StreamDesc{}, } @@ -2247,27 +2428,27 @@ type AuthClient interface { // Authenticate processes authenticate request. Authenticate(ctx context.Context, in *AuthenticateRequest, opts ...grpc.CallOption) (*AuthenticateResponse, error) // UserAdd adds a new user. - UserAdd(ctx context.Context, in *UserAddRequest, opts ...grpc.CallOption) (*UserAddResponse, error) + UserAdd(ctx context.Context, in *AuthUserAddRequest, opts ...grpc.CallOption) (*AuthUserAddResponse, error) // UserGet gets a detailed information of a user or lists entire users. - UserGet(ctx context.Context, in *UserGetRequest, opts ...grpc.CallOption) (*UserGetResponse, error) + UserGet(ctx context.Context, in *AuthUserGetRequest, opts ...grpc.CallOption) (*AuthUserGetResponse, error) // UserDelete deletes a specified user. - UserDelete(ctx context.Context, in *UserDeleteRequest, opts ...grpc.CallOption) (*UserDeleteResponse, error) + UserDelete(ctx context.Context, in *AuthUserDeleteRequest, opts ...grpc.CallOption) (*AuthUserDeleteResponse, error) // UserChangePassword changes password of a specified user. - UserChangePassword(ctx context.Context, in *UserChangePasswordRequest, opts ...grpc.CallOption) (*UserChangePasswordResponse, error) + UserChangePassword(ctx context.Context, in *AuthUserChangePasswordRequest, opts ...grpc.CallOption) (*AuthUserChangePasswordResponse, error) // UserGrant grants a role to a specified user. - UserGrant(ctx context.Context, in *UserGrantRequest, opts ...grpc.CallOption) (*UserGrantResponse, error) + UserGrant(ctx context.Context, in *AuthUserGrantRequest, opts ...grpc.CallOption) (*AuthUserGrantResponse, error) // UserRevoke revokes a role of specified user. - UserRevoke(ctx context.Context, in *UserRevokeRequest, opts ...grpc.CallOption) (*UserRevokeResponse, error) + UserRevoke(ctx context.Context, in *AuthUserRevokeRequest, opts ...grpc.CallOption) (*AuthUserRevokeResponse, error) // RoleAdd adds a new role. - RoleAdd(ctx context.Context, in *RoleAddRequest, opts ...grpc.CallOption) (*RoleAddResponse, error) + RoleAdd(ctx context.Context, in *AuthRoleAddRequest, opts ...grpc.CallOption) (*AuthRoleAddResponse, error) // RoleGet gets a detailed information of a role or lists entire roles. - RoleGet(ctx context.Context, in *RoleGetRequest, opts ...grpc.CallOption) (*RoleGetResponse, error) + RoleGet(ctx context.Context, in *AuthRoleGetRequest, opts ...grpc.CallOption) (*AuthRoleGetResponse, error) // RoleDelete deletes a specified role. - RoleDelete(ctx context.Context, in *RoleDeleteRequest, opts ...grpc.CallOption) (*RoleDeleteResponse, error) + RoleDelete(ctx context.Context, in *AuthRoleDeleteRequest, opts ...grpc.CallOption) (*AuthRoleDeleteResponse, error) // RoleGrant grants a permission of a specified key or range to a specified role. - RoleGrant(ctx context.Context, in *RoleGrantRequest, opts ...grpc.CallOption) (*RoleGrantResponse, error) + RoleGrant(ctx context.Context, in *AuthRoleGrantRequest, opts ...grpc.CallOption) (*AuthRoleGrantResponse, error) // RoleRevoke revokes a key or range permission of a specified role. - RoleRevoke(ctx context.Context, in *RoleRevokeRequest, opts ...grpc.CallOption) (*RoleRevokeResponse, error) + RoleRevoke(ctx context.Context, in *AuthRoleRevokeRequest, opts ...grpc.CallOption) (*AuthRoleRevokeResponse, error) } type authClient struct { @@ -2305,8 +2486,8 @@ func (c *authClient) Authenticate(ctx context.Context, in *AuthenticateRequest, return out, nil } -func (c *authClient) UserAdd(ctx context.Context, in *UserAddRequest, opts ...grpc.CallOption) (*UserAddResponse, error) { - out := new(UserAddResponse) +func (c *authClient) UserAdd(ctx context.Context, in *AuthUserAddRequest, opts ...grpc.CallOption) (*AuthUserAddResponse, error) { + out := new(AuthUserAddResponse) err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserAdd", in, out, c.cc, opts...) if err != nil { return nil, err @@ -2314,8 +2495,8 @@ func (c *authClient) UserAdd(ctx context.Context, in *UserAddRequest, opts ...gr return out, nil } -func (c *authClient) UserGet(ctx context.Context, in *UserGetRequest, opts ...grpc.CallOption) (*UserGetResponse, error) { - out := new(UserGetResponse) +func (c *authClient) UserGet(ctx context.Context, in *AuthUserGetRequest, opts ...grpc.CallOption) (*AuthUserGetResponse, error) { + out := new(AuthUserGetResponse) err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserGet", in, out, c.cc, opts...) if err != nil { return nil, err @@ -2323,8 +2504,8 @@ func (c *authClient) UserGet(ctx context.Context, in *UserGetRequest, opts ...gr return out, nil } -func (c *authClient) UserDelete(ctx context.Context, in *UserDeleteRequest, opts ...grpc.CallOption) (*UserDeleteResponse, error) { - out := new(UserDeleteResponse) +func (c *authClient) UserDelete(ctx context.Context, in *AuthUserDeleteRequest, opts ...grpc.CallOption) (*AuthUserDeleteResponse, error) { + out := new(AuthUserDeleteResponse) err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserDelete", in, out, c.cc, opts...) if err != nil { return nil, err @@ -2332,8 +2513,8 @@ func (c *authClient) UserDelete(ctx context.Context, in *UserDeleteRequest, opts return out, nil } -func (c *authClient) UserChangePassword(ctx context.Context, in *UserChangePasswordRequest, opts ...grpc.CallOption) (*UserChangePasswordResponse, error) { - out := new(UserChangePasswordResponse) +func (c *authClient) UserChangePassword(ctx context.Context, in *AuthUserChangePasswordRequest, opts ...grpc.CallOption) (*AuthUserChangePasswordResponse, error) { + out := new(AuthUserChangePasswordResponse) err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserChangePassword", in, out, c.cc, opts...) if err != nil { return nil, err @@ -2341,8 +2522,8 @@ func (c *authClient) UserChangePassword(ctx context.Context, in *UserChangePassw return out, nil } -func (c *authClient) UserGrant(ctx context.Context, in *UserGrantRequest, opts ...grpc.CallOption) (*UserGrantResponse, error) { - out := new(UserGrantResponse) +func (c *authClient) UserGrant(ctx context.Context, in *AuthUserGrantRequest, opts ...grpc.CallOption) (*AuthUserGrantResponse, error) { + out := new(AuthUserGrantResponse) err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserGrant", in, out, c.cc, opts...) if err != nil { return nil, err @@ -2350,8 +2531,8 @@ func (c *authClient) UserGrant(ctx context.Context, in *UserGrantRequest, opts . return out, nil } -func (c *authClient) UserRevoke(ctx context.Context, in *UserRevokeRequest, opts ...grpc.CallOption) (*UserRevokeResponse, error) { - out := new(UserRevokeResponse) +func (c *authClient) UserRevoke(ctx context.Context, in *AuthUserRevokeRequest, opts ...grpc.CallOption) (*AuthUserRevokeResponse, error) { + out := new(AuthUserRevokeResponse) err := grpc.Invoke(ctx, "/etcdserverpb.Auth/UserRevoke", in, out, c.cc, opts...) if err != nil { return nil, err @@ -2359,8 +2540,8 @@ func (c *authClient) UserRevoke(ctx context.Context, in *UserRevokeRequest, opts return out, nil } -func (c *authClient) RoleAdd(ctx context.Context, in *RoleAddRequest, opts ...grpc.CallOption) (*RoleAddResponse, error) { - out := new(RoleAddResponse) +func (c *authClient) RoleAdd(ctx context.Context, in *AuthRoleAddRequest, opts ...grpc.CallOption) (*AuthRoleAddResponse, error) { + out := new(AuthRoleAddResponse) err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleAdd", in, out, c.cc, opts...) if err != nil { return nil, err @@ -2368,8 +2549,8 @@ func (c *authClient) RoleAdd(ctx context.Context, in *RoleAddRequest, opts ...gr return out, nil } -func (c *authClient) RoleGet(ctx context.Context, in *RoleGetRequest, opts ...grpc.CallOption) (*RoleGetResponse, error) { - out := new(RoleGetResponse) +func (c *authClient) RoleGet(ctx context.Context, in *AuthRoleGetRequest, opts ...grpc.CallOption) (*AuthRoleGetResponse, error) { + out := new(AuthRoleGetResponse) err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleGet", in, out, c.cc, opts...) if err != nil { return nil, err @@ -2377,8 +2558,8 @@ func (c *authClient) RoleGet(ctx context.Context, in *RoleGetRequest, opts ...gr return out, nil } -func (c *authClient) RoleDelete(ctx context.Context, in *RoleDeleteRequest, opts ...grpc.CallOption) (*RoleDeleteResponse, error) { - out := new(RoleDeleteResponse) +func (c *authClient) RoleDelete(ctx context.Context, in *AuthRoleDeleteRequest, opts ...grpc.CallOption) (*AuthRoleDeleteResponse, error) { + out := new(AuthRoleDeleteResponse) err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleDelete", in, out, c.cc, opts...) if err != nil { return nil, err @@ -2386,8 +2567,8 @@ func (c *authClient) RoleDelete(ctx context.Context, in *RoleDeleteRequest, opts return out, nil } -func (c *authClient) RoleGrant(ctx context.Context, in *RoleGrantRequest, opts ...grpc.CallOption) (*RoleGrantResponse, error) { - out := new(RoleGrantResponse) +func (c *authClient) RoleGrant(ctx context.Context, in *AuthRoleGrantRequest, opts ...grpc.CallOption) (*AuthRoleGrantResponse, error) { + out := new(AuthRoleGrantResponse) err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleGrant", in, out, c.cc, opts...) if err != nil { return nil, err @@ -2395,8 +2576,8 @@ func (c *authClient) RoleGrant(ctx context.Context, in *RoleGrantRequest, opts . return out, nil } -func (c *authClient) RoleRevoke(ctx context.Context, in *RoleRevokeRequest, opts ...grpc.CallOption) (*RoleRevokeResponse, error) { - out := new(RoleRevokeResponse) +func (c *authClient) RoleRevoke(ctx context.Context, in *AuthRoleRevokeRequest, opts ...grpc.CallOption) (*AuthRoleRevokeResponse, error) { + out := new(AuthRoleRevokeResponse) err := grpc.Invoke(ctx, "/etcdserverpb.Auth/RoleRevoke", in, out, c.cc, opts...) if err != nil { return nil, err @@ -2414,27 +2595,27 @@ type AuthServer interface { // Authenticate processes authenticate request. Authenticate(context.Context, *AuthenticateRequest) (*AuthenticateResponse, error) // UserAdd adds a new user. - UserAdd(context.Context, *UserAddRequest) (*UserAddResponse, error) + UserAdd(context.Context, *AuthUserAddRequest) (*AuthUserAddResponse, error) // UserGet gets a detailed information of a user or lists entire users. - UserGet(context.Context, *UserGetRequest) (*UserGetResponse, error) + UserGet(context.Context, *AuthUserGetRequest) (*AuthUserGetResponse, error) // UserDelete deletes a specified user. - UserDelete(context.Context, *UserDeleteRequest) (*UserDeleteResponse, error) + UserDelete(context.Context, *AuthUserDeleteRequest) (*AuthUserDeleteResponse, error) // UserChangePassword changes password of a specified user. - UserChangePassword(context.Context, *UserChangePasswordRequest) (*UserChangePasswordResponse, error) + UserChangePassword(context.Context, *AuthUserChangePasswordRequest) (*AuthUserChangePasswordResponse, error) // UserGrant grants a role to a specified user. - UserGrant(context.Context, *UserGrantRequest) (*UserGrantResponse, error) + UserGrant(context.Context, *AuthUserGrantRequest) (*AuthUserGrantResponse, error) // UserRevoke revokes a role of specified user. - UserRevoke(context.Context, *UserRevokeRequest) (*UserRevokeResponse, error) + UserRevoke(context.Context, *AuthUserRevokeRequest) (*AuthUserRevokeResponse, error) // RoleAdd adds a new role. - RoleAdd(context.Context, *RoleAddRequest) (*RoleAddResponse, error) + RoleAdd(context.Context, *AuthRoleAddRequest) (*AuthRoleAddResponse, error) // RoleGet gets a detailed information of a role or lists entire roles. - RoleGet(context.Context, *RoleGetRequest) (*RoleGetResponse, error) + RoleGet(context.Context, *AuthRoleGetRequest) (*AuthRoleGetResponse, error) // RoleDelete deletes a specified role. - RoleDelete(context.Context, *RoleDeleteRequest) (*RoleDeleteResponse, error) + RoleDelete(context.Context, *AuthRoleDeleteRequest) (*AuthRoleDeleteResponse, error) // RoleGrant grants a permission of a specified key or range to a specified role. - RoleGrant(context.Context, *RoleGrantRequest) (*RoleGrantResponse, error) + RoleGrant(context.Context, *AuthRoleGrantRequest) (*AuthRoleGrantResponse, error) // RoleRevoke revokes a key or range permission of a specified role. - RoleRevoke(context.Context, *RoleRevokeRequest) (*RoleRevokeResponse, error) + RoleRevoke(context.Context, *AuthRoleRevokeRequest) (*AuthRoleRevokeResponse, error) } func RegisterAuthServer(s *grpc.Server, srv AuthServer) { @@ -2478,7 +2659,7 @@ func _Auth_Authenticate_Handler(srv interface{}, ctx context.Context, dec func(i } func _Auth_UserAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(UserAddRequest) + in := new(AuthUserAddRequest) if err := dec(in); err != nil { return nil, err } @@ -2490,7 +2671,7 @@ func _Auth_UserAdd_Handler(srv interface{}, ctx context.Context, dec func(interf } func _Auth_UserGet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(UserGetRequest) + in := new(AuthUserGetRequest) if err := dec(in); err != nil { return nil, err } @@ -2502,7 +2683,7 @@ func _Auth_UserGet_Handler(srv interface{}, ctx context.Context, dec func(interf } func _Auth_UserDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(UserDeleteRequest) + in := new(AuthUserDeleteRequest) if err := dec(in); err != nil { return nil, err } @@ -2514,7 +2695,7 @@ func _Auth_UserDelete_Handler(srv interface{}, ctx context.Context, dec func(int } func _Auth_UserChangePassword_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(UserChangePasswordRequest) + in := new(AuthUserChangePasswordRequest) if err := dec(in); err != nil { return nil, err } @@ -2526,7 +2707,7 @@ func _Auth_UserChangePassword_Handler(srv interface{}, ctx context.Context, dec } func _Auth_UserGrant_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(UserGrantRequest) + in := new(AuthUserGrantRequest) if err := dec(in); err != nil { return nil, err } @@ -2538,7 +2719,7 @@ func _Auth_UserGrant_Handler(srv interface{}, ctx context.Context, dec func(inte } func _Auth_UserRevoke_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(UserRevokeRequest) + in := new(AuthUserRevokeRequest) if err := dec(in); err != nil { return nil, err } @@ -2550,7 +2731,7 @@ func _Auth_UserRevoke_Handler(srv interface{}, ctx context.Context, dec func(int } func _Auth_RoleAdd_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(RoleAddRequest) + in := new(AuthRoleAddRequest) if err := dec(in); err != nil { return nil, err } @@ -2562,7 +2743,7 @@ func _Auth_RoleAdd_Handler(srv interface{}, ctx context.Context, dec func(interf } func _Auth_RoleGet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(RoleGetRequest) + in := new(AuthRoleGetRequest) if err := dec(in); err != nil { return nil, err } @@ -2574,7 +2755,7 @@ func _Auth_RoleGet_Handler(srv interface{}, ctx context.Context, dec func(interf } func _Auth_RoleDelete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(RoleDeleteRequest) + in := new(AuthRoleDeleteRequest) if err := dec(in); err != nil { return nil, err } @@ -2586,7 +2767,7 @@ func _Auth_RoleDelete_Handler(srv interface{}, ctx context.Context, dec func(int } func _Auth_RoleGrant_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(RoleGrantRequest) + in := new(AuthRoleGrantRequest) if err := dec(in); err != nil { return nil, err } @@ -2598,7 +2779,7 @@ func _Auth_RoleGrant_Handler(srv interface{}, ctx context.Context, dec func(inte } func _Auth_RoleRevoke_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) { - in := new(RoleRevokeRequest) + in := new(AuthRoleRevokeRequest) if err := dec(in); err != nil { return nil, err } @@ -3291,6 +3472,16 @@ func (m *CompactionRequest) MarshalTo(data []byte) (int, error) { i++ i = encodeVarintRpc(data, i, uint64(m.Revision)) } + if m.Physical { + data[i] = 0x10 + i++ + if m.Physical { + data[i] = 1 + } else { + data[i] = 0 + } + i++ + } return i, nil } @@ -3568,7 +3759,7 @@ func (m *WatchResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *LeaseCreateRequest) Marshal() (data []byte, err error) { +func (m *LeaseGrantRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -3578,7 +3769,7 @@ func (m *LeaseCreateRequest) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *LeaseCreateRequest) MarshalTo(data []byte) (int, error) { +func (m *LeaseGrantRequest) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -3596,7 +3787,7 @@ func (m *LeaseCreateRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *LeaseCreateResponse) Marshal() (data []byte, err error) { +func (m *LeaseGrantResponse) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -3606,7 +3797,7 @@ func (m *LeaseCreateResponse) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *LeaseCreateResponse) MarshalTo(data []byte) (int, error) { +func (m *LeaseGrantResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4113,6 +4304,159 @@ func (m *DefragmentResponse) MarshalTo(data []byte) (int, error) { return i, nil } +func (m *AlarmRequest) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *AlarmRequest) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Action != 0 { + data[i] = 0x8 + i++ + i = encodeVarintRpc(data, i, uint64(m.Action)) + } + if m.MemberID != 0 { + data[i] = 0x10 + i++ + i = encodeVarintRpc(data, i, uint64(m.MemberID)) + } + if m.Alarm != 0 { + data[i] = 0x18 + i++ + i = encodeVarintRpc(data, i, uint64(m.Alarm)) + } + return i, nil +} + +func (m *AlarmMember) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *AlarmMember) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.MemberID != 0 { + data[i] = 0x8 + i++ + i = encodeVarintRpc(data, i, uint64(m.MemberID)) + } + if m.Alarm != 0 { + data[i] = 0x10 + i++ + i = encodeVarintRpc(data, i, uint64(m.Alarm)) + } + return i, nil +} + +func (m *AlarmResponse) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *AlarmResponse) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + data[i] = 0xa + i++ + i = encodeVarintRpc(data, i, uint64(m.Header.Size())) + n29, err := m.Header.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n29 + } + if len(m.Alarms) > 0 { + for _, msg := range m.Alarms { + data[i] = 0x12 + i++ + i = encodeVarintRpc(data, i, uint64(msg.Size())) + n, err := msg.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + +func (m *StatusRequest) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *StatusRequest) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + return i, nil +} + +func (m *StatusResponse) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *StatusResponse) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + data[i] = 0xa + i++ + i = encodeVarintRpc(data, i, uint64(m.Header.Size())) + n30, err := m.Header.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n30 + } + if len(m.Version) > 0 { + data[i] = 0x12 + i++ + i = encodeVarintRpc(data, i, uint64(len(m.Version))) + i += copy(data[i:], m.Version) + } + return i, nil +} + func (m *AuthEnableRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -4167,7 +4511,7 @@ func (m *AuthenticateRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *UserAddRequest) Marshal() (data []byte, err error) { +func (m *AuthUserAddRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4177,7 +4521,37 @@ func (m *UserAddRequest) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *UserAddRequest) MarshalTo(data []byte) (int, error) { +func (m *AuthUserAddRequest) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + data[i] = 0xa + i++ + i = encodeVarintRpc(data, i, uint64(len(m.Name))) + i += copy(data[i:], m.Name) + } + if len(m.Password) > 0 { + data[i] = 0x12 + i++ + i = encodeVarintRpc(data, i, uint64(len(m.Password))) + i += copy(data[i:], m.Password) + } + return i, nil +} + +func (m *AuthUserGetRequest) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *AuthUserGetRequest) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4185,7 +4559,7 @@ func (m *UserAddRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *UserGetRequest) Marshal() (data []byte, err error) { +func (m *AuthUserDeleteRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4195,7 +4569,61 @@ func (m *UserGetRequest) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *UserGetRequest) MarshalTo(data []byte) (int, error) { +func (m *AuthUserDeleteRequest) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + data[i] = 0xa + i++ + i = encodeVarintRpc(data, i, uint64(len(m.Name))) + i += copy(data[i:], m.Name) + } + return i, nil +} + +func (m *AuthUserChangePasswordRequest) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *AuthUserChangePasswordRequest) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + data[i] = 0xa + i++ + i = encodeVarintRpc(data, i, uint64(len(m.Name))) + i += copy(data[i:], m.Name) + } + if len(m.Password) > 0 { + data[i] = 0x12 + i++ + i = encodeVarintRpc(data, i, uint64(len(m.Password))) + i += copy(data[i:], m.Password) + } + return i, nil +} + +func (m *AuthUserGrantRequest) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *AuthUserGrantRequest) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4203,7 +4631,7 @@ func (m *UserGetRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *UserDeleteRequest) Marshal() (data []byte, err error) { +func (m *AuthUserRevokeRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4213,7 +4641,7 @@ func (m *UserDeleteRequest) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *UserDeleteRequest) MarshalTo(data []byte) (int, error) { +func (m *AuthUserRevokeRequest) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4221,7 +4649,7 @@ func (m *UserDeleteRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *UserChangePasswordRequest) Marshal() (data []byte, err error) { +func (m *AuthRoleAddRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4231,7 +4659,31 @@ func (m *UserChangePasswordRequest) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *UserChangePasswordRequest) MarshalTo(data []byte) (int, error) { +func (m *AuthRoleAddRequest) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Name) > 0 { + data[i] = 0xa + i++ + i = encodeVarintRpc(data, i, uint64(len(m.Name))) + i += copy(data[i:], m.Name) + } + return i, nil +} + +func (m *AuthRoleGetRequest) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *AuthRoleGetRequest) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4239,7 +4691,7 @@ func (m *UserChangePasswordRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *UserGrantRequest) Marshal() (data []byte, err error) { +func (m *AuthRoleDeleteRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4249,7 +4701,7 @@ func (m *UserGrantRequest) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *UserGrantRequest) MarshalTo(data []byte) (int, error) { +func (m *AuthRoleDeleteRequest) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4257,7 +4709,7 @@ func (m *UserGrantRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *UserRevokeRequest) Marshal() (data []byte, err error) { +func (m *AuthRoleGrantRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4267,7 +4719,7 @@ func (m *UserRevokeRequest) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *UserRevokeRequest) MarshalTo(data []byte) (int, error) { +func (m *AuthRoleGrantRequest) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4275,7 +4727,7 @@ func (m *UserRevokeRequest) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *RoleAddRequest) Marshal() (data []byte, err error) { +func (m *AuthRoleRevokeRequest) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4285,79 +4737,7 @@ func (m *RoleAddRequest) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *RoleAddRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - return i, nil -} - -func (m *RoleGetRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *RoleGetRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - return i, nil -} - -func (m *RoleDeleteRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *RoleDeleteRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - return i, nil -} - -func (m *RoleGrantRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *RoleGrantRequest) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - return i, nil -} - -func (m *RoleRevokeRequest) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *RoleRevokeRequest) MarshalTo(data []byte) (int, error) { +func (m *AuthRoleRevokeRequest) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4384,11 +4764,11 @@ func (m *AuthEnableResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n29, err := m.Header.MarshalTo(data[i:]) + n31, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n29 + i += n31 } return i, nil } @@ -4412,11 +4792,11 @@ func (m *AuthDisableResponse) MarshalTo(data []byte) (int, error) { data[i] = 0xa i++ i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n30, err := m.Header.MarshalTo(data[i:]) + n32, err := m.Header.MarshalTo(data[i:]) if err != nil { return 0, err } - i += n30 + i += n32 } return i, nil } @@ -4432,62 +4812,6 @@ func (m *AuthenticateResponse) Marshal() (data []byte, err error) { } func (m *AuthenticateResponse) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Header != nil { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n31, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n31 - } - return i, nil -} - -func (m *UserAddResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *UserAddResponse) MarshalTo(data []byte) (int, error) { - var i int - _ = i - var l int - _ = l - if m.Header != nil { - data[i] = 0xa - i++ - i = encodeVarintRpc(data, i, uint64(m.Header.Size())) - n32, err := m.Header.MarshalTo(data[i:]) - if err != nil { - return 0, err - } - i += n32 - } - return i, nil -} - -func (m *UserGetResponse) Marshal() (data []byte, err error) { - size := m.Size() - data = make([]byte, size) - n, err := m.MarshalTo(data) - if err != nil { - return nil, err - } - return data[:n], nil -} - -func (m *UserGetResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4505,7 +4829,7 @@ func (m *UserGetResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *UserDeleteResponse) Marshal() (data []byte, err error) { +func (m *AuthUserAddResponse) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4515,7 +4839,7 @@ func (m *UserDeleteResponse) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *UserDeleteResponse) MarshalTo(data []byte) (int, error) { +func (m *AuthUserAddResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4533,7 +4857,7 @@ func (m *UserDeleteResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *UserChangePasswordResponse) Marshal() (data []byte, err error) { +func (m *AuthUserGetResponse) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4543,7 +4867,7 @@ func (m *UserChangePasswordResponse) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *UserChangePasswordResponse) MarshalTo(data []byte) (int, error) { +func (m *AuthUserGetResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4561,7 +4885,7 @@ func (m *UserChangePasswordResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *UserGrantResponse) Marshal() (data []byte, err error) { +func (m *AuthUserDeleteResponse) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4571,7 +4895,7 @@ func (m *UserGrantResponse) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *UserGrantResponse) MarshalTo(data []byte) (int, error) { +func (m *AuthUserDeleteResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4589,7 +4913,7 @@ func (m *UserGrantResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *UserRevokeResponse) Marshal() (data []byte, err error) { +func (m *AuthUserChangePasswordResponse) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4599,7 +4923,7 @@ func (m *UserRevokeResponse) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *UserRevokeResponse) MarshalTo(data []byte) (int, error) { +func (m *AuthUserChangePasswordResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4617,7 +4941,7 @@ func (m *UserRevokeResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *RoleAddResponse) Marshal() (data []byte, err error) { +func (m *AuthUserGrantResponse) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4627,7 +4951,7 @@ func (m *RoleAddResponse) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *RoleAddResponse) MarshalTo(data []byte) (int, error) { +func (m *AuthUserGrantResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4645,7 +4969,7 @@ func (m *RoleAddResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *RoleGetResponse) Marshal() (data []byte, err error) { +func (m *AuthUserRevokeResponse) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4655,7 +4979,7 @@ func (m *RoleGetResponse) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *RoleGetResponse) MarshalTo(data []byte) (int, error) { +func (m *AuthUserRevokeResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4673,7 +4997,7 @@ func (m *RoleGetResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *RoleDeleteResponse) Marshal() (data []byte, err error) { +func (m *AuthRoleAddResponse) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4683,7 +5007,7 @@ func (m *RoleDeleteResponse) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *RoleDeleteResponse) MarshalTo(data []byte) (int, error) { +func (m *AuthRoleAddResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4701,7 +5025,7 @@ func (m *RoleDeleteResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *RoleGrantResponse) Marshal() (data []byte, err error) { +func (m *AuthRoleGetResponse) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4711,7 +5035,7 @@ func (m *RoleGrantResponse) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *RoleGrantResponse) MarshalTo(data []byte) (int, error) { +func (m *AuthRoleGetResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4729,7 +5053,7 @@ func (m *RoleGrantResponse) MarshalTo(data []byte) (int, error) { return i, nil } -func (m *RoleRevokeResponse) Marshal() (data []byte, err error) { +func (m *AuthRoleDeleteResponse) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) n, err := m.MarshalTo(data) @@ -4739,7 +5063,7 @@ func (m *RoleRevokeResponse) Marshal() (data []byte, err error) { return data[:n], nil } -func (m *RoleRevokeResponse) MarshalTo(data []byte) (int, error) { +func (m *AuthRoleDeleteResponse) MarshalTo(data []byte) (int, error) { var i int _ = i var l int @@ -4757,6 +5081,62 @@ func (m *RoleRevokeResponse) MarshalTo(data []byte) (int, error) { return i, nil } +func (m *AuthRoleGrantResponse) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *AuthRoleGrantResponse) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + data[i] = 0xa + i++ + i = encodeVarintRpc(data, i, uint64(m.Header.Size())) + n43, err := m.Header.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n43 + } + return i, nil +} + +func (m *AuthRoleRevokeResponse) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *AuthRoleRevokeResponse) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Header != nil { + data[i] = 0xa + i++ + i = encodeVarintRpc(data, i, uint64(m.Header.Size())) + n44, err := m.Header.MarshalTo(data[i:]) + if err != nil { + return 0, err + } + i += n44 + } + return i, nil +} + func encodeFixed64Rpc(data []byte, offset int, v uint64) int { data[offset] = uint8(v) data[offset+1] = uint8(v >> 8) @@ -5085,6 +5465,9 @@ func (m *CompactionRequest) Size() (n int) { if m.Revision != 0 { n += 1 + sovRpc(uint64(m.Revision)) } + if m.Physical { + n += 2 + } return n } @@ -5205,7 +5588,7 @@ func (m *WatchResponse) Size() (n int) { return n } -func (m *LeaseCreateRequest) Size() (n int) { +func (m *LeaseGrantRequest) Size() (n int) { var l int _ = l if m.TTL != 0 { @@ -5217,7 +5600,7 @@ func (m *LeaseCreateRequest) Size() (n int) { return n } -func (m *LeaseCreateResponse) Size() (n int) { +func (m *LeaseGrantResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -5417,6 +5800,69 @@ func (m *DefragmentResponse) Size() (n int) { return n } +func (m *AlarmRequest) Size() (n int) { + var l int + _ = l + if m.Action != 0 { + n += 1 + sovRpc(uint64(m.Action)) + } + if m.MemberID != 0 { + n += 1 + sovRpc(uint64(m.MemberID)) + } + if m.Alarm != 0 { + n += 1 + sovRpc(uint64(m.Alarm)) + } + return n +} + +func (m *AlarmMember) Size() (n int) { + var l int + _ = l + if m.MemberID != 0 { + n += 1 + sovRpc(uint64(m.MemberID)) + } + if m.Alarm != 0 { + n += 1 + sovRpc(uint64(m.Alarm)) + } + return n +} + +func (m *AlarmResponse) Size() (n int) { + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovRpc(uint64(l)) + } + if len(m.Alarms) > 0 { + for _, e := range m.Alarms { + l = e.Size() + n += 1 + l + sovRpc(uint64(l)) + } + } + return n +} + +func (m *StatusRequest) Size() (n int) { + var l int + _ = l + return n +} + +func (m *StatusResponse) Size() (n int) { + var l int + _ = l + if m.Header != nil { + l = m.Header.Size() + n += 1 + l + sovRpc(uint64(l)) + } + l = len(m.Version) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + return n +} + func (m *AuthEnableRequest) Size() (n int) { var l int _ = l @@ -5435,67 +5881,91 @@ func (m *AuthenticateRequest) Size() (n int) { return n } -func (m *UserAddRequest) Size() (n int) { +func (m *AuthUserAddRequest) Size() (n int) { + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + l = len(m.Password) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + return n +} + +func (m *AuthUserGetRequest) Size() (n int) { var l int _ = l return n } -func (m *UserGetRequest) Size() (n int) { +func (m *AuthUserDeleteRequest) Size() (n int) { + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + return n +} + +func (m *AuthUserChangePasswordRequest) Size() (n int) { + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + l = len(m.Password) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + return n +} + +func (m *AuthUserGrantRequest) Size() (n int) { var l int _ = l return n } -func (m *UserDeleteRequest) Size() (n int) { +func (m *AuthUserRevokeRequest) Size() (n int) { var l int _ = l return n } -func (m *UserChangePasswordRequest) Size() (n int) { +func (m *AuthRoleAddRequest) Size() (n int) { + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovRpc(uint64(l)) + } + return n +} + +func (m *AuthRoleGetRequest) Size() (n int) { var l int _ = l return n } -func (m *UserGrantRequest) Size() (n int) { +func (m *AuthRoleDeleteRequest) Size() (n int) { var l int _ = l return n } -func (m *UserRevokeRequest) Size() (n int) { +func (m *AuthRoleGrantRequest) Size() (n int) { var l int _ = l return n } -func (m *RoleAddRequest) Size() (n int) { - var l int - _ = l - return n -} - -func (m *RoleGetRequest) Size() (n int) { - var l int - _ = l - return n -} - -func (m *RoleDeleteRequest) Size() (n int) { - var l int - _ = l - return n -} - -func (m *RoleGrantRequest) Size() (n int) { - var l int - _ = l - return n -} - -func (m *RoleRevokeRequest) Size() (n int) { +func (m *AuthRoleRevokeRequest) Size() (n int) { var l int _ = l return n @@ -5531,7 +6001,7 @@ func (m *AuthenticateResponse) Size() (n int) { return n } -func (m *UserAddResponse) Size() (n int) { +func (m *AuthUserAddResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -5541,7 +6011,7 @@ func (m *UserAddResponse) Size() (n int) { return n } -func (m *UserGetResponse) Size() (n int) { +func (m *AuthUserGetResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -5551,7 +6021,7 @@ func (m *UserGetResponse) Size() (n int) { return n } -func (m *UserDeleteResponse) Size() (n int) { +func (m *AuthUserDeleteResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -5561,7 +6031,7 @@ func (m *UserDeleteResponse) Size() (n int) { return n } -func (m *UserChangePasswordResponse) Size() (n int) { +func (m *AuthUserChangePasswordResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -5571,7 +6041,7 @@ func (m *UserChangePasswordResponse) Size() (n int) { return n } -func (m *UserGrantResponse) Size() (n int) { +func (m *AuthUserGrantResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -5581,7 +6051,7 @@ func (m *UserGrantResponse) Size() (n int) { return n } -func (m *UserRevokeResponse) Size() (n int) { +func (m *AuthUserRevokeResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -5591,7 +6061,7 @@ func (m *UserRevokeResponse) Size() (n int) { return n } -func (m *RoleAddResponse) Size() (n int) { +func (m *AuthRoleAddResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -5601,7 +6071,7 @@ func (m *RoleAddResponse) Size() (n int) { return n } -func (m *RoleGetResponse) Size() (n int) { +func (m *AuthRoleGetResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -5611,7 +6081,7 @@ func (m *RoleGetResponse) Size() (n int) { return n } -func (m *RoleDeleteResponse) Size() (n int) { +func (m *AuthRoleDeleteResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -5621,7 +6091,7 @@ func (m *RoleDeleteResponse) Size() (n int) { return n } -func (m *RoleGrantResponse) Size() (n int) { +func (m *AuthRoleGrantResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -5631,7 +6101,7 @@ func (m *RoleGrantResponse) Size() (n int) { return n } -func (m *RoleRevokeResponse) Size() (n int) { +func (m *AuthRoleRevokeResponse) Size() (n int) { var l int _ = l if m.Header != nil { @@ -7376,6 +7846,26 @@ func (m *CompactionRequest) Unmarshal(data []byte) error { break } } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Physical", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + v |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + m.Physical = bool(v != 0) default: iNdEx = preIndex skippy, err := skipRpc(data[iNdEx:]) @@ -8158,7 +8648,7 @@ func (m *WatchResponse) Unmarshal(data []byte) error { } return nil } -func (m *LeaseCreateRequest) Unmarshal(data []byte) error { +func (m *LeaseGrantRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -8181,10 +8671,10 @@ func (m *LeaseCreateRequest) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: LeaseCreateRequest: wiretype end group for non-group") + return fmt.Errorf("proto: LeaseGrantRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: LeaseCreateRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: LeaseGrantRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -8246,7 +8736,7 @@ func (m *LeaseCreateRequest) Unmarshal(data []byte) error { } return nil } -func (m *LeaseCreateResponse) Unmarshal(data []byte) error { +func (m *LeaseGrantResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -8269,10 +8759,10 @@ func (m *LeaseCreateResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: LeaseCreateResponse: wiretype end group for non-group") + return fmt.Errorf("proto: LeaseGrantResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: LeaseCreateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: LeaseGrantResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -9739,6 +10229,477 @@ func (m *DefragmentResponse) Unmarshal(data []byte) error { } return nil } +func (m *AlarmRequest) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AlarmRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AlarmRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Action", wireType) + } + m.Action = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.Action |= (AlarmRequest_AlarmAction(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MemberID", wireType) + } + m.MemberID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.MemberID |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Alarm", wireType) + } + m.Alarm = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.Alarm |= (AlarmType(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipRpc(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AlarmMember) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AlarmMember: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AlarmMember: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MemberID", wireType) + } + m.MemberID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.MemberID |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Alarm", wireType) + } + m.Alarm = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.Alarm |= (AlarmType(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipRpc(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AlarmResponse) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AlarmResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AlarmResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header == nil { + m.Header = &ResponseHeader{} + } + if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Alarms", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Alarms = append(m.Alarms, &AlarmMember{}) + if err := m.Alarms[len(m.Alarms)-1].Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *StatusRequest) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StatusRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StatusRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipRpc(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *StatusResponse) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StatusResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StatusResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Header", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Header == nil { + m.Header = &ResponseHeader{} + } + if err := m.Header.Unmarshal(data[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(data[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *AuthEnableRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 @@ -9889,7 +10850,7 @@ func (m *AuthenticateRequest) Unmarshal(data []byte) error { } return nil } -func (m *UserAddRequest) Unmarshal(data []byte) error { +func (m *AuthUserAddRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -9912,10 +10873,118 @@ func (m *UserAddRequest) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserAddRequest: wiretype end group for non-group") + return fmt.Errorf("proto: AuthUserAddRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserAddRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthUserAddRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Password = string(data[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AuthUserGetRequest) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AuthUserGetRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AuthUserGetRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -9939,7 +11008,7 @@ func (m *UserAddRequest) Unmarshal(data []byte) error { } return nil } -func (m *UserGetRequest) Unmarshal(data []byte) error { +func (m *AuthUserDeleteRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -9962,10 +11031,197 @@ func (m *UserGetRequest) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserGetRequest: wiretype end group for non-group") + return fmt.Errorf("proto: AuthUserDeleteRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserGetRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthUserDeleteRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(data[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AuthUserChangePasswordRequest) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AuthUserChangePasswordRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AuthUserChangePasswordRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(data[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Password", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Password = string(data[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AuthUserGrantRequest) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AuthUserGrantRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AuthUserGrantRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -9989,7 +11245,7 @@ func (m *UserGetRequest) Unmarshal(data []byte) error { } return nil } -func (m *UserDeleteRequest) Unmarshal(data []byte) error { +func (m *AuthUserRevokeRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -10012,10 +11268,10 @@ func (m *UserDeleteRequest) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserDeleteRequest: wiretype end group for non-group") + return fmt.Errorf("proto: AuthUserRevokeRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserDeleteRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthUserRevokeRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -10039,7 +11295,7 @@ func (m *UserDeleteRequest) Unmarshal(data []byte) error { } return nil } -func (m *UserChangePasswordRequest) Unmarshal(data []byte) error { +func (m *AuthRoleAddRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -10062,10 +11318,89 @@ func (m *UserChangePasswordRequest) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserChangePasswordRequest: wiretype end group for non-group") + return fmt.Errorf("proto: AuthRoleAddRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserChangePasswordRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthRoleAddRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthRpc + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(data[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipRpc(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthRpc + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AuthRoleGetRequest) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRpc + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AuthRoleGetRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AuthRoleGetRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -10089,7 +11424,7 @@ func (m *UserChangePasswordRequest) Unmarshal(data []byte) error { } return nil } -func (m *UserGrantRequest) Unmarshal(data []byte) error { +func (m *AuthRoleDeleteRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -10112,10 +11447,10 @@ func (m *UserGrantRequest) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserGrantRequest: wiretype end group for non-group") + return fmt.Errorf("proto: AuthRoleDeleteRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserGrantRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthRoleDeleteRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -10139,7 +11474,7 @@ func (m *UserGrantRequest) Unmarshal(data []byte) error { } return nil } -func (m *UserRevokeRequest) Unmarshal(data []byte) error { +func (m *AuthRoleGrantRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -10162,10 +11497,10 @@ func (m *UserRevokeRequest) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserRevokeRequest: wiretype end group for non-group") + return fmt.Errorf("proto: AuthRoleGrantRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserRevokeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthRoleGrantRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -10189,7 +11524,7 @@ func (m *UserRevokeRequest) Unmarshal(data []byte) error { } return nil } -func (m *RoleAddRequest) Unmarshal(data []byte) error { +func (m *AuthRoleRevokeRequest) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -10212,210 +11547,10 @@ func (m *RoleAddRequest) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RoleAddRequest: wiretype end group for non-group") + return fmt.Errorf("proto: AuthRoleRevokeRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RoleAddRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthRpc - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RoleGetRequest) Unmarshal(data []byte) error { - l := len(data) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRpc - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RoleGetRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RoleGetRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthRpc - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RoleDeleteRequest) Unmarshal(data []byte) error { - l := len(data) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRpc - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RoleDeleteRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RoleDeleteRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthRpc - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RoleGrantRequest) Unmarshal(data []byte) error { - l := len(data) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRpc - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RoleGrantRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RoleGrantRequest: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - default: - iNdEx = preIndex - skippy, err := skipRpc(data[iNdEx:]) - if err != nil { - return err - } - if skippy < 0 { - return ErrInvalidLengthRpc - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func (m *RoleRevokeRequest) Unmarshal(data []byte) error { - l := len(data) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowRpc - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := data[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: RoleRevokeRequest: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: RoleRevokeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthRoleRevokeRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -10688,7 +11823,7 @@ func (m *AuthenticateResponse) Unmarshal(data []byte) error { } return nil } -func (m *UserAddResponse) Unmarshal(data []byte) error { +func (m *AuthUserAddResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -10711,10 +11846,10 @@ func (m *UserAddResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserAddResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AuthUserAddResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserAddResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthUserAddResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -10771,7 +11906,7 @@ func (m *UserAddResponse) Unmarshal(data []byte) error { } return nil } -func (m *UserGetResponse) Unmarshal(data []byte) error { +func (m *AuthUserGetResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -10794,10 +11929,10 @@ func (m *UserGetResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserGetResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AuthUserGetResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserGetResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthUserGetResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -10854,7 +11989,7 @@ func (m *UserGetResponse) Unmarshal(data []byte) error { } return nil } -func (m *UserDeleteResponse) Unmarshal(data []byte) error { +func (m *AuthUserDeleteResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -10877,10 +12012,10 @@ func (m *UserDeleteResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserDeleteResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AuthUserDeleteResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserDeleteResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthUserDeleteResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -10937,7 +12072,7 @@ func (m *UserDeleteResponse) Unmarshal(data []byte) error { } return nil } -func (m *UserChangePasswordResponse) Unmarshal(data []byte) error { +func (m *AuthUserChangePasswordResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -10960,10 +12095,10 @@ func (m *UserChangePasswordResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserChangePasswordResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AuthUserChangePasswordResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserChangePasswordResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthUserChangePasswordResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11020,7 +12155,7 @@ func (m *UserChangePasswordResponse) Unmarshal(data []byte) error { } return nil } -func (m *UserGrantResponse) Unmarshal(data []byte) error { +func (m *AuthUserGrantResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -11043,10 +12178,10 @@ func (m *UserGrantResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserGrantResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AuthUserGrantResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserGrantResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthUserGrantResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11103,7 +12238,7 @@ func (m *UserGrantResponse) Unmarshal(data []byte) error { } return nil } -func (m *UserRevokeResponse) Unmarshal(data []byte) error { +func (m *AuthUserRevokeResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -11126,10 +12261,10 @@ func (m *UserRevokeResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserRevokeResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AuthUserRevokeResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserRevokeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthUserRevokeResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11186,7 +12321,7 @@ func (m *UserRevokeResponse) Unmarshal(data []byte) error { } return nil } -func (m *RoleAddResponse) Unmarshal(data []byte) error { +func (m *AuthRoleAddResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -11209,10 +12344,10 @@ func (m *RoleAddResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RoleAddResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AuthRoleAddResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RoleAddResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthRoleAddResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11269,7 +12404,7 @@ func (m *RoleAddResponse) Unmarshal(data []byte) error { } return nil } -func (m *RoleGetResponse) Unmarshal(data []byte) error { +func (m *AuthRoleGetResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -11292,10 +12427,10 @@ func (m *RoleGetResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RoleGetResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AuthRoleGetResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RoleGetResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthRoleGetResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11352,7 +12487,7 @@ func (m *RoleGetResponse) Unmarshal(data []byte) error { } return nil } -func (m *RoleDeleteResponse) Unmarshal(data []byte) error { +func (m *AuthRoleDeleteResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -11375,10 +12510,10 @@ func (m *RoleDeleteResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RoleDeleteResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AuthRoleDeleteResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RoleDeleteResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthRoleDeleteResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11435,7 +12570,7 @@ func (m *RoleDeleteResponse) Unmarshal(data []byte) error { } return nil } -func (m *RoleGrantResponse) Unmarshal(data []byte) error { +func (m *AuthRoleGrantResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -11458,10 +12593,10 @@ func (m *RoleGrantResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RoleGrantResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AuthRoleGrantResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RoleGrantResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthRoleGrantResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -11518,7 +12653,7 @@ func (m *RoleGrantResponse) Unmarshal(data []byte) error { } return nil } -func (m *RoleRevokeResponse) Unmarshal(data []byte) error { +func (m *AuthRoleRevokeResponse) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 for iNdEx < l { @@ -11541,10 +12676,10 @@ func (m *RoleRevokeResponse) Unmarshal(data []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: RoleRevokeResponse: wiretype end group for non-group") + return fmt.Errorf("proto: AuthRoleRevokeResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: RoleRevokeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: AuthRoleRevokeResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto index f0e7f2a62cc..b1a501bf29e 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/etcdserverpb/rpc.proto @@ -30,11 +30,6 @@ service KV { // Compact compacts the event history in etcd. User should compact the // event history periodically, or it will grow infinitely. rpc Compact(CompactionRequest) returns (CompactionResponse) {} - - // Hash returns the hash of local KV state for consistency checking purpose. - // This is designed for testing purpose. Do not use this in production when there - // are ongoing transactions. - rpc Hash(HashRequest) returns (HashResponse) {} } service Watch { @@ -46,11 +41,11 @@ service Watch { } service Lease { - // LeaseCreate creates a lease. A lease has a TTL. The lease will expire if the + // LeaseGrant creates a lease. A lease has a TTL. The lease will expire if the // server does not receive a keepAlive within TTL from the lease holder. // All keys attached to the lease will be expired and deleted if the lease expires. // The key expiration generates an event in event history. - rpc LeaseCreate(LeaseCreateRequest) returns (LeaseCreateResponse) {} + rpc LeaseGrant(LeaseGrantRequest) returns (LeaseGrantResponse) {} // LeaseRevoke revokes a lease. All the key attached to the lease will be expired and deleted. rpc LeaseRevoke(LeaseRevokeRequest) returns (LeaseRevokeResponse) {} @@ -77,8 +72,18 @@ service Cluster { } service Maintenance { - // TODO: move Hash from kv to Maintenance + // Alarm activates, deactivates, and queries alarms regarding cluster health. + rpc Alarm(AlarmRequest) returns (AlarmResponse) {} + + // Status gets the status of the member. + rpc Status(StatusRequest) returns (StatusResponse) {} + rpc Defragment(DefragmentRequest) returns (DefragmentResponse) {} + + // Hash returns the hash of the local KV state for consistency checking purpose. + // This is designed for testing; do not use this in production when there + // are ongoing transactions. + rpc Hash(HashRequest) returns (HashResponse) {} } service Auth { @@ -92,37 +97,37 @@ service Auth { rpc Authenticate(AuthenticateRequest) returns (AuthenticateResponse) {} // UserAdd adds a new user. - rpc UserAdd(UserAddRequest) returns (UserAddResponse) {} + rpc UserAdd(AuthUserAddRequest) returns (AuthUserAddResponse) {} // UserGet gets a detailed information of a user or lists entire users. - rpc UserGet(UserGetRequest) returns (UserGetResponse) {} + rpc UserGet(AuthUserGetRequest) returns (AuthUserGetResponse) {} // UserDelete deletes a specified user. - rpc UserDelete(UserDeleteRequest) returns (UserDeleteResponse) {} + rpc UserDelete(AuthUserDeleteRequest) returns (AuthUserDeleteResponse) {} // UserChangePassword changes password of a specified user. - rpc UserChangePassword(UserChangePasswordRequest) returns (UserChangePasswordResponse) {} + rpc UserChangePassword(AuthUserChangePasswordRequest) returns (AuthUserChangePasswordResponse) {} // UserGrant grants a role to a specified user. - rpc UserGrant(UserGrantRequest) returns (UserGrantResponse) {} + rpc UserGrant(AuthUserGrantRequest) returns (AuthUserGrantResponse) {} // UserRevoke revokes a role of specified user. - rpc UserRevoke(UserRevokeRequest) returns (UserRevokeResponse) {} + rpc UserRevoke(AuthUserRevokeRequest) returns (AuthUserRevokeResponse) {} // RoleAdd adds a new role. - rpc RoleAdd(RoleAddRequest) returns (RoleAddResponse) {} + rpc RoleAdd(AuthRoleAddRequest) returns (AuthRoleAddResponse) {} // RoleGet gets a detailed information of a role or lists entire roles. - rpc RoleGet(RoleGetRequest) returns (RoleGetResponse) {} + rpc RoleGet(AuthRoleGetRequest) returns (AuthRoleGetResponse) {} // RoleDelete deletes a specified role. - rpc RoleDelete(RoleDeleteRequest) returns (RoleDeleteResponse) {} + rpc RoleDelete(AuthRoleDeleteRequest) returns (AuthRoleDeleteResponse) {} // RoleGrant grants a permission of a specified key or range to a specified role. - rpc RoleGrant(RoleGrantRequest) returns (RoleGrantResponse) {} + rpc RoleGrant(AuthRoleGrantRequest) returns (AuthRoleGrantResponse) {} // RoleRevoke revokes a key or range permission of a specified role. - rpc RoleRevoke(RoleRevokeRequest) returns (RoleRevokeResponse) {} + rpc RoleRevoke(AuthRoleRevokeRequest) returns (AuthRoleRevokeResponse) {} } message ResponseHeader { @@ -287,6 +292,10 @@ message TxnResponse { // revision. message CompactionRequest { int64 revision = 1; + // physical is set so the RPC will wait until the compaction is physically + // applied to the local database such that compacted entries are totally + // removed from the backing store. + bool physical = 2; } message CompactionResponse { @@ -352,14 +361,14 @@ message WatchResponse { repeated storagepb.Event events = 11; } -message LeaseCreateRequest { +message LeaseGrantRequest { // advisory ttl in seconds int64 TTL = 1; // requested ID to create; 0 lets lessor choose int64 ID = 2; } -message LeaseCreateResponse { +message LeaseGrantResponse { ResponseHeader header = 1; int64 ID = 2; // server decided ttl in second @@ -438,6 +447,41 @@ message DefragmentResponse { ResponseHeader header = 1; } +enum AlarmType { + NONE = 0; // default, used to query if any alarm is active + NOSPACE = 1; +} + +message AlarmRequest { + enum AlarmAction { + GET = 0; + ACTIVATE = 1; + DEACTIVATE = 2; + } + AlarmAction action = 1; + // MemberID is the member raising the alarm request + uint64 memberID = 2; + AlarmType alarm = 3; +} + +message AlarmMember { + uint64 memberID = 1; + AlarmType alarm = 2; +} + +message AlarmResponse { + ResponseHeader header = 1; + repeated AlarmMember alarms = 2; +} + +message StatusRequest { +} + +message StatusResponse { + ResponseHeader header = 1; + string version = 2; +} + message AuthEnableRequest { } @@ -447,37 +491,43 @@ message AuthDisableRequest { message AuthenticateRequest { } -message UserAddRequest { +message AuthUserAddRequest { + string name = 1; + string password = 2; } -message UserGetRequest { +message AuthUserGetRequest { } -message UserDeleteRequest { +message AuthUserDeleteRequest { + string name = 1; } -message UserChangePasswordRequest { +message AuthUserChangePasswordRequest { + string name = 1; + string password = 2; } -message UserGrantRequest { +message AuthUserGrantRequest { } -message UserRevokeRequest { +message AuthUserRevokeRequest { } -message RoleAddRequest { +message AuthRoleAddRequest { + string name = 1; } -message RoleGetRequest { +message AuthRoleGetRequest { } -message RoleDeleteRequest { +message AuthRoleDeleteRequest { } -message RoleGrantRequest { +message AuthRoleGrantRequest { } -message RoleRevokeRequest { +message AuthRoleRevokeRequest { } message AuthEnableResponse { @@ -492,46 +542,46 @@ message AuthenticateResponse { ResponseHeader header = 1; } -message UserAddResponse { +message AuthUserAddResponse { ResponseHeader header = 1; } -message UserGetResponse { +message AuthUserGetResponse { ResponseHeader header = 1; } -message UserDeleteResponse { +message AuthUserDeleteResponse { ResponseHeader header = 1; } -message UserChangePasswordResponse { +message AuthUserChangePasswordResponse { ResponseHeader header = 1; } -message UserGrantResponse { +message AuthUserGrantResponse { ResponseHeader header = 1; } -message UserRevokeResponse { +message AuthUserRevokeResponse { ResponseHeader header = 1; } -message RoleAddResponse { +message AuthRoleAddResponse { ResponseHeader header = 1; } -message RoleGetResponse { +message AuthRoleGetResponse { ResponseHeader header = 1; } -message RoleDeleteResponse { +message AuthRoleDeleteResponse { ResponseHeader header = 1; } -message RoleGrantResponse { +message AuthRoleGrantResponse { ResponseHeader header = 1; } -message RoleRevokeResponse { +message AuthRoleRevokeResponse { ResponseHeader header = 1; } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/cluster.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/membership/cluster.go similarity index 73% rename from Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/cluster.go rename to Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/membership/cluster.go index 4cdad9dd939..0771e874f73 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/cluster.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/membership/cluster.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package etcdserver +package membership import ( "bytes" @@ -29,39 +29,19 @@ import ( "github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/raft" "github.com/coreos/etcd/raft/raftpb" + "github.com/coreos/etcd/storage/backend" "github.com/coreos/etcd/store" "github.com/coreos/etcd/version" "github.com/coreos/go-semver/semver" ) -const ( - raftAttributesSuffix = "raftAttributes" - attributesSuffix = "attributes" -) - -type Cluster interface { - // ID returns the cluster ID - ID() types.ID - // ClientURLs returns an aggregate set of all URLs on which this - // cluster is listening for client requests - ClientURLs() []string - // Members returns a slice of members sorted by their ID - Members() []*Member - // Member retrieves a particular member based on ID, or nil if the - // member does not exist in the cluster - Member(id types.ID) *Member - // IsIDRemoved checks whether the given ID has been removed from this - // cluster at some point in the past - IsIDRemoved(id types.ID) bool - // Version is the cluster-wide minimum major.minor version. - Version() *semver.Version -} - -// Cluster is a list of Members that belong to the same raft cluster -type cluster struct { +// RaftCluster is a list of Members that belong to the same raft cluster +type RaftCluster struct { id types.ID token string + store store.Store + be backend.Backend sync.Mutex // guards the fields below version *semver.Version @@ -71,8 +51,8 @@ type cluster struct { removed map[types.ID]bool } -func newClusterFromURLsMap(token string, urlsmap types.URLsMap) (*cluster, error) { - c := newCluster(token) +func NewClusterFromURLsMap(token string, urlsmap types.URLsMap) (*RaftCluster, error) { + c := NewCluster(token) for name, urls := range urlsmap { m := NewMember(name, urls, token, nil) if _, ok := c.members[m.ID]; ok { @@ -87,8 +67,8 @@ func newClusterFromURLsMap(token string, urlsmap types.URLsMap) (*cluster, error return c, nil } -func newClusterFromMembers(token string, id types.ID, membs []*Member) *cluster { - c := newCluster(token) +func NewClusterFromMembers(token string, id types.ID, membs []*Member) *RaftCluster { + c := NewCluster(token) c.id = id for _, m := range membs { c.members[m.ID] = m @@ -96,17 +76,17 @@ func newClusterFromMembers(token string, id types.ID, membs []*Member) *cluster return c } -func newCluster(token string) *cluster { - return &cluster{ +func NewCluster(token string) *RaftCluster { + return &RaftCluster{ token: token, members: make(map[types.ID]*Member), removed: make(map[types.ID]bool), } } -func (c *cluster) ID() types.ID { return c.id } +func (c *RaftCluster) ID() types.ID { return c.id } -func (c *cluster) Members() []*Member { +func (c *RaftCluster) Members() []*Member { c.Lock() defer c.Unlock() var ms MembersByID @@ -117,7 +97,7 @@ func (c *cluster) Members() []*Member { return []*Member(ms) } -func (c *cluster) Member(id types.ID) *Member { +func (c *RaftCluster) Member(id types.ID) *Member { c.Lock() defer c.Unlock() return c.members[id].Clone() @@ -125,7 +105,7 @@ func (c *cluster) Member(id types.ID) *Member { // MemberByName returns a Member with the given name if exists. // If more than one member has the given name, it will panic. -func (c *cluster) MemberByName(name string) *Member { +func (c *RaftCluster) MemberByName(name string) *Member { c.Lock() defer c.Unlock() var memb *Member @@ -140,7 +120,7 @@ func (c *cluster) MemberByName(name string) *Member { return memb.Clone() } -func (c *cluster) MemberIDs() []types.ID { +func (c *RaftCluster) MemberIDs() []types.ID { c.Lock() defer c.Unlock() var ids []types.ID @@ -151,7 +131,7 @@ func (c *cluster) MemberIDs() []types.ID { return ids } -func (c *cluster) IsIDRemoved(id types.ID) bool { +func (c *RaftCluster) IsIDRemoved(id types.ID) bool { c.Lock() defer c.Unlock() return c.removed[id] @@ -159,7 +139,7 @@ func (c *cluster) IsIDRemoved(id types.ID) bool { // PeerURLs returns a list of all peer addresses. // The returned list is sorted in ascending lexicographical order. -func (c *cluster) PeerURLs() []string { +func (c *RaftCluster) PeerURLs() []string { c.Lock() defer c.Unlock() urls := make([]string, 0) @@ -174,7 +154,7 @@ func (c *cluster) PeerURLs() []string { // ClientURLs returns a list of all client addresses. // The returned list is sorted in ascending lexicographical order. -func (c *cluster) ClientURLs() []string { +func (c *RaftCluster) ClientURLs() []string { c.Lock() defer c.Unlock() urls := make([]string, 0) @@ -187,7 +167,7 @@ func (c *cluster) ClientURLs() []string { return urls } -func (c *cluster) String() string { +func (c *RaftCluster) String() string { c.Lock() defer c.Unlock() b := &bytes.Buffer{} @@ -205,7 +185,7 @@ func (c *cluster) String() string { return b.String() } -func (c *cluster) genID() { +func (c *RaftCluster) genID() { mIDs := c.MemberIDs() b := make([]byte, 8*len(mIDs)) for i, id := range mIDs { @@ -215,17 +195,17 @@ func (c *cluster) genID() { c.id = types.ID(binary.BigEndian.Uint64(hash[:8])) } -func (c *cluster) SetID(id types.ID) { c.id = id } +func (c *RaftCluster) SetID(id types.ID) { c.id = id } -func (c *cluster) SetStore(st store.Store) { c.store = st } +func (c *RaftCluster) SetStore(st store.Store) { c.store = st } -func (c *cluster) Recover() { +func (c *RaftCluster) Recover() { c.Lock() defer c.Unlock() c.members, c.removed = membersFromStore(c.store) c.version = clusterVersionFromStore(c.store) - MustDetectDowngrade(c.version) + mustDetectDowngrade(c.version) for _, m := range c.members { plog.Infof("added member %s %v to cluster %s from store", m.ID, m.PeerURLs, c.id) @@ -237,7 +217,7 @@ func (c *cluster) Recover() { // ValidateConfigurationChange takes a proposed ConfChange and // ensures that it is still valid. -func (c *cluster) ValidateConfigurationChange(cc raftpb.ConfChange) error { +func (c *RaftCluster) ValidateConfigurationChange(cc raftpb.ConfChange) error { members, removed := membersFromStore(c.store) id := types.ID(cc.NodeID) if removed[id] { @@ -298,36 +278,36 @@ func (c *cluster) ValidateConfigurationChange(cc raftpb.ConfChange) error { // AddMember adds a new Member into the cluster, and saves the given member's // raftAttributes into the store. The given member should have empty attributes. // A Member with a matching id must not exist. -func (c *cluster) AddMember(m *Member) { +func (c *RaftCluster) AddMember(m *Member) { c.Lock() defer c.Unlock() - b, err := json.Marshal(m.RaftAttributes) - if err != nil { - plog.Panicf("marshal raftAttributes should never fail: %v", err) + if c.store != nil { + mustSaveMemberToStore(c.store, m) } - p := path.Join(memberStoreKey(m.ID), raftAttributesSuffix) - if _, err := c.store.Create(p, false, string(b), false, store.TTLOptionSet{ExpireTime: store.Permanent}); err != nil { - plog.Panicf("create raftAttributes should never fail: %v", err) + if c.be != nil { + mustSaveMemberToBackend(c.be, m) } + c.members[m.ID] = m } // RemoveMember removes a member from the store. // The given id MUST exist, or the function panics. -func (c *cluster) RemoveMember(id types.ID) { +func (c *RaftCluster) RemoveMember(id types.ID) { c.Lock() defer c.Unlock() - if _, err := c.store.Delete(memberStoreKey(id), true, true); err != nil { - plog.Panicf("delete member should never fail: %v", err) + if c.store != nil { + mustDeleteMemberFromStore(c.store, id) } + if c.be != nil { + mustDeleteMemberFromBackend(c.be, id) + } + delete(c.members, id) - if _, err := c.store.Create(removedMemberStoreKey(id), false, "", false, store.TTLOptionSet{ExpireTime: store.Permanent}); err != nil { - plog.Panicf("create removedMember should never fail: %v", err) - } c.removed[id] = true } -func (c *cluster) UpdateAttributes(id types.ID, attr Attributes) bool { +func (c *RaftCluster) UpdateAttributes(id types.ID, attr Attributes) bool { c.Lock() defer c.Unlock() if m, ok := c.members[id]; ok { @@ -344,21 +324,20 @@ func (c *cluster) UpdateAttributes(id types.ID, attr Attributes) bool { return false } -func (c *cluster) UpdateRaftAttributes(id types.ID, raftAttr RaftAttributes) { +func (c *RaftCluster) UpdateRaftAttributes(id types.ID, raftAttr RaftAttributes) { c.Lock() defer c.Unlock() - b, err := json.Marshal(raftAttr) - if err != nil { - plog.Panicf("marshal raftAttributes should never fail: %v", err) - } - p := path.Join(memberStoreKey(id), raftAttributesSuffix) - if _, err := c.store.Update(p, string(b), store.TTLOptionSet{ExpireTime: store.Permanent}); err != nil { - plog.Panicf("update raftAttributes should never fail: %v", err) - } + c.members[id].RaftAttributes = raftAttr + if c.store != nil { + mustUpdateMemberInStore(c.store, c.members[id]) + } + if c.be != nil { + mustSaveMemberToBackend(c.be, c.members[id]) + } } -func (c *cluster) Version() *semver.Version { +func (c *RaftCluster) Version() *semver.Version { c.Lock() defer c.Unlock() if c.version == nil { @@ -367,7 +346,7 @@ func (c *cluster) Version() *semver.Version { return semver.Must(semver.NewVersion(c.version.String())) } -func (c *cluster) SetVersion(ver *semver.Version) { +func (c *RaftCluster) SetVersion(ver *semver.Version) { c.Lock() defer c.Unlock() if c.version != nil { @@ -376,10 +355,10 @@ func (c *cluster) SetVersion(ver *semver.Version) { plog.Noticef("set the initial cluster version to %v", version.Cluster(ver.String())) } c.version = ver - MustDetectDowngrade(c.version) + mustDetectDowngrade(c.version) } -func (c *cluster) isReadyToAddNewMember() bool { +func (c *RaftCluster) IsReadyToAddNewMember() bool { nmembers := 1 nstarted := 0 @@ -407,7 +386,7 @@ func (c *cluster) isReadyToAddNewMember() bool { return true } -func (c *cluster) isReadyToRemoveMember(id uint64) bool { +func (c *RaftCluster) IsReadyToRemoveMember(id uint64) bool { nmembers := 0 nstarted := 0 @@ -434,7 +413,7 @@ func (c *cluster) isReadyToRemoveMember(id uint64) bool { func membersFromStore(st store.Store) (map[types.ID]*Member, map[types.ID]bool) { members := make(map[types.ID]*Member) removed := make(map[types.ID]bool) - e, err := st.Get(storeMembersPrefix, true, true) + e, err := st.Get(StoreMembersPrefix, true, true) if err != nil { if isKeyNotFound(err) { return members, removed @@ -458,13 +437,13 @@ func membersFromStore(st store.Store) (map[types.ID]*Member, map[types.ID]bool) plog.Panicf("get storeRemovedMembers should never fail: %v", err) } for _, n := range e.Node.Nodes { - removed[mustParseMemberIDFromKey(n.Key)] = true + removed[MustParseMemberIDFromKey(n.Key)] = true } return members, removed } func clusterVersionFromStore(st store.Store) *semver.Version { - e, err := st.Get(path.Join(StoreClusterPrefix, "version"), false, false) + e, err := st.Get(path.Join(storePrefix, "version"), false, false) if err != nil { if isKeyNotFound(err) { return nil @@ -478,7 +457,7 @@ func clusterVersionFromStore(st store.Store) *semver.Version { // with the existing cluster. If the validation succeeds, it assigns the IDs // from the existing cluster to the local cluster. // If the validation fails, an error will be returned. -func ValidateClusterAndAssignIDs(local *cluster, existing *cluster) error { +func ValidateClusterAndAssignIDs(local *RaftCluster, existing *RaftCluster) error { ems := existing.Members() lms := local.Members() if len(ems) != len(lms) { @@ -499,3 +478,12 @@ func ValidateClusterAndAssignIDs(local *cluster, existing *cluster) error { } return nil } + +func mustDetectDowngrade(cv *semver.Version) { + lv := semver.Must(semver.NewVersion(version.Version)) + // only keep major.minor version for comparison against cluster version + lv = &semver.Version{Major: lv.Major, Minor: lv.Minor} + if cv != nil && lv.LessThan(*cv) { + plog.Fatalf("cluster cannot be downgraded (current version: %s is lower than determined cluster version: %s).", version.Version, version.Cluster(cv.String())) + } +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/membership/errors.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/membership/errors.go new file mode 100644 index 00000000000..a8605e3ebf2 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/membership/errors.go @@ -0,0 +1,33 @@ +// Copyright 2016 CoreOS, 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. + +package membership + +import ( + "errors" + + etcdErr "github.com/coreos/etcd/error" +) + +var ( + ErrIDRemoved = errors.New("membership: ID removed") + ErrIDExists = errors.New("membership: ID exists") + ErrIDNotFound = errors.New("membership: ID not found") + ErrPeerURLexists = errors.New("membership: peerURL exists") +) + +func isKeyNotFound(err error) bool { + e, ok := err.(*etcdErr.Error) + return ok && e.ErrorCode == etcdErr.EcodeKeyNotFound +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/member.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/membership/member.go similarity index 65% rename from Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/member.go rename to Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/membership/member.go index e56881a51ec..fbf2c0702da 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/member.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/membership/member.go @@ -12,25 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -package etcdserver +package membership import ( "crypto/sha1" "encoding/binary" - "encoding/json" "fmt" "math/rand" - "path" "sort" "time" "github.com/coreos/etcd/pkg/types" - "github.com/coreos/etcd/store" + "github.com/coreos/pkg/capnslog" ) var ( - storeMembersPrefix = path.Join(StoreClusterPrefix, "members") - storeRemovedMembersPrefix = path.Join(StoreClusterPrefix, "removed_members") + plog = capnslog.NewPackageLogger("github.com/coreos/etcd/etcdserver", "membership") ) // RaftAttributes represents the raft related attributes of an etcd member. @@ -110,54 +107,6 @@ func (m *Member) IsStarted() bool { return len(m.Name) != 0 } -func memberStoreKey(id types.ID) string { - return path.Join(storeMembersPrefix, id.String()) -} - -func MemberAttributesStorePath(id types.ID) string { - return path.Join(memberStoreKey(id), attributesSuffix) -} - -func mustParseMemberIDFromKey(key string) types.ID { - id, err := types.IDFromString(path.Base(key)) - if err != nil { - plog.Panicf("unexpected parse member id error: %v", err) - } - return id -} - -func removedMemberStoreKey(id types.ID) string { - return path.Join(storeRemovedMembersPrefix, id.String()) -} - -// nodeToMember builds member from a key value node. -// the child nodes of the given node MUST be sorted by key. -func nodeToMember(n *store.NodeExtern) (*Member, error) { - m := &Member{ID: mustParseMemberIDFromKey(n.Key)} - attrs := make(map[string][]byte) - raftAttrKey := path.Join(n.Key, raftAttributesSuffix) - attrKey := path.Join(n.Key, attributesSuffix) - for _, nn := range n.Nodes { - if nn.Key != raftAttrKey && nn.Key != attrKey { - return nil, fmt.Errorf("unknown key %q", nn.Key) - } - attrs[nn.Key] = []byte(*nn.Value) - } - if data := attrs[raftAttrKey]; data != nil { - if err := json.Unmarshal(data, &m.RaftAttributes); err != nil { - return nil, fmt.Errorf("unmarshal raftAttributes error: %v", err) - } - } else { - return nil, fmt.Errorf("raftAttributes key doesn't exist") - } - if data := attrs[attrKey]; data != nil { - if err := json.Unmarshal(data, &m.Attributes); err != nil { - return m, fmt.Errorf("unmarshal attributes error: %v", err) - } - } - return m, nil -} - // MembersByID implements sort by ID interface type MembersByID []*Member diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/membership/store.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/membership/store.go new file mode 100644 index 00000000000..cdd16371fc6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/membership/store.go @@ -0,0 +1,149 @@ +// Copyright 2016 CoreOS, 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. + +package membership + +import ( + "encoding/json" + "fmt" + "path" + + "github.com/coreos/etcd/pkg/types" + "github.com/coreos/etcd/storage/backend" + "github.com/coreos/etcd/store" +) + +const ( + // TODO: make this private after moving all membership storage logic + // from etcdserver pkg + AttributesSuffix = "attributes" + raftAttributesSuffix = "raftAttributes" + + // the prefix for stroing membership related information in store provided by store pkg. + storePrefix = "/0" +) + +var ( + membersBucketName = []byte("members") + membersRemovedBuckedName = []byte("members_removed") + + StoreMembersPrefix = path.Join(storePrefix, "members") + storeRemovedMembersPrefix = path.Join(storePrefix, "removed_members") +) + +func mustSaveMemberToBackend(be backend.Backend, m *Member) { + mkey := backendMemberKey(m.ID) + mvalue, err := json.Marshal(m.RaftAttributes) + if err != nil { + plog.Panicf("marshal raftAttributes should never fail: %v", err) + } + + tx := be.BatchTx() + tx.Lock() + tx.UnsafePut(membersBucketName, mkey, mvalue) + tx.Unlock() +} + +func mustDeleteMemberFromBackend(be backend.Backend, id types.ID) { + mkey := backendMemberKey(id) + + tx := be.BatchTx() + tx.Lock() + tx.UnsafeDelete(membersBucketName, mkey) + tx.UnsafePut(membersRemovedBuckedName, mkey, []byte("removed")) + tx.Unlock() +} + +func mustSaveMemberToStore(s store.Store, m *Member) { + b, err := json.Marshal(m.RaftAttributes) + if err != nil { + plog.Panicf("marshal raftAttributes should never fail: %v", err) + } + p := path.Join(MemberStoreKey(m.ID), raftAttributesSuffix) + if _, err := s.Create(p, false, string(b), false, store.TTLOptionSet{ExpireTime: store.Permanent}); err != nil { + plog.Panicf("create raftAttributes should never fail: %v", err) + } +} + +func mustDeleteMemberFromStore(s store.Store, id types.ID) { + if _, err := s.Delete(MemberStoreKey(id), true, true); err != nil { + plog.Panicf("delete member should never fail: %v", err) + } + if _, err := s.Create(RemovedMemberStoreKey(id), false, "", false, store.TTLOptionSet{ExpireTime: store.Permanent}); err != nil { + plog.Panicf("create removedMember should never fail: %v", err) + } +} + +func mustUpdateMemberInStore(s store.Store, m *Member) { + b, err := json.Marshal(m.RaftAttributes) + if err != nil { + plog.Panicf("marshal raftAttributes should never fail: %v", err) + } + p := path.Join(MemberStoreKey(m.ID), raftAttributesSuffix) + if _, err := s.Update(p, string(b), store.TTLOptionSet{ExpireTime: store.Permanent}); err != nil { + plog.Panicf("update raftAttributes should never fail: %v", err) + } +} + +// nodeToMember builds member from a key value node. +// the child nodes of the given node MUST be sorted by key. +func nodeToMember(n *store.NodeExtern) (*Member, error) { + m := &Member{ID: MustParseMemberIDFromKey(n.Key)} + attrs := make(map[string][]byte) + raftAttrKey := path.Join(n.Key, raftAttributesSuffix) + attrKey := path.Join(n.Key, AttributesSuffix) + for _, nn := range n.Nodes { + if nn.Key != raftAttrKey && nn.Key != attrKey { + return nil, fmt.Errorf("unknown key %q", nn.Key) + } + attrs[nn.Key] = []byte(*nn.Value) + } + if data := attrs[raftAttrKey]; data != nil { + if err := json.Unmarshal(data, &m.RaftAttributes); err != nil { + return nil, fmt.Errorf("unmarshal raftAttributes error: %v", err) + } + } else { + return nil, fmt.Errorf("raftAttributes key doesn't exist") + } + if data := attrs[attrKey]; data != nil { + if err := json.Unmarshal(data, &m.Attributes); err != nil { + return m, fmt.Errorf("unmarshal attributes error: %v", err) + } + } + return m, nil +} + +func backendMemberKey(id types.ID) []byte { + return []byte(path.Join(id.String(), raftAttributesSuffix)) +} + +func MemberStoreKey(id types.ID) string { + return path.Join(StoreMembersPrefix, id.String()) +} + +func MemberAttributesStorePath(id types.ID) string { + return path.Join(MemberStoreKey(id), AttributesSuffix) +} + +func MustParseMemberIDFromKey(key string) types.ID { + id, err := types.IDFromString(path.Base(key)) + if err != nil { + plog.Panicf("unexpected parse member id error: %v", err) + } + return id +} + +func RemovedMemberStoreKey(id types.ID) string { + return path.Join(storeRemovedMembersPrefix, id.String()) +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/quota.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/quota.go new file mode 100644 index 00000000000..87c97f4acfa --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/quota.go @@ -0,0 +1,114 @@ +// Copyright 2016 CoreOS, 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. + +package etcdserver + +import ( + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/storage/backend" +) + +// Quota represents an arbitrary quota against arbitrary requests. Each request +// costs some charge; if there is not enough remaining charge, then there are +// too few resources available within the quota to apply the request. +type Quota interface { + // Available judges whether the given request fits within the quota. + Available(req interface{}) bool + // Cost computes the charge against the quota for a given request. + Cost(req interface{}) int + // Remaining is the amount of charge left for the quota. + Remaining() int64 +} + +type passthroughQuota struct{} + +func (*passthroughQuota) Available(interface{}) bool { return true } +func (*passthroughQuota) Cost(interface{}) int { return 0 } +func (*passthroughQuota) Remaining() int64 { return 1 } + +type backendQuota struct { + s *EtcdServer + maxBackendBytes int64 +} + +const ( + // leaseOverhead is an estimate for the cost of storing a lease + leaseOverhead = 64 + // kvOverhead is an estimate for the cost of storing a key's metadata + kvOverhead = 256 +) + +func NewBackendQuota(s *EtcdServer) Quota { + if s.cfg.QuotaBackendBytes < 0 { + // disable quotas if negative + plog.Warningf("disabling backend quota") + return &passthroughQuota{} + } + if s.cfg.QuotaBackendBytes == 0 { + // use default size if no quota size given + return &backendQuota{s, backend.DefaultQuotaBytes} + } + if s.cfg.QuotaBackendBytes > backend.MaxQuotaBytes { + plog.Warningf("backend quota %v exceeds maximum quota %v; using maximum", s.cfg.QuotaBackendBytes, backend.MaxQuotaBytes) + return &backendQuota{s, backend.MaxQuotaBytes} + } + return &backendQuota{s, s.cfg.QuotaBackendBytes} +} + +func (b *backendQuota) Available(v interface{}) bool { + // TODO: maybe optimize backend.Size() + return b.s.Backend().Size()+int64(b.Cost(v)) < b.maxBackendBytes +} + +func (b *backendQuota) Cost(v interface{}) int { + switch r := v.(type) { + case *pb.PutRequest: + return costPut(r) + case *pb.TxnRequest: + return costTxn(r) + case *pb.LeaseGrantRequest: + return leaseOverhead + default: + panic("unexpected cost") + } +} + +func costPut(r *pb.PutRequest) int { return kvOverhead + len(r.Key) + len(r.Value) } + +func costTxnReq(u *pb.RequestUnion) int { + r := u.GetRequestPut() + if r == nil { + return 0 + } + return costPut(r) +} + +func costTxn(r *pb.TxnRequest) int { + sizeSuccess := 0 + for _, u := range r.Success { + sizeSuccess += costTxnReq(u) + } + sizeFailure := 0 + for _, u := range r.Failure { + sizeFailure += costTxnReq(u) + } + if sizeFailure > sizeSuccess { + return sizeFailure + } + return sizeSuccess +} + +func (b *backendQuota) Remaining() int64 { + return b.maxBackendBytes - b.s.Backend().Size() +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/raft.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/raft.go index 56f25b45f45..a936afee751 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/raft.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/raft.go @@ -24,6 +24,7 @@ import ( "time" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/etcdserver/membership" "github.com/coreos/etcd/pkg/contention" "github.com/coreos/etcd/pkg/pbutil" "github.com/coreos/etcd/pkg/types" @@ -279,7 +280,7 @@ func advanceTicksForElection(n raft.Node, electionTicks int) { } } -func startNode(cfg *ServerConfig, cl *cluster, ids []types.ID) (id types.ID, n raft.Node, s *raft.MemoryStorage, w *wal.WAL) { +func startNode(cfg *ServerConfig, cl *membership.RaftCluster, ids []types.ID) (id types.ID, n raft.Node, s *raft.MemoryStorage, w *wal.WAL) { var err error member := cl.MemberByName(cfg.Name) metadata := pbutil.MustMarshal( @@ -312,10 +313,7 @@ func startNode(cfg *ServerConfig, cl *cluster, ids []types.ID) (id types.ID, n r Storage: s, MaxSizePerMsg: maxSizePerMsg, MaxInflightMsgs: maxInflightMsgs, - } - - if cfg.V3demo { - c.CheckQuorum = true + CheckQuorum: true, } n = raft.StartNode(c, peers) @@ -326,7 +324,7 @@ func startNode(cfg *ServerConfig, cl *cluster, ids []types.ID) (id types.ID, n r return } -func restartNode(cfg *ServerConfig, snapshot *raftpb.Snapshot) (types.ID, *cluster, raft.Node, *raft.MemoryStorage, *wal.WAL) { +func restartNode(cfg *ServerConfig, snapshot *raftpb.Snapshot) (types.ID, *membership.RaftCluster, raft.Node, *raft.MemoryStorage, *wal.WAL) { var walsnap walpb.Snapshot if snapshot != nil { walsnap.Index, walsnap.Term = snapshot.Metadata.Index, snapshot.Metadata.Term @@ -334,7 +332,7 @@ func restartNode(cfg *ServerConfig, snapshot *raftpb.Snapshot) (types.ID, *clust w, id, cid, st, ents := readWAL(cfg.WALDir(), walsnap) plog.Infof("restarting member %s in cluster %s at commit index %d", id, cid, st.Commit) - cl := newCluster("") + cl := membership.NewCluster("") cl.SetID(cid) s := raft.NewMemoryStorage() if snapshot != nil { @@ -349,10 +347,7 @@ func restartNode(cfg *ServerConfig, snapshot *raftpb.Snapshot) (types.ID, *clust Storage: s, MaxSizePerMsg: maxSizePerMsg, MaxInflightMsgs: maxInflightMsgs, - } - - if cfg.V3demo { - c.CheckQuorum = true + CheckQuorum: true, } n := raft.RestartNode(c) @@ -363,7 +358,7 @@ func restartNode(cfg *ServerConfig, snapshot *raftpb.Snapshot) (types.ID, *clust return id, cl, n, s, w } -func restartAsStandaloneNode(cfg *ServerConfig, snapshot *raftpb.Snapshot) (types.ID, *cluster, raft.Node, *raft.MemoryStorage, *wal.WAL) { +func restartAsStandaloneNode(cfg *ServerConfig, snapshot *raftpb.Snapshot) (types.ID, *membership.RaftCluster, raft.Node, *raft.MemoryStorage, *wal.WAL) { var walsnap walpb.Snapshot if snapshot != nil { walsnap.Index, walsnap.Term = snapshot.Metadata.Index, snapshot.Metadata.Term @@ -393,7 +388,7 @@ func restartAsStandaloneNode(cfg *ServerConfig, snapshot *raftpb.Snapshot) (type } plog.Printf("forcing restart of member %s in cluster %s at commit index %d", id, cid, st.Commit) - cl := newCluster("") + cl := membership.NewCluster("") cl.SetID(cid) s := raft.NewMemoryStorage() if snapshot != nil { @@ -479,9 +474,9 @@ func createConfigChangeEnts(ids []uint64, self uint64, term, index uint64) []raf next++ } if !found { - m := Member{ + m := membership.Member{ ID: types.ID(self), - RaftAttributes: RaftAttributes{PeerURLs: []string{"http://localhost:7001", "http://localhost:2380"}}, + RaftAttributes: membership.RaftAttributes{PeerURLs: []string{"http://localhost:7001", "http://localhost:2380"}}, } ctx, err := json.Marshal(m) if err != nil { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/server.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/server.go index badc463853b..2a0d9c99896 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/server.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/server.go @@ -16,7 +16,6 @@ package etcdserver import ( "encoding/json" - "errors" "expvar" "fmt" "math/rand" @@ -28,11 +27,13 @@ import ( "sync/atomic" "time" + "github.com/coreos/etcd/alarm" "github.com/coreos/etcd/auth" "github.com/coreos/etcd/compactor" "github.com/coreos/etcd/discovery" - "github.com/coreos/etcd/etcdserver/etcdhttp/httptypes" + "github.com/coreos/etcd/etcdserver/api/v2http/httptypes" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/etcdserver/membership" "github.com/coreos/etcd/etcdserver/stats" "github.com/coreos/etcd/lease" "github.com/coreos/etcd/pkg/fileutil" @@ -82,7 +83,7 @@ const ( var ( plog = capnslog.NewPackageLogger("github.com/coreos/etcd", "etcdserver") - storeMemberAttributeRegexp = regexp.MustCompile(path.Join(storeMembersPrefix, "[[:xdigit:]]{1,16}", attributesSuffix)) + storeMemberAttributeRegexp = regexp.MustCompile(path.Join(membership.StoreMembersPrefix, "[[:xdigit:]]{1,16}", "attributes")) ) func init() { @@ -126,7 +127,7 @@ type Server interface { // AddMember attempts to add a member into the cluster. It will return // ErrIDRemoved if member ID is removed from the cluster, or return // ErrIDExists if member ID exists in the cluster. - AddMember(ctx context.Context, memb Member) error + AddMember(ctx context.Context, memb membership.Member) error // RemoveMember attempts to remove a member from the cluster. It will // return ErrIDRemoved if member ID is removed from the cluster, or return // ErrIDNotFound if member ID is not in the cluster. @@ -134,7 +135,7 @@ type Server interface { // UpdateMember attempts to update an existing member in the cluster. It will // return ErrIDNotFound if the member ID does not exist. - UpdateMember(ctx context.Context, updateMemb Member) error + UpdateMember(ctx context.Context, updateMemb membership.Member) error // ClusterVersion is the cluster-wide minimum major.minor version. // Cluster version is set to the min version that an etcd member is @@ -167,17 +168,19 @@ type EtcdServer struct { done chan struct{} errorc chan error id types.ID - attributes Attributes + attributes membership.Attributes - cluster *cluster + cluster *membership.RaftCluster store store.Store - kv dstorage.ConsistentWatchableKV - lessor lease.Lessor - bemu sync.Mutex - be backend.Backend - authStore auth.AuthStore + applyV3 applierV3 + kv dstorage.ConsistentWatchableKV + lessor lease.Lessor + bemu sync.Mutex + be backend.Backend + authStore auth.AuthStore + alarmStore *alarm.AlarmStore stats *stats.ServerStats lstats *stats.LeaderStats @@ -214,17 +217,13 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { n raft.Node s *raft.MemoryStorage id types.ID - cl *cluster + cl *membership.RaftCluster ) if terr := fileutil.TouchDirAll(cfg.DataDir); terr != nil { return nil, fmt.Errorf("cannot access data directory: %v", terr) } - if !cfg.V3demo && fileutil.Exist(path.Join(cfg.SnapDir(), databaseFilename)) { - return nil, errors.New("experimental-v3demo cannot be disabled once it is enabled") - } - // Run the migrations. dataVer, err := version.DetectDataDir(cfg.DataDir) if err != nil { @@ -241,13 +240,13 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { if err != nil { return nil, err } - var remotes []*Member + var remotes []*membership.Member switch { case !haveWAL && !cfg.NewCluster: if err := cfg.VerifyJoinExisting(); err != nil { return nil, err } - cl, err = newClusterFromURLsMap(cfg.InitialClusterToken, cfg.InitialPeerURLsMap) + cl, err = membership.NewClusterFromURLsMap(cfg.InitialClusterToken, cfg.InitialPeerURLsMap) if err != nil { return nil, err } @@ -255,7 +254,7 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { if err != nil { return nil, fmt.Errorf("cannot fetch cluster info from peer urls: %v", err) } - if err := ValidateClusterAndAssignIDs(cl, existingCluster); err != nil { + if err := membership.ValidateClusterAndAssignIDs(cl, existingCluster); err != nil { return nil, fmt.Errorf("error validating peerURLs %s: %v", existingCluster, err) } if !isCompatibleWithCluster(cl, cl.MemberByName(cfg.Name).ID, prt) { @@ -263,7 +262,7 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { } remotes = existingCluster.Members() - cl.SetID(existingCluster.id) + cl.SetID(existingCluster.ID()) cl.SetStore(st) cfg.Print() id, n, s, w = startNode(cfg, cl, nil) @@ -271,7 +270,7 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { if err := cfg.VerifyBootstrap(); err != nil { return nil, err } - cl, err = newClusterFromURLsMap(cfg.InitialClusterToken, cfg.InitialPeerURLsMap) + cl, err = membership.NewClusterFromURLsMap(cfg.InitialClusterToken, cfg.InitialPeerURLsMap) if err != nil { return nil, err } @@ -293,7 +292,7 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { if checkDuplicateURL(urlsmap) { return nil, fmt.Errorf("discovery cluster %s has duplicate url", urlsmap) } - if cl, err = newClusterFromURLsMap(cfg.InitialClusterToken, urlsmap); err != nil { + if cl, err = membership.NewClusterFromURLsMap(cfg.InitialClusterToken, urlsmap); err != nil { return nil, err } } @@ -359,7 +358,7 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { storage: NewStorage(w, ss), }, id: id, - attributes: Attributes{Name: cfg.Name, ClientURLs: cfg.ClientURLs.StringSlice()}, + attributes: membership.Attributes{Name: cfg.Name, ClientURLs: cfg.ClientURLs.StringSlice()}, cluster: cl, stats: sstats, lstats: lstats, @@ -370,15 +369,18 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { msgSnapC: make(chan raftpb.Message, maxInFlightMsgSnap), } - if cfg.V3demo { - srv.be = backend.NewDefaultBackend(path.Join(cfg.SnapDir(), databaseFilename)) - srv.lessor = lease.NewLessor(srv.be) - srv.kv = dstorage.New(srv.be, srv.lessor, &srv.consistIndex) - srv.authStore = auth.NewAuthStore(srv) - if h := cfg.AutoCompactionRetention; h != 0 { - srv.compactor = compactor.NewPeriodic(h, srv.kv, srv) - srv.compactor.Run() - } + srv.be = backend.NewDefaultBackend(path.Join(cfg.SnapDir(), databaseFilename)) + srv.lessor = lease.NewLessor(srv.be) + srv.kv = dstorage.New(srv.be, srv.lessor, &srv.consistIndex) + srv.consistIndex.setConsistentIndex(srv.kv.ConsistentIndex()) + srv.authStore = auth.NewAuthStore(srv.be) + if h := cfg.AutoCompactionRetention; h != 0 { + srv.compactor = compactor.NewPeriodic(h, srv.kv, srv) + srv.compactor.Run() + } + + if err := srv.restoreAlarms(); err != nil { + return nil, err } // TODO: move transport initialization near the definition of remote @@ -393,7 +395,6 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) { ServerStats: sstats, LeaderStats: lstats, ErrorC: srv.errorc, - V3demo: cfg.V3demo, } if err := tr.Start(); err != nil { return nil, err @@ -466,7 +467,7 @@ func (s *EtcdServer) purgeFile() { func (s *EtcdServer) ID() types.ID { return s.id } -func (s *EtcdServer) Cluster() Cluster { return s.cluster } +func (s *EtcdServer) Cluster() *membership.RaftCluster { return s.cluster } func (s *EtcdServer) RaftHandler() http.Handler { return s.r.transport.Handler() } @@ -588,40 +589,48 @@ func (s *EtcdServer) applySnapshot(ep *etcdProgress, apply *apply) { apply.snapshot.Metadata.Index, ep.appliedi) } - if s.cfg.V3demo { - snapfn, err := s.r.storage.DBFilePath(apply.snapshot.Metadata.Index) - if err != nil { - plog.Panicf("get database snapshot file path error: %v", err) - } - - fn := path.Join(s.cfg.SnapDir(), databaseFilename) - if err := os.Rename(snapfn, fn); err != nil { - plog.Panicf("rename snapshot file error: %v", err) - } - - newbe := backend.NewDefaultBackend(fn) - if err := s.kv.Restore(newbe); err != nil { - plog.Panicf("restore KV error: %v", err) - } - - // Closing old backend might block until all the txns - // on the backend are finished. - // We do not want to wait on closing the old backend. - s.bemu.Lock() - oldbe := s.be - go func() { - if err := oldbe.Close(); err != nil { - plog.Panicf("close backend error: %v", err) - } - }() - - s.be = newbe - s.bemu.Unlock() - - if s.lessor != nil { - s.lessor.Recover(newbe, s.kv) - } + snapfn, err := s.r.storage.DBFilePath(apply.snapshot.Metadata.Index) + if err != nil { + plog.Panicf("get database snapshot file path error: %v", err) } + + fn := path.Join(s.cfg.SnapDir(), databaseFilename) + if err := os.Rename(snapfn, fn); err != nil { + plog.Panicf("rename snapshot file error: %v", err) + } + + newbe := backend.NewDefaultBackend(fn) + if err := s.kv.Restore(newbe); err != nil { + plog.Panicf("restore KV error: %v", err) + } + s.consistIndex.setConsistentIndex(s.kv.ConsistentIndex()) + + // Closing old backend might block until all the txns + // on the backend are finished. + // We do not want to wait on closing the old backend. + s.bemu.Lock() + oldbe := s.be + go func() { + if err := oldbe.Close(); err != nil { + plog.Panicf("close backend error: %v", err) + } + }() + + s.be = newbe + s.bemu.Unlock() + + if s.lessor != nil { + s.lessor.Recover(newbe, s.kv) + } + + if err := s.restoreAlarms(); err != nil { + plog.Panicf("restore alarms error: %v", err) + } + + if s.authStore != nil { + s.authStore.Recover(newbe) + } + if err := s.store.Recovery(apply.snapshot.Data); err != nil { plog.Panicf("recovery store error: %v", err) } @@ -784,9 +793,9 @@ func (s *EtcdServer) LeaderStats() []byte { func (s *EtcdServer) StoreStats() []byte { return s.store.JsonStats() } -func (s *EtcdServer) AddMember(ctx context.Context, memb Member) error { - if s.cfg.StrictReconfigCheck && !s.cluster.isReadyToAddNewMember() { - // If s.cfg.StrictReconfigCheck is false, it means the option -strict-reconfig-check isn't passed to etcd. +func (s *EtcdServer) AddMember(ctx context.Context, memb membership.Member) error { + if s.cfg.StrictReconfigCheck && !s.cluster.IsReadyToAddNewMember() { + // If s.cfg.StrictReconfigCheck is false, it means the option --strict-reconfig-check isn't passed to etcd. // In such a case adding a new member is allowed unconditionally return ErrNotEnoughStartedMembers } @@ -805,8 +814,8 @@ func (s *EtcdServer) AddMember(ctx context.Context, memb Member) error { } func (s *EtcdServer) RemoveMember(ctx context.Context, id uint64) error { - if s.cfg.StrictReconfigCheck && !s.cluster.isReadyToRemoveMember(id) { - // If s.cfg.StrictReconfigCheck is false, it means the option -strict-reconfig-check isn't passed to etcd. + if s.cfg.StrictReconfigCheck && !s.cluster.IsReadyToRemoveMember(id) { + // If s.cfg.StrictReconfigCheck is false, it means the option --strict-reconfig-check isn't passed to etcd. // In such a case removing a member is allowed unconditionally return ErrNotEnoughStartedMembers } @@ -818,7 +827,7 @@ func (s *EtcdServer) RemoveMember(ctx context.Context, id uint64) error { return s.configure(ctx, cc) } -func (s *EtcdServer) UpdateMember(ctx context.Context, memb Member) error { +func (s *EtcdServer) UpdateMember(ctx context.Context, memb membership.Member) error { b, err := json.Marshal(memb) if err != nil { return err @@ -906,7 +915,7 @@ func (s *EtcdServer) publish(timeout time.Duration) { } req := pb.Request{ Method: "PUT", - Path: MemberAttributesStorePath(s.id), + Path: membership.MemberAttributesStorePath(s.id), Val: string(b), } @@ -934,20 +943,17 @@ func (s *EtcdServer) send(ms []raftpb.Message) { ms[i].To = 0 } - if s.cfg.V3demo { - if ms[i].Type == raftpb.MsgSnap { - // There are two separate data store when v3 demo is enabled: the store for v2, - // and the KV for v3. - // The msgSnap only contains the most recent snapshot of store without KV. - // So we need to redirect the msgSnap to etcd server main loop for merging in the - // current store snapshot and KV snapshot. - select { - case s.msgSnapC <- ms[i]: - default: - // drop msgSnap if the inflight chan if full. - } - ms[i].To = 0 + if ms[i].Type == raftpb.MsgSnap { + // There are two separate data store: the store for v2, and the KV for v3. + // The msgSnap only contains the most recent snapshot of store without KV. + // So we need to redirect the msgSnap to etcd server main loop for merging in the + // current store snapshot and KV snapshot. + select { + case s.msgSnapC <- ms[i]: + default: + // drop msgSnap if the inflight chan if full. } + ms[i].To = 0 } if ms[i].Type == raftpb.MsgHeartbeat { ok, exceed := s.r.td.Observe(ms[i].To) @@ -994,8 +1000,6 @@ func (s *EtcdServer) apply(es []raftpb.Entry, confState *raftpb.ConfState) (uint var shouldstop bool for i := range es { e := es[i] - // set the consistent index of current executing entry - s.consistIndex.setConsistentIndex(e.Index) switch e.Type { case raftpb.EntryNormal: // raft state machine may generate noop entry when leader confirmation. @@ -1013,14 +1017,32 @@ func (s *EtcdServer) apply(es []raftpb.Entry, confState *raftpb.ConfState) (uint var r pb.Request pbutil.MustUnmarshal(&r, e.Data) s.w.Trigger(r.ID, s.applyRequest(r)) + } else if raftReq.V2 != nil { + req := raftReq.V2 + s.w.Trigger(req.ID, s.applyRequest(*req)) } else { - switch { - case raftReq.V2 != nil: - req := raftReq.V2 - s.w.Trigger(req.ID, s.applyRequest(*req)) - default: - s.w.Trigger(raftReq.ID, s.applyV3Request(&raftReq)) + // do not re-apply applied entries. + if e.Index <= s.consistIndex.ConsistentIndex() { + break } + // set the consistent index of current executing entry + s.consistIndex.setConsistentIndex(e.Index) + ar := s.applyV3Request(&raftReq) + if ar.err != ErrNoSpace || len(s.alarmStore.Get(pb.AlarmType_NOSPACE)) > 0 { + s.w.Trigger(raftReq.ID, ar) + break + } + plog.Errorf("applying raft message exceeded backend quota") + go func() { + a := &pb.AlarmRequest{ + MemberID: uint64(s.ID()), + Action: pb.AlarmRequest_ACTIVATE, + Alarm: pb.AlarmType_NOSPACE, + } + r := pb.InternalRaftRequest{Alarm: a} + s.processInternalRaftRequest(context.TODO(), r) + s.w.Trigger(raftReq.ID, ar) + }() } case raftpb.EntryConfChange: var cc raftpb.ConfChange @@ -1072,8 +1094,8 @@ func (s *EtcdServer) applyRequest(r pb.Request) Response { // TODO (yicheng): cluster should be the owner of cluster prefix store // we should not modify cluster store here. if storeMemberAttributeRegexp.MatchString(r.Path) { - id := mustParseMemberIDFromKey(path.Dir(r.Path)) - var attr Attributes + id := membership.MustParseMemberIDFromKey(path.Dir(r.Path)) + var attr membership.Attributes if err := json.Unmarshal([]byte(r.Val), &attr); err != nil { plog.Panicf("unmarshal %s should never fail: %v", r.Val, err) } @@ -1116,7 +1138,7 @@ func (s *EtcdServer) applyConfChange(cc raftpb.ConfChange, confState *raftpb.Con *confState = *s.r.ApplyConfChange(cc) switch cc.Type { case raftpb.ConfChangeAddNode: - m := new(Member) + m := new(membership.Member) if err := json.Unmarshal(cc.Context, m); err != nil { plog.Panicf("unmarshal member should never fail: %v", err) } @@ -1140,7 +1162,7 @@ func (s *EtcdServer) applyConfChange(cc raftpb.ConfChange, confState *raftpb.Con plog.Noticef("removed member %s from cluster %s", id, s.cluster.ID()) } case raftpb.ConfChangeUpdateNode: - m := new(Member) + m := new(membership.Member) if err := json.Unmarshal(cc.Context, m); err != nil { plog.Panicf("unmarshal member should never fail: %v", err) } @@ -1178,11 +1200,9 @@ func (s *EtcdServer) snapshot(snapi uint64, confState raftpb.ConfState) { } plog.Panicf("unexpected create snapshot error %v", err) } - if s.cfg.V3demo { - // commit v3 storage because WAL file before snapshot index - // could be removed after SaveSnap. - s.getKV().Commit() - } + // commit v3 storage because WAL file before snapshot index + // could be removed after SaveSnap. + s.KV().Commit() // SaveSnap saves the snapshot and releases the locked wal files // to the snapshot index. if err = s.r.storage.SaveSnap(snap); err != nil { @@ -1321,7 +1341,7 @@ func (s *EtcdServer) parseProposeCtxErr(err error, start time.Time) error { } } -func (s *EtcdServer) getKV() dstorage.ConsistentWatchableKV { return s.kv } +func (s *EtcdServer) KV() dstorage.ConsistentWatchableKV { return s.kv } func (s *EtcdServer) Backend() backend.Backend { s.bemu.Lock() defer s.bemu.Unlock() @@ -1329,3 +1349,17 @@ func (s *EtcdServer) Backend() backend.Backend { } func (s *EtcdServer) AuthStore() auth.AuthStore { return s.authStore } + +func (s *EtcdServer) restoreAlarms() error { + s.applyV3 = newQuotaApplierV3(s, &applierV3backend{s}) + + as, err := alarm.NewAlarmStore(s) + if err != nil { + return err + } + s.alarmStore = as + if len(as.Get(pb.AlarmType_NOSPACE)) > 0 { + s.applyV3 = newApplierV3Capped(s.applyV3) + } + return nil +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/util.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/util.go index e02a1d0a158..0f4c3772b94 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/util.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/util.go @@ -17,13 +17,14 @@ package etcdserver import ( "time" + "github.com/coreos/etcd/etcdserver/membership" "github.com/coreos/etcd/pkg/types" "github.com/coreos/etcd/rafthttp" ) // isConnectedToQuorumSince checks whether the local member is connected to the // quorum of the cluster since the given time. -func isConnectedToQuorumSince(transport rafthttp.Transporter, since time.Time, self types.ID, members []*Member) bool { +func isConnectedToQuorumSince(transport rafthttp.Transporter, since time.Time, self types.ID, members []*membership.Member) bool { var connectedNum int for _, m := range members { if m.ID == self || isConnectedSince(transport, since, m.ID) { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/v3demo_server.go b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/v3demo_server.go index 1ce8bad675f..eb81e2b8941 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/v3demo_server.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/etcdserver/v3demo_server.go @@ -15,17 +15,12 @@ package etcdserver import ( - "bytes" - "fmt" - "sort" "time" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/lease" "github.com/coreos/etcd/lease/leasehttp" dstorage "github.com/coreos/etcd/storage" - "github.com/coreos/etcd/storage/storagepb" - "github.com/gogo/protobuf/proto" "golang.org/x/net/context" ) @@ -43,12 +38,11 @@ type RaftKV interface { DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error) - Hash(ctx context.Context, r *pb.HashRequest) (*pb.HashResponse, error) } type Lessor interface { - // LeaseCreate sends LeaseCreate request to raft and apply it after committed. - LeaseCreate(ctx context.Context, r *pb.LeaseCreateRequest) (*pb.LeaseCreateResponse, error) + // LeaseGrant sends LeaseGrant request to raft and apply it after committed. + LeaseGrant(ctx context.Context, r *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) // LeaseRevoke sends LeaseRevoke request to raft and apply it after committed. LeaseRevoke(ctx context.Context, r *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) @@ -59,11 +53,15 @@ type Lessor interface { type Authenticator interface { AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) + UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) + UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) + UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) + RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) } func (s *EtcdServer) Range(ctx context.Context, r *pb.RangeRequest) (*pb.RangeResponse, error) { if r.Serializable { - return applyRange(noTxn, s.kv, r) + return s.applyV3.Range(noTxn, r) } result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Range: r}) @@ -90,6 +88,10 @@ func (s *EtcdServer) DeleteRange(ctx context.Context, r *pb.DeleteRangeRequest) } func (s *EtcdServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse, error) { + if isTxnSerializable(r) { + return s.applyV3.Txn(r) + } + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Txn: r}) if err != nil { return nil, err @@ -97,8 +99,31 @@ func (s *EtcdServer) Txn(ctx context.Context, r *pb.TxnRequest) (*pb.TxnResponse return result.resp.(*pb.TxnResponse), result.err } +func isTxnSerializable(r *pb.TxnRequest) bool { + for _, u := range r.Success { + if r := u.GetRequestRange(); r == nil || !r.Serializable { + return false + } + } + for _, u := range r.Failure { + if r := u.GetRequestRange(); r == nil || !r.Serializable { + return false + } + } + return true +} + func (s *EtcdServer) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb.CompactionResponse, error) { result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Compaction: r}) + if r.Physical && result.physc != nil { + <-result.physc + // The compaction is done deleting keys; the hash is now settled + // but the data is not necessarily committed. If there's a crash, + // the hash may revert to a hash prior to compaction completing + // if the compaction resumes. Force the finished compaction to + // commit so it won't resume following a crash. + s.be.ForceCommit() + } if err != nil { return nil, err } @@ -113,25 +138,17 @@ func (s *EtcdServer) Compact(ctx context.Context, r *pb.CompactionRequest) (*pb. return resp, result.err } -func (s *EtcdServer) Hash(ctx context.Context, r *pb.HashRequest) (*pb.HashResponse, error) { - h, err := s.be.Hash() - if err != nil { - return nil, err - } - return &pb.HashResponse{Header: &pb.ResponseHeader{Revision: s.kv.Rev()}, Hash: h}, nil -} - -func (s *EtcdServer) LeaseCreate(ctx context.Context, r *pb.LeaseCreateRequest) (*pb.LeaseCreateResponse, error) { +func (s *EtcdServer) LeaseGrant(ctx context.Context, r *pb.LeaseGrantRequest) (*pb.LeaseGrantResponse, error) { // no id given? choose one for r.ID == int64(lease.NoLease) { // only use positive int64 id's r.ID = int64(s.reqIDGen.Next() & ((1 << 63) - 1)) } - result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{LeaseCreate: r}) + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{LeaseGrant: r}) if err != nil { return nil, err } - return result.resp.(*pb.LeaseCreateResponse), result.err + return result.resp.(*pb.LeaseGrantResponse), result.err } func (s *EtcdServer) LeaseRevoke(ctx context.Context, r *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) { @@ -177,6 +194,14 @@ func (s *EtcdServer) LeaseRenew(id lease.LeaseID) (int64, error) { return ttl, err } +func (s *EtcdServer) Alarm(ctx context.Context, r *pb.AlarmRequest) (*pb.AlarmResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{Alarm: r}) + if err != nil { + return nil, err + } + return result.resp.(*pb.AlarmResponse), result.err +} + func (s *EtcdServer) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (*pb.AuthEnableResponse, error) { result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthEnable: r}) if err != nil { @@ -185,9 +210,36 @@ func (s *EtcdServer) AuthEnable(ctx context.Context, r *pb.AuthEnableRequest) (* return result.resp.(*pb.AuthEnableResponse), result.err } -type applyResult struct { - resp proto.Message - err error +func (s *EtcdServer) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserAdd: r}) + if err != nil { + return nil, err + } + return result.resp.(*pb.AuthUserAddResponse), result.err +} + +func (s *EtcdServer) UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest) (*pb.AuthUserDeleteResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserDelete: r}) + if err != nil { + return nil, err + } + return result.resp.(*pb.AuthUserDeleteResponse), result.err +} + +func (s *EtcdServer) UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthUserChangePassword: r}) + if err != nil { + return nil, err + } + return result.resp.(*pb.AuthUserChangePasswordResponse), result.err +} + +func (s *EtcdServer) RoleAdd(ctx context.Context, r *pb.AuthRoleAddRequest) (*pb.AuthRoleAddResponse, error) { + result, err := s.processInternalRaftRequest(ctx, pb.InternalRaftRequest{AuthRoleAdd: r}) + if err != nil { + return nil, err + } + return result.resp.(*pb.AuthRoleAddResponse), result.err } func (s *EtcdServer) processInternalRaftRequest(ctx context.Context, r pb.InternalRaftRequest) (*applyResult, error) { @@ -218,445 +270,4 @@ func (s *EtcdServer) processInternalRaftRequest(ctx context.Context, r pb.Intern } // Watchable returns a watchable interface attached to the etcdserver. -func (s *EtcdServer) Watchable() dstorage.Watchable { - return s.getKV() -} - -const ( - // noTxn is an invalid txn ID. - // To apply with independent Range, Put, Delete, you can pass noTxn - // to apply functions instead of a valid txn ID. - noTxn = -1 -) - -func (s *EtcdServer) applyV3Request(r *pb.InternalRaftRequest) interface{} { - kv := s.getKV() - le := s.lessor - - ar := &applyResult{} - - switch { - case r.Range != nil: - ar.resp, ar.err = applyRange(noTxn, kv, r.Range) - case r.Put != nil: - ar.resp, ar.err = applyPut(noTxn, kv, le, r.Put) - case r.DeleteRange != nil: - ar.resp, ar.err = applyDeleteRange(noTxn, kv, r.DeleteRange) - case r.Txn != nil: - ar.resp, ar.err = applyTxn(kv, le, r.Txn) - case r.Compaction != nil: - ar.resp, ar.err = applyCompaction(kv, r.Compaction) - case r.LeaseCreate != nil: - ar.resp, ar.err = applyLeaseCreate(le, r.LeaseCreate) - case r.LeaseRevoke != nil: - ar.resp, ar.err = applyLeaseRevoke(le, r.LeaseRevoke) - case r.AuthEnable != nil: - ar.resp, ar.err = applyAuthEnable(s) - default: - panic("not implemented") - } - - return ar -} - -func applyPut(txnID int64, kv dstorage.KV, le lease.Lessor, p *pb.PutRequest) (*pb.PutResponse, error) { - resp := &pb.PutResponse{} - resp.Header = &pb.ResponseHeader{} - var ( - rev int64 - err error - ) - if txnID != noTxn { - rev, err = kv.TxnPut(txnID, p.Key, p.Value, lease.LeaseID(p.Lease)) - if err != nil { - return nil, err - } - } else { - leaseID := lease.LeaseID(p.Lease) - if leaseID != lease.NoLease { - if l := le.Lookup(leaseID); l == nil { - return nil, lease.ErrLeaseNotFound - } - } - rev = kv.Put(p.Key, p.Value, leaseID) - } - resp.Header.Revision = rev - return resp, nil -} - -type kvSort struct{ kvs []storagepb.KeyValue } - -func (s *kvSort) Swap(i, j int) { - t := s.kvs[i] - s.kvs[i] = s.kvs[j] - s.kvs[j] = t -} -func (s *kvSort) Len() int { return len(s.kvs) } - -type kvSortByKey struct{ *kvSort } - -func (s *kvSortByKey) Less(i, j int) bool { - return bytes.Compare(s.kvs[i].Key, s.kvs[j].Key) < 0 -} - -type kvSortByVersion struct{ *kvSort } - -func (s *kvSortByVersion) Less(i, j int) bool { - return (s.kvs[i].Version - s.kvs[j].Version) < 0 -} - -type kvSortByCreate struct{ *kvSort } - -func (s *kvSortByCreate) Less(i, j int) bool { - return (s.kvs[i].CreateRevision - s.kvs[j].CreateRevision) < 0 -} - -type kvSortByMod struct{ *kvSort } - -func (s *kvSortByMod) Less(i, j int) bool { - return (s.kvs[i].ModRevision - s.kvs[j].ModRevision) < 0 -} - -type kvSortByValue struct{ *kvSort } - -func (s *kvSortByValue) Less(i, j int) bool { - return bytes.Compare(s.kvs[i].Value, s.kvs[j].Value) < 0 -} - -func applyRange(txnID int64, kv dstorage.KV, r *pb.RangeRequest) (*pb.RangeResponse, error) { - resp := &pb.RangeResponse{} - resp.Header = &pb.ResponseHeader{} - - var ( - kvs []storagepb.KeyValue - rev int64 - err error - ) - - if isGteRange(r.RangeEnd) { - r.RangeEnd = []byte{} - } - - limit := r.Limit - if r.SortOrder != pb.RangeRequest_NONE { - // fetch everything; sort and truncate afterwards - limit = 0 - } - if limit > 0 { - // fetch one extra for 'more' flag - limit = limit + 1 - } - - if txnID != noTxn { - kvs, rev, err = kv.TxnRange(txnID, r.Key, r.RangeEnd, limit, r.Revision) - if err != nil { - return nil, err - } - } else { - kvs, rev, err = kv.Range(r.Key, r.RangeEnd, limit, r.Revision) - if err != nil { - return nil, err - } - } - - if r.SortOrder != pb.RangeRequest_NONE { - var sorter sort.Interface - switch { - case r.SortTarget == pb.RangeRequest_KEY: - sorter = &kvSortByKey{&kvSort{kvs}} - case r.SortTarget == pb.RangeRequest_VERSION: - sorter = &kvSortByVersion{&kvSort{kvs}} - case r.SortTarget == pb.RangeRequest_CREATE: - sorter = &kvSortByCreate{&kvSort{kvs}} - case r.SortTarget == pb.RangeRequest_MOD: - sorter = &kvSortByMod{&kvSort{kvs}} - case r.SortTarget == pb.RangeRequest_VALUE: - sorter = &kvSortByValue{&kvSort{kvs}} - } - switch { - case r.SortOrder == pb.RangeRequest_ASCEND: - sort.Sort(sorter) - case r.SortOrder == pb.RangeRequest_DESCEND: - sort.Sort(sort.Reverse(sorter)) - } - } - - if r.Limit > 0 && len(kvs) > int(r.Limit) { - kvs = kvs[:r.Limit] - resp.More = true - } - - resp.Header.Revision = rev - for i := range kvs { - resp.Kvs = append(resp.Kvs, &kvs[i]) - } - return resp, nil -} - -func applyDeleteRange(txnID int64, kv dstorage.KV, dr *pb.DeleteRangeRequest) (*pb.DeleteRangeResponse, error) { - resp := &pb.DeleteRangeResponse{} - resp.Header = &pb.ResponseHeader{} - - var ( - n int64 - rev int64 - err error - ) - - if isGteRange(dr.RangeEnd) { - dr.RangeEnd = []byte{} - } - - if txnID != noTxn { - n, rev, err = kv.TxnDeleteRange(txnID, dr.Key, dr.RangeEnd) - if err != nil { - return nil, err - } - } else { - n, rev = kv.DeleteRange(dr.Key, dr.RangeEnd) - } - - resp.Deleted = n - resp.Header.Revision = rev - return resp, nil -} - -func checkRequestLeases(le lease.Lessor, reqs []*pb.RequestUnion) error { - for _, requ := range reqs { - tv, ok := requ.Request.(*pb.RequestUnion_RequestPut) - if !ok { - continue - } - preq := tv.RequestPut - if preq == nil || lease.LeaseID(preq.Lease) == lease.NoLease { - continue - } - if l := le.Lookup(lease.LeaseID(preq.Lease)); l == nil { - return lease.ErrLeaseNotFound - } - } - return nil -} - -func checkRequestRange(kv dstorage.KV, reqs []*pb.RequestUnion) error { - for _, requ := range reqs { - tv, ok := requ.Request.(*pb.RequestUnion_RequestRange) - if !ok { - continue - } - greq := tv.RequestRange - if greq == nil || greq.Revision == 0 { - continue - } - - if greq.Revision > kv.Rev() { - return dstorage.ErrFutureRev - } - if greq.Revision < kv.FirstRev() { - return dstorage.ErrCompacted - } - } - return nil -} - -func applyTxn(kv dstorage.KV, le lease.Lessor, rt *pb.TxnRequest) (*pb.TxnResponse, error) { - var revision int64 - - ok := true - for _, c := range rt.Compare { - if revision, ok = applyCompare(kv, c); !ok { - break - } - } - - var reqs []*pb.RequestUnion - if ok { - reqs = rt.Success - } else { - reqs = rt.Failure - } - - if err := checkRequestLeases(le, reqs); err != nil { - return nil, err - } - if err := checkRequestRange(kv, reqs); err != nil { - return nil, err - } - - // When executing the operations of txn, we need to hold the txn lock. - // So the reader will not see any intermediate results. - txnID := kv.TxnBegin() - defer func() { - err := kv.TxnEnd(txnID) - if err != nil { - panic(fmt.Sprint("unexpected error when closing txn", txnID)) - } - }() - - resps := make([]*pb.ResponseUnion, len(reqs)) - for i := range reqs { - resps[i] = applyUnion(txnID, kv, reqs[i]) - } - - if len(resps) != 0 { - revision += 1 - } - - txnResp := &pb.TxnResponse{} - txnResp.Header = &pb.ResponseHeader{} - txnResp.Header.Revision = revision - txnResp.Responses = resps - txnResp.Succeeded = ok - return txnResp, nil -} - -func applyCompaction(kv dstorage.KV, compaction *pb.CompactionRequest) (*pb.CompactionResponse, error) { - resp := &pb.CompactionResponse{} - resp.Header = &pb.ResponseHeader{} - err := kv.Compact(compaction.Revision) - if err != nil { - return nil, err - } - // get the current revision. which key to get is not important. - _, resp.Header.Revision, _ = kv.Range([]byte("compaction"), nil, 1, 0) - return resp, err -} - -func applyUnion(txnID int64, kv dstorage.KV, union *pb.RequestUnion) *pb.ResponseUnion { - switch tv := union.Request.(type) { - case *pb.RequestUnion_RequestRange: - if tv.RequestRange != nil { - resp, err := applyRange(txnID, kv, tv.RequestRange) - if err != nil { - panic("unexpected error during txn") - } - return &pb.ResponseUnion{Response: &pb.ResponseUnion_ResponseRange{ResponseRange: resp}} - } - case *pb.RequestUnion_RequestPut: - if tv.RequestPut != nil { - resp, err := applyPut(txnID, kv, nil, tv.RequestPut) - if err != nil { - panic("unexpected error during txn") - } - return &pb.ResponseUnion{Response: &pb.ResponseUnion_ResponsePut{ResponsePut: resp}} - } - case *pb.RequestUnion_RequestDeleteRange: - if tv.RequestDeleteRange != nil { - resp, err := applyDeleteRange(txnID, kv, tv.RequestDeleteRange) - if err != nil { - panic("unexpected error during txn") - } - return &pb.ResponseUnion{Response: &pb.ResponseUnion_ResponseDeleteRange{ResponseDeleteRange: resp}} - } - default: - // empty union - return nil - } - return nil -} - -// applyCompare applies the compare request. -// It returns the revision at which the comparison happens. If the comparison -// succeeds, the it returns true. Otherwise it returns false. -func applyCompare(kv dstorage.KV, c *pb.Compare) (int64, bool) { - ckvs, rev, err := kv.Range(c.Key, nil, 1, 0) - if err != nil { - if err == dstorage.ErrTxnIDMismatch { - panic("unexpected txn ID mismatch error") - } - return rev, false - } - var ckv storagepb.KeyValue - if len(ckvs) != 0 { - ckv = ckvs[0] - } else { - // Use the zero value of ckv normally. However... - if c.Target == pb.Compare_VALUE { - // Always fail if we're comparing a value on a key that doesn't exist. - // We can treat non-existence as the empty set explicitly, such that - // even a key with a value of length 0 bytes is still a real key - // that was written that way - return rev, false - } - } - - // -1 is less, 0 is equal, 1 is greater - var result int - switch c.Target { - case pb.Compare_VALUE: - tv, _ := c.TargetUnion.(*pb.Compare_Value) - if tv != nil { - result = bytes.Compare(ckv.Value, tv.Value) - } - case pb.Compare_CREATE: - tv, _ := c.TargetUnion.(*pb.Compare_CreateRevision) - if tv != nil { - result = compareInt64(ckv.CreateRevision, tv.CreateRevision) - } - - case pb.Compare_MOD: - tv, _ := c.TargetUnion.(*pb.Compare_ModRevision) - if tv != nil { - result = compareInt64(ckv.ModRevision, tv.ModRevision) - } - case pb.Compare_VERSION: - tv, _ := c.TargetUnion.(*pb.Compare_Version) - if tv != nil { - result = compareInt64(ckv.Version, tv.Version) - } - } - - switch c.Result { - case pb.Compare_EQUAL: - if result != 0 { - return rev, false - } - case pb.Compare_GREATER: - if result != 1 { - return rev, false - } - case pb.Compare_LESS: - if result != -1 { - return rev, false - } - } - return rev, true -} - -func applyLeaseCreate(le lease.Lessor, lc *pb.LeaseCreateRequest) (*pb.LeaseCreateResponse, error) { - l, err := le.Grant(lease.LeaseID(lc.ID), lc.TTL) - resp := &pb.LeaseCreateResponse{} - if err == nil { - resp.ID = int64(l.ID) - resp.TTL = l.TTL - } - return resp, err -} - -func applyLeaseRevoke(le lease.Lessor, lc *pb.LeaseRevokeRequest) (*pb.LeaseRevokeResponse, error) { - err := le.Revoke(lease.LeaseID(lc.ID)) - - return &pb.LeaseRevokeResponse{}, err -} - -func compareInt64(a, b int64) int { - switch { - case a < b: - return -1 - case a > b: - return 1 - default: - return 0 - } -} - -// isGteRange determines if the range end is a >= range. This works around grpc -// sending empty byte strings as nil; >= is encoded in the range end as '\0'. -func isGteRange(rangeEnd []byte) bool { - return len(rangeEnd) == 1 && rangeEnd[0] == 0 -} - -func applyAuthEnable(s *EtcdServer) (*pb.AuthEnableResponse, error) { - s.AuthStore().AuthEnable() - return &pb.AuthEnableResponse{}, nil -} +func (s *EtcdServer) Watchable() dstorage.Watchable { return s.KV() } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/integration/cluster.go b/Godeps/_workspace/src/github.com/coreos/etcd/integration/cluster.go index 31a437bfba9..4798aeb707e 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/integration/cluster.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/integration/cluster.go @@ -10,10 +10,12 @@ // 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.package recipe +// limitations under the License. + package integration import ( + "crypto/tls" "fmt" "io/ioutil" "math/rand" @@ -35,8 +37,8 @@ import ( "github.com/coreos/etcd/client" "github.com/coreos/etcd/clientv3" "github.com/coreos/etcd/etcdserver" + "github.com/coreos/etcd/etcdserver/api/v2http" "github.com/coreos/etcd/etcdserver/api/v3rpc" - "github.com/coreos/etcd/etcdserver/etcdhttp" pb "github.com/coreos/etcd/etcdserver/etcdserverpb" "github.com/coreos/etcd/pkg/testutil" "github.com/coreos/etcd/pkg/transport" @@ -70,7 +72,6 @@ type ClusterConfig struct { PeerTLS *transport.TLSInfo ClientTLS *transport.TLSInfo DiscoveryURL string - UseV3 bool UseGRPC bool } @@ -197,7 +198,6 @@ func (c *cluster) mustNewMember(t *testing.T) *member { name := c.name(rand.Int()) m := mustNewMember(t, name, c.cfg.PeerTLS, c.cfg.ClientTLS) m.DiscoveryURL = c.cfg.DiscoveryURL - m.V3demo = c.cfg.UseV3 if c.cfg.UseGRPC { if err := m.listenGRPC(); err != nil { t.Fatal(err) @@ -469,9 +469,6 @@ func mustNewMember(t *testing.T, name string, peerTLS *transport.TLSInfo, client // listenGRPC starts a grpc server over a unix domain socket on the member func (m *member) listenGRPC() error { - if m.V3demo == false { - return fmt.Errorf("starting grpc server without v3 configured") - } // prefix with localhost so cert has right domain m.grpcAddr = "localhost:" + m.Name + ".sock" if err := os.RemoveAll(m.grpcAddr); err != nil { @@ -549,7 +546,7 @@ func (m *member) Launch() error { m.s.SyncTicker = time.Tick(500 * time.Millisecond) m.s.Start() - m.raftHandler = &testutil.PauseableHandler{Next: etcdhttp.NewPeerHandler(m.s)} + m.raftHandler = &testutil.PauseableHandler{Next: v2http.NewPeerHandler(m.s)} for _, ln := range m.PeerListeners { hs := &httptest.Server{ @@ -570,7 +567,7 @@ func (m *member) Launch() error { for _, ln := range m.ClientListeners { hs := &httptest.Server{ Listener: ln, - Config: &http.Server{Handler: etcdhttp.NewClientHandler(m.s, m.ServerConfig.ReqTimeout())}, + Config: &http.Server{Handler: v2http.NewClientHandler(m.s, m.ServerConfig.ReqTimeout())}, } if m.ClientTLSInfo == nil { hs.Start() @@ -584,7 +581,16 @@ func (m *member) Launch() error { m.hss = append(m.hss, hs) } if m.grpcListener != nil { - m.grpcServer, err = v3rpc.Server(m.s, m.ClientTLSInfo) + var ( + tlscfg *tls.Config + ) + if m.ClientTLSInfo != nil && !m.ClientTLSInfo.Empty() { + tlscfg, err = m.ClientTLSInfo.ServerConfig() + if err != nil { + return err + } + } + m.grpcServer = v3rpc.Server(m.s, tlscfg) go m.grpcServer.Serve(m.grpcListener) } return nil @@ -712,7 +718,6 @@ type ClusterV3 struct { // NewClusterV3 returns a launched cluster with a grpc client connection // for each cluster member. func NewClusterV3(t *testing.T, cfg *ClusterConfig) *ClusterV3 { - cfg.UseV3 = true cfg.UseGRPC = true clus := &ClusterV3{cluster: NewClusterByConfig(t, cfg)} for _, m := range clus.Members { @@ -752,6 +757,8 @@ type grpcAPI struct { Lease pb.LeaseClient // Watch is the watch API for the client's connection. Watch pb.WatchClient + // Maintenance is the maintenance API for the client's connection. + Maintenance pb.MaintenanceClient } func toGRPC(c *clientv3.Client) grpcAPI { @@ -760,5 +767,6 @@ func toGRPC(c *clientv3.Client) grpcAPI { pb.NewKVClient(c.ActiveConnection()), pb.NewLeaseClient(c.ActiveConnection()), pb.NewWatchClient(c.ActiveConnection()), + pb.NewMaintenanceClient(c.ActiveConnection()), } } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/lease/leasepb/lease.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/lease/leasepb/lease.pb.go index b98ca98ca2a..9c0d77124c2 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/lease/leasepb/lease.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/lease/leasepb/lease.pb.go @@ -17,9 +17,9 @@ import ( "fmt" proto "github.com/gogo/protobuf/proto" -) -import math "math" + math "math" +) import io "io" diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/adt/interval_tree.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/adt/interval_tree.go index 465c6200c6e..a3ec803f64f 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/adt/interval_tree.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/adt/interval_tree.go @@ -27,10 +27,12 @@ type Comparable interface { Compare(c Comparable) int } -type rbcolor bool +type rbcolor int -const black = true -const red = false +const ( + black rbcolor = iota + red +) // Interval implements a Comparable interval [begin, end) // TODO: support different sorts of intervals: (a,b), [a,b], (a, b] @@ -400,7 +402,7 @@ func (ivt *IntervalTree) MaxHeight() int { return int((2 * math.Log2(float64(ivt.Len()+1))) + 0.5) } -// InternalVisitor is used on tree searchs; return false to stop searching. +// IntervalVisitor is used on tree searchs; return false to stop searching. type IntervalVisitor func(n *IntervalValue) bool // Visit calls a visitor function on every tree node intersecting the given interval. diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock.go index bf411d3a179..da2b92c7314 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock.go @@ -14,16 +14,13 @@ package fileutil -type Lock interface { - // Name returns the name of the file. - Name() string - // TryLock acquires exclusivity on the lock without blocking. - TryLock() error - // Lock acquires exclusivity on the lock. - Lock() error - // Unlock unlocks the lock. - Unlock() error - // Destroy should be called after Unlock to clean up - // the resources. - Destroy() error -} +import ( + "errors" + "os" +) + +var ( + ErrLocked = errors.New("fileutil: file already locked") +) + +type LockedFile struct{ *os.File } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_plan9.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_plan9.go index bd2bc867645..1c924a7e5f6 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_plan9.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_plan9.go @@ -15,65 +15,31 @@ package fileutil import ( - "errors" "os" "syscall" "time" ) -var ( - ErrLocked = errors.New("file already locked") -) - -type lock struct { - fname string - file *os.File +func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { + if err := os.Chmod(path, syscall.DMEXCL|0600); err != nil { + return nil, err + } + f, err := os.Open(path, flag, perm) + if err != nil { + return nil, ErrLocked + } + return &LockedFile{f}, nil } -func (l *lock) Name() string { - return l.fname -} - -func (l *lock) TryLock() error { - err := os.Chmod(l.fname, syscall.DMEXCL|0600) - if err != nil { - return err +func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { + if err := os.Chmod(path, syscall.DMEXCL|0600); err != nil { + return nil, err } - - f, err := os.Open(l.fname) - if err != nil { - return ErrLocked - } - - l.file = f - return nil -} - -func (l *lock) Lock() error { - err := os.Chmod(l.fname, syscall.DMEXCL|0600) - if err != nil { - return err - } - for { - f, err := os.Open(l.fname) + f, err := os.OpenFile(path, flag, perm) if err == nil { - l.file = f - return nil + return &LockedFile{f}, nil } time.Sleep(10 * time.Millisecond) } } - -func (l *lock) Unlock() error { - return l.file.Close() -} - -func (l *lock) Destroy() error { - return nil -} - -func NewLock(file string) (Lock, error) { - l := &lock{fname: file} - return l, nil -} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_solaris.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_solaris.go index e3b0a017683..0d5375aee74 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_solaris.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_solaris.go @@ -17,25 +17,11 @@ package fileutil import ( - "errors" "os" "syscall" ) -var ( - ErrLocked = errors.New("file already locked") -) - -type lock struct { - fd int - file *os.File -} - -func (l *lock) Name() string { - return l.file.Name() -} - -func (l *lock) TryLock() error { +func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { var lock syscall.Flock_t lock.Start = 0 lock.Len = 0 @@ -43,45 +29,34 @@ func (l *lock) TryLock() error { lock.Type = syscall.F_WRLCK lock.Whence = 0 lock.Pid = 0 - err := syscall.FcntlFlock(uintptr(l.fd), syscall.F_SETLK, &lock) - if err != nil && err == syscall.EAGAIN { - return ErrLocked - } - return err -} - -func (l *lock) Lock() error { - var lock syscall.Flock_t - lock.Start = 0 - lock.Len = 0 - lock.Type = syscall.F_WRLCK - lock.Whence = 0 - lock.Pid = 0 - return syscall.FcntlFlock(uintptr(l.fd), syscall.F_SETLK, &lock) -} - -func (l *lock) Unlock() error { - var lock syscall.Flock_t - lock.Start = 0 - lock.Len = 0 - lock.Type = syscall.F_UNLCK - lock.Whence = 0 - err := syscall.FcntlFlock(uintptr(l.fd), syscall.F_SETLK, &lock) - if err != nil && err == syscall.EAGAIN { - return ErrLocked - } - return err -} - -func (l *lock) Destroy() error { - return l.file.Close() -} - -func NewLock(file string) (Lock, error) { - f, err := os.OpenFile(file, os.O_WRONLY, 0600) + f, err := os.OpenFile(path, flag, perm) if err != nil { return nil, err } - l := &lock{int(f.Fd()), f} - return l, nil + if err := syscall.FcntlFlock(f.Fd(), syscall.F_SETLK, &lock); err != nil { + f.Close() + if err == syscall.EAGAIN { + err = ErrLocked + } + return nil, err + } + return &LockedFile{f}, nil +} + +func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { + var lock syscall.Flock_t + lock.Start = 0 + lock.Len = 0 + lock.Pid = 0 + lock.Type = syscall.F_WRLCK + lock.Whence = 0 + f, err := os.OpenFile(path, flag, perm) + if err != nil { + return nil, err + } + if err = syscall.FcntlFlock(f.Fd(), syscall.F_SETLKW, &lock); err != nil { + f.Close() + return nil, err + } + return &LockedFile{f}, nil } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_unix.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_unix.go index 4f90e42aced..aa5127ef550 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_unix.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_unix.go @@ -17,49 +17,33 @@ package fileutil import ( - "errors" "os" "syscall" ) -var ( - ErrLocked = errors.New("file already locked") -) - -type lock struct { - fd int - file *os.File -} - -func (l *lock) Name() string { - return l.file.Name() -} - -func (l *lock) TryLock() error { - err := syscall.Flock(l.fd, syscall.LOCK_EX|syscall.LOCK_NB) - if err != nil && err == syscall.EWOULDBLOCK { - return ErrLocked - } - return err -} - -func (l *lock) Lock() error { - return syscall.Flock(l.fd, syscall.LOCK_EX) -} - -func (l *lock) Unlock() error { - return syscall.Flock(l.fd, syscall.LOCK_UN) -} - -func (l *lock) Destroy() error { - return l.file.Close() -} - -func NewLock(file string) (Lock, error) { - f, err := os.Open(file) +func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { + f, err := os.OpenFile(path, flag, perm) if err != nil { return nil, err } - l := &lock{int(f.Fd()), f} - return l, nil + if err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil { + f.Close() + if err == syscall.EWOULDBLOCK { + err = ErrLocked + } + return nil, err + } + return &LockedFile{f}, nil +} + +func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { + f, err := os.OpenFile(path, flag, perm) + if err != nil { + return nil, err + } + if err = syscall.Flock(int(f.Fd()), syscall.LOCK_EX); err != nil { + f.Close() + return nil, err + } + return &LockedFile{f}, err } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_windows.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_windows.go index ddca9a66959..67a425a9124 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_windows.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/lock_windows.go @@ -18,43 +18,108 @@ package fileutil import ( "errors" + "fmt" "os" + "syscall" + "unsafe" ) var ( - ErrLocked = errors.New("file already locked") + modkernel32 = syscall.NewLazyDLL("kernel32.dll") + procLockFileEx = modkernel32.NewProc("LockFileEx") + + errLocked = errors.New("The process cannot access the file because another process has locked a portion of the file.") ) -type lock struct { - fd int - file *os.File -} +const ( + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx + LOCKFILE_EXCLUSIVE_LOCK = 2 + LOCKFILE_FAIL_IMMEDIATELY = 1 -func (l *lock) Name() string { - return l.file.Name() -} + // see https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx + errLockViolation syscall.Errno = 0x21 +) -func (l *lock) TryLock() error { - return nil -} - -func (l *lock) Lock() error { - return nil -} - -func (l *lock) Unlock() error { - return nil -} - -func (l *lock) Destroy() error { - return l.file.Close() -} - -func NewLock(file string) (Lock, error) { - f, err := os.Open(file) +func TryLockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { + f, err := open(path, flag, perm) if err != nil { return nil, err } - l := &lock{int(f.Fd()), f} - return l, nil + if err := lockFile(syscall.Handle(f.Fd()), LOCKFILE_FAIL_IMMEDIATELY); err != nil { + f.Close() + return nil, err + } + return &LockedFile{f}, nil +} + +func LockFile(path string, flag int, perm os.FileMode) (*LockedFile, error) { + f, err := open(path, flag, perm) + if err != nil { + return nil, err + } + if err := lockFile(syscall.Handle(f.Fd()), 0); err != nil { + f.Close() + return nil, err + } + return &LockedFile{f}, nil +} + +func open(path string, flag int, perm os.FileMode) (*os.File, error) { + if path == "" { + return nil, fmt.Errorf("cannot open empty filename") + } + var access uint32 + switch flag { + case syscall.O_RDONLY: + access = syscall.GENERIC_READ + case syscall.O_WRONLY: + access = syscall.GENERIC_WRITE + case syscall.O_RDWR: + access = syscall.GENERIC_READ | syscall.GENERIC_WRITE + case syscall.O_WRONLY | syscall.O_CREAT: + access = syscall.GENERIC_ALL + default: + panic(fmt.Errorf("flag %v is not supported", flag)) + } + fd, err := syscall.CreateFile(&(syscall.StringToUTF16(path)[0]), + access, + syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE, + nil, + syscall.OPEN_ALWAYS, + syscall.FILE_ATTRIBUTE_NORMAL, + 0) + if err != nil { + return nil, err + } + return os.NewFile(uintptr(fd), path), nil +} + +func lockFile(fd syscall.Handle, flags uint32) error { + var flag uint32 = LOCKFILE_EXCLUSIVE_LOCK + flag |= flags + if fd == syscall.InvalidHandle { + return nil + } + err := lockFileEx(fd, flag, 1, 0, &syscall.Overlapped{}) + if err == nil { + return nil + } else if err.Error() == errLocked.Error() { + return ErrLocked + } else if err != errLockViolation { + return err + } + return nil +} + +func lockFileEx(h syscall.Handle, flags, locklow, lockhigh uint32, ol *syscall.Overlapped) (err error) { + var reserved uint32 = 0 + r1, _, e1 := syscall.Syscall6(procLockFileEx.Addr(), 6, uintptr(h), uintptr(flags), uintptr(reserved), uintptr(locklow), uintptr(lockhigh), uintptr(unsafe.Pointer(ol))) + if r1 == 0 { + if e1 != 0 { + err = error(e1) + } else { + err = syscall.EINVAL + } + } + return } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/preallocate.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/preallocate.go index c4bd4f4c815..8cd03f015e4 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/preallocate.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/preallocate.go @@ -12,31 +12,36 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build linux - package fileutil -import ( - "os" - "syscall" -) +import "os" // Preallocate tries to allocate the space for given // file. This operation is only supported on linux by a // few filesystems (btrfs, ext4, etc.). // If the operation is unsupported, no error will be returned. // Otherwise, the error encountered will be returned. -func Preallocate(f *os.File, sizeInBytes int) error { - // use mode = 1 to keep size - // see FALLOC_FL_KEEP_SIZE - err := syscall.Fallocate(int(f.Fd()), 1, 0, int64(sizeInBytes)) +func Preallocate(f *os.File, sizeInBytes int64, extendFile bool) error { + if extendFile { + preallocExtend(f, sizeInBytes) + } + return preallocFixed(f, sizeInBytes) +} + +func preallocExtendTrunc(f *os.File, sizeInBytes int64) error { + curOff, err := f.Seek(0, os.SEEK_CUR) if err != nil { - errno, ok := err.(syscall.Errno) - // treat not support as nil error - if ok && errno == syscall.ENOTSUP { - return nil - } return err } - return nil + size, err := f.Seek(sizeInBytes, os.SEEK_END) + if err != nil { + return err + } + if _, err = f.Seek(curOff, os.SEEK_SET); err != nil { + return err + } + if sizeInBytes > size { + return nil + } + return f.Truncate(sizeInBytes) } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/preallocate_darwin.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/preallocate_darwin.go new file mode 100644 index 00000000000..5ac19508a7c --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/preallocate_darwin.go @@ -0,0 +1,43 @@ +// Copyright 2016 CoreOS, 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. + +// +build darwin + +package fileutil + +import ( + "os" + "syscall" + "unsafe" +) + +func preallocExtend(f *os.File, sizeInBytes int64) error { + if err := preallocFixed(f, sizeInBytes); err != nil { + return err + } + return preallocExtendTrunc(f, sizeInBytes) +} + +func preallocFixed(f *os.File, sizeInBytes int64) error { + fstore := &syscall.Fstore_t{ + Flags: syscall.F_ALLOCATEALL, + Posmode: syscall.F_PEOFPOSMODE, + Length: sizeInBytes} + p := unsafe.Pointer(fstore) + _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_PREALLOCATE), uintptr(p)) + if errno == 0 || errno == syscall.ENOTSUP { + return nil + } + return errno +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/preallocate_unix.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/preallocate_unix.go new file mode 100644 index 00000000000..b71113e7259 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/preallocate_unix.go @@ -0,0 +1,48 @@ +// Copyright 2016 CoreOS, 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. + +// +build linux + +package fileutil + +import ( + "os" + "syscall" +) + +func preallocExtend(f *os.File, sizeInBytes int64) error { + // use mode = 0 to change size + err := syscall.Fallocate(int(f.Fd()), 0, 0, sizeInBytes) + if err != nil { + errno, ok := err.(syscall.Errno) + // treat not support as nil error + if ok && errno == syscall.ENOTSUP { + return preallocExtendTrunc(f, sizeInBytes) + } + } + return err +} + +func preallocFixed(f *os.File, sizeInBytes int64) error { + // use mode = 1 to keep size; see FALLOC_FL_KEEP_SIZE + err := syscall.Fallocate(int(f.Fd()), 1, 0, sizeInBytes) + if err != nil { + errno, ok := err.(syscall.Errno) + // treat not supported as nil error + if ok && errno == syscall.ENOTSUP { + return nil + } + } + return err +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/perallocate_unsupported.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/preallocate_unsupported.go similarity index 64% rename from Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/perallocate_unsupported.go rename to Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/preallocate_unsupported.go index c1a952bb796..7f94a3653ef 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/perallocate_unsupported.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/preallocate_unsupported.go @@ -12,17 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build !linux +// +build !linux,!darwin package fileutil import "os" -// Preallocate tries to allocate the space for given -// file. This operation is only supported on linux by a -// few filesystems (btrfs, ext4, etc.). -// If the operation is unsupported, no error will be returned. -// Otherwise, the error encountered will be returned. -func Preallocate(f *os.File, sizeInBytes int) error { - return nil +func preallocExtend(f *os.File, sizeInBytes int64) error { + return preallocExtendTrunc(f, sizeInBytes) } + +func preallocFixed(f *os.File, sizeInBytes int64) error { return nil } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/purge.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/purge.go index 375aa971974..0d1bd99c0d6 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/purge.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/fileutil/purge.go @@ -40,32 +40,19 @@ func PurgeFile(dirname string, suffix string, max uint, interval time.Duration, sort.Strings(newfnames) for len(newfnames) > int(max) { f := path.Join(dirname, newfnames[0]) - l, err := NewLock(f) - if err != nil { - errC <- err - return - } - err = l.TryLock() + l, err := TryLockFile(f, os.O_WRONLY, 0600) if err != nil { break } - err = os.Remove(f) - if err != nil { + if err = os.Remove(f); err != nil { errC <- err return } - err = l.Unlock() - if err != nil { + if err = l.Close(); err != nil { plog.Errorf("error unlocking %s when purging file (%v)", l.Name(), err) errC <- err return } - err = l.Destroy() - if err != nil { - plog.Errorf("error destroying lock %s when purging file (%v)", l.Name(), err) - errC <- err - return - } plog.Infof("purged file %s successfully", f) newfnames = newfnames[1:] } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/httputil/cancelreq_go14.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/httputil/cancelreq_go14.go deleted file mode 100644 index b270f921289..00000000000 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/httputil/cancelreq_go14.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// borrowed from golang/net/context/ctxhttp/cancelreq_go14.go - -// +build !go1.5 - -package httputil - -import "net/http" - -type requestCanceler interface { - CancelRequest(req *http.Request) -} - -func RequestCanceler(rt http.RoundTripper, req *http.Request) func() { - c, ok := rt.(requestCanceler) - if !ok { - return func() {} - } - return func() { - c.CancelRequest(req) - } -} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/httputil/cancelreq.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/httputil/httputil.go similarity index 59% rename from Godeps/_workspace/src/github.com/coreos/etcd/pkg/httputil/cancelreq.go rename to Godeps/_workspace/src/github.com/coreos/etcd/pkg/httputil/httputil.go index e3a7a7422de..daf43bd8f6c 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/httputil/cancelreq.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/httputil/httputil.go @@ -4,12 +4,14 @@ // borrowed from golang/net/context/ctxhttp/cancelreq.go -// +build go1.5 - // Package httputil provides HTTP utility functions. package httputil -import "net/http" +import ( + "io" + "io/ioutil" + "net/http" +) func RequestCanceler(rt http.RoundTripper, req *http.Request) func() { ch := make(chan struct{}) @@ -19,3 +21,11 @@ func RequestCanceler(rt http.RoundTripper, req *http.Request) func() { close(ch) } } + +// GracefulClose drains http.Response.Body until it hits EOF +// and closes it. This prevents TCP/TLS connections from closing, +// therefore available for reuse. +func GracefulClose(resp *http.Response) { + io.Copy(ioutil.Discard, resp.Body) + resp.Body.Close() +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/netutil/netutil.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/netutil/netutil.go index 5a24abed46e..4292cd06f63 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/netutil/netutil.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/netutil/netutil.go @@ -116,3 +116,8 @@ func URLStringsEqual(a []string, b []string) bool { return urlsEqual(urlsA, urlsB) } + +func IsNetworkTimeoutError(err error) bool { + nerr, ok := err.(net.Error) + return ok && nerr.Timeout() +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/testutil/leak.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/testutil/leak.go index 38ef4dc9d7a..79b8b2db4d6 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/testutil/leak.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/testutil/leak.go @@ -74,12 +74,7 @@ func AfterTest(t *testing.T) { "timeoutHandler": "a TimeoutHandler", "net.(*netFD).connect(": "a timing out dial", ").noteClientGone(": "a closenotifier sender", - } - - // readLoop was buggy before go1.5: - // https://github.com/golang/go/issues/10457 - if getAtLeastGo15() { - badSubstring[").readLoop("] = "a Transport" + ").readLoop(": "a Transport", } var stacks string @@ -126,11 +121,3 @@ func interestingGoroutines() (gs []string) { sort.Strings(gs) return } - -// getAtLeastGo15 returns true if the runtime has go1.5+. -func getAtLeastGo15() bool { - var major, minor int - var discard string - i, err := fmt.Sscanf(runtime.Version(), "go%d.%d%s", &major, &minor, &discard) - return (err == nil && i == 3 && (major > 1 || major == 1 && minor >= 5)) -} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/testutil/testutil.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/testutil/testutil.go index 464e5cccfb4..a789667b5c0 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/testutil/testutil.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/testutil/testutil.go @@ -22,6 +22,7 @@ import ( "time" ) +// WaitSchedule briefly sleeps in order to invoke the go scheduler. // TODO: improve this when we are able to know the schedule or status of target go-routine. func WaitSchedule() { time.Sleep(10 * time.Millisecond) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/tlsutil/tlsutil.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/tlsutil/tlsutil.go new file mode 100644 index 00000000000..340dd2c09d0 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/tlsutil/tlsutil.go @@ -0,0 +1,72 @@ +// Copyright 2016 CoreOS, 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. + +package tlsutil + +import ( + "crypto/tls" + "crypto/x509" + "encoding/pem" + "io/ioutil" +) + +// NewCertPool creates x509 certPool with provided CA files. +func NewCertPool(CAFiles []string) (*x509.CertPool, error) { + certPool := x509.NewCertPool() + + for _, CAFile := range CAFiles { + pemByte, err := ioutil.ReadFile(CAFile) + if err != nil { + return nil, err + } + + for { + var block *pem.Block + block, pemByte = pem.Decode(pemByte) + if block == nil { + break + } + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, err + } + certPool.AddCert(cert) + } + } + + return certPool, nil +} + +// NewCert generates TLS cert by using the given cert,key and parse function. +func NewCert(certfile, keyfile string, parseFunc func([]byte, []byte) (tls.Certificate, error)) (*tls.Certificate, error) { + cert, err := ioutil.ReadFile(certfile) + if err != nil { + return nil, err + } + + key, err := ioutil.ReadFile(keyfile) + if err != nil { + return nil, err + } + + if parseFunc == nil { + parseFunc = tls.X509KeyPair + } + + tlsCert, err := parseFunc(cert, key) + if err != nil { + return nil, err + } + return &tlsCert, nil +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/keepalive_listener.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/keepalive_listener.go index 1fe1ba80dd4..ee9a3a13e5b 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/keepalive_listener.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/keepalive_listener.go @@ -30,17 +30,12 @@ type keepAliveConn interface { // Be careful when wrap around KeepAliveListener with another Listener if TLSInfo is not nil. // Some pkgs (like go/http) might expect Listener to return TLSConn type to start TLS handshake. // http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html -func NewKeepAliveListener(l net.Listener, scheme string, info TLSInfo) (net.Listener, error) { +func NewKeepAliveListener(l net.Listener, scheme string, tlscfg *tls.Config) (net.Listener, error) { if scheme == "https" { - if info.Empty() { + if tlscfg == nil { return nil, fmt.Errorf("cannot listen on TLS for given listener: KeyFile and CertFile are not presented") } - cfg, err := info.ServerConfig() - if err != nil { - return nil, err - } - - return newTLSKeepaliveListener(l, cfg), nil + return newTLSKeepaliveListener(l, tlscfg), nil } return &keepaliveListener{ diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/limit_listen.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/limit_listen.go index 8a81a6b93f7..ad2bc417c21 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/limit_listen.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/limit_listen.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package netutil provides network utility functions, complementing the more +// Package transport provides network utility functions, complementing the more // common ones in the net package. package transport diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/listener.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/listener.go index 56c77b409c0..931652d3f13 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/listener.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/listener.go @@ -15,17 +15,26 @@ package transport import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" "crypto/tls" "crypto/x509" + "crypto/x509/pkix" "encoding/pem" "fmt" - "io/ioutil" + "math/big" "net" "net/http" + "os" + "path" + "strings" "time" + + "github.com/coreos/etcd/pkg/tlsutil" ) -func NewListener(addr string, scheme string, info TLSInfo) (net.Listener, error) { +func NewListener(addr string, scheme string, tlscfg *tls.Config) (net.Listener, error) { nettype := "tcp" if scheme == "unix" { // unix sockets via unix://laddr @@ -38,15 +47,11 @@ func NewListener(addr string, scheme string, info TLSInfo) (net.Listener, error) } if scheme == "https" { - if info.Empty() { + if tlscfg == nil { return nil, fmt.Errorf("cannot listen on TLS for %s: KeyFile and CertFile are not presented", scheme+"://"+addr) } - cfg, err := info.ServerConfig() - if err != nil { - return nil, err - } - l = tls.NewListener(l, cfg) + l = tls.NewListener(l, tlscfg) } return l, nil @@ -59,6 +64,7 @@ func NewTransport(info TLSInfo, dialtimeoutd time.Duration) (*http.Transport, er } t := &http.Transport{ + Proxy: http.ProxyFromEnvironment, Dial: (&net.Dialer{ Timeout: dialtimeoutd, // value taken from http.DefaultTransport @@ -79,6 +85,8 @@ type TLSInfo struct { TrustedCAFile string ClientCertAuth bool + selfCert bool + // parseFunc exists to simplify testing. Typically, parseFunc // should be left nil. In that case, tls.X509KeyPair will be used. parseFunc func([]byte, []byte) (tls.Certificate, error) @@ -92,33 +100,90 @@ func (info TLSInfo) Empty() bool { return info.CertFile == "" && info.KeyFile == "" } +func SelfCert(dirpath string, hosts []string) (info TLSInfo, err error) { + if err = os.MkdirAll(dirpath, 0700); err != nil { + return + } + + certPath := path.Join(dirpath, "cert.pem") + keyPath := path.Join(dirpath, "key.pem") + _, errcert := os.Stat(certPath) + _, errkey := os.Stat(keyPath) + if errcert == nil && errkey == nil { + info.CertFile = certPath + info.KeyFile = keyPath + info.selfCert = true + return + } + + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + if err != nil { + return + } + + tmpl := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{Organization: []string{"etcd"}}, + NotBefore: time.Now(), + NotAfter: time.Now().Add(365 * (24 * time.Hour)), + + KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + BasicConstraintsValid: true, + } + + for _, host := range hosts { + if ip := net.ParseIP(host); ip != nil { + tmpl.IPAddresses = append(tmpl.IPAddresses, ip) + } else { + tmpl.DNSNames = append(tmpl.DNSNames, strings.Split(host, ":")[0]) + } + } + + priv, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) + if err != nil { + return + } + + derBytes, err := x509.CreateCertificate(rand.Reader, &tmpl, &tmpl, &priv.PublicKey, priv) + if err != nil { + return + } + + certOut, err := os.Create(certPath) + if err != nil { + return + } + pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) + certOut.Close() + + b, err := x509.MarshalECPrivateKey(priv) + if err != nil { + return + } + keyOut, err := os.OpenFile(keyPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + return + } + pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}) + keyOut.Close() + + return SelfCert(dirpath, hosts) +} + func (info TLSInfo) baseConfig() (*tls.Config, error) { if info.KeyFile == "" || info.CertFile == "" { return nil, fmt.Errorf("KeyFile and CertFile must both be present[key: %v, cert: %v]", info.KeyFile, info.CertFile) } - cert, err := ioutil.ReadFile(info.CertFile) - if err != nil { - return nil, err - } - - key, err := ioutil.ReadFile(info.KeyFile) - if err != nil { - return nil, err - } - - parseFunc := info.parseFunc - if parseFunc == nil { - parseFunc = tls.X509KeyPair - } - - tlsCert, err := parseFunc(cert, key) + tlsCert, err := tlsutil.NewCert(info.CertFile, info.KeyFile, info.parseFunc) if err != nil { return nil, err } cfg := &tls.Config{ - Certificates: []tls.Certificate{tlsCert}, + Certificates: []tls.Certificate{*tlsCert}, MinVersion: tls.VersionTLS10, } return cfg, nil @@ -150,7 +215,7 @@ func (info TLSInfo) ServerConfig() (*tls.Config, error) { CAFiles := info.cafiles() if len(CAFiles) > 0 { - cp, err := newCertPool(CAFiles) + cp, err := tlsutil.NewCertPool(CAFiles) if err != nil { return nil, err } @@ -176,38 +241,14 @@ func (info TLSInfo) ClientConfig() (*tls.Config, error) { CAFiles := info.cafiles() if len(CAFiles) > 0 { - cfg.RootCAs, err = newCertPool(CAFiles) + cfg.RootCAs, err = tlsutil.NewCertPool(CAFiles) if err != nil { return nil, err } } + if info.selfCert { + cfg.InsecureSkipVerify = true + } return cfg, nil } - -// newCertPool creates x509 certPool with provided CA files. -func newCertPool(CAFiles []string) (*x509.CertPool, error) { - certPool := x509.NewCertPool() - - for _, CAFile := range CAFiles { - pemByte, err := ioutil.ReadFile(CAFile) - if err != nil { - return nil, err - } - - for { - var block *pem.Block - block, pemByte = pem.Decode(pemByte) - if block == nil { - break - } - cert, err := x509.ParseCertificate(block.Bytes) - if err != nil { - return nil, err - } - certPool.AddCert(cert) - } - } - - return certPool, nil -} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/timeout_listener.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/timeout_listener.go index 6992a8eee05..bf12ba6ed1d 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/timeout_listener.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/transport/timeout_listener.go @@ -15,6 +15,7 @@ package transport import ( + "crypto/tls" "net" "time" ) @@ -22,8 +23,8 @@ import ( // NewTimeoutListener returns a listener that listens on the given address. // If read/write on the accepted connection blocks longer than its time limit, // it will return timeout error. -func NewTimeoutListener(addr string, scheme string, info TLSInfo, rdtimeoutd, wtimeoutd time.Duration) (net.Listener, error) { - ln, err := NewListener(addr, scheme, info) +func NewTimeoutListener(addr string, scheme string, tlscfg *tls.Config, rdtimeoutd, wtimeoutd time.Duration) (net.Listener, error) { + ln, err := NewListener(addr, scheme, tlscfg) if err != nil { return nil, err } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/types/urls.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/types/urls.go index ce2483ffaaa..8d5ff624811 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/types/urls.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/types/urls.go @@ -53,6 +53,14 @@ func NewURLs(strs []string) (URLs, error) { return us, nil } +func MustNewURLs(strs []string) URLs { + urls, err := NewURLs(strs) + if err != nil { + panic(err) + } + return urls +} + func (us URLs) String() string { return strings.Join(us.StringSlice(), ",") } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/raft/log.go b/Godeps/_workspace/src/github.com/coreos/etcd/raft/log.go index 99cd1b31ef2..7a2709afbb1 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/raft/log.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/raft/log.go @@ -152,10 +152,7 @@ func (l *raftLog) nextEnts() (ents []pb.Entry) { // is a fast check without heavy raftLog.slice() in raftLog.nextEnts(). func (l *raftLog) hasNextEnts() bool { off := max(l.applied+1, l.firstIndex()) - if l.committed+1 > off { - return true - } - return false + return l.committed+1 > off } func (l *raftLog) snapshot() (pb.Snapshot, error) { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/raft/raft.go b/Godeps/_workspace/src/github.com/coreos/etcd/raft/raft.go index 5639fcb8f3a..e7da600b762 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/raft/raft.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/raft/raft.go @@ -29,8 +29,6 @@ import ( const None uint64 = 0 const noLimit = math.MaxUint64 -var errNoLeader = errors.New("no leader") - var ErrSnapshotTemporarilyUnavailable = errors.New("snapshot is temporarily unavailable") // Possible values for StateType. @@ -176,9 +174,14 @@ type raft struct { heartbeatTimeout int electionTimeout int - rand *rand.Rand - tick func() - step stepFunc + // randomizedElectionTimeout is a random number between + // [electiontimeout, 2 * electiontimeout - 1]. It gets reset + // when raft changes its state to follower or candidate. + randomizedElectionTimeout int + + rand *rand.Rand + tick func() + step stepFunc logger Logger } @@ -392,6 +395,7 @@ func (r *raft) reset(term uint64) { r.electionElapsed = 0 r.heartbeatElapsed = 0 + r.resetRandomizedElectionTimeout() r.votes = make(map[uint64]bool) for id := range r.prs { @@ -422,7 +426,7 @@ func (r *raft) tickElection() { return } r.electionElapsed++ - if r.isElectionTimeout() { + if r.pastElectionTimeout() { r.electionElapsed = 0 r.Step(pb.Message{From: r.id, Type: pb.MsgHup}) } @@ -863,15 +867,15 @@ func (r *raft) loadState(state pb.HardState) { r.Vote = state.Vote } -// isElectionTimeout returns true if r.electionElapsed is greater than the -// randomized election timeout in (electiontimeout, 2 * electiontimeout - 1). -// Otherwise, it returns false. -func (r *raft) isElectionTimeout() bool { - d := r.electionElapsed - r.electionTimeout - if d < 0 { - return false - } - return d > r.rand.Int()%r.electionTimeout +// pastElectionTimeout returns true iff r.electionElapsed is greater +// than or equal to the randomized election timeout in +// [electiontimeout, 2 * electiontimeout - 1]. +func (r *raft) pastElectionTimeout() bool { + return r.electionElapsed >= r.randomizedElectionTimeout +} + +func (r *raft) resetRandomizedElectionTimeout() { + r.randomizedElectionTimeout = r.electionTimeout + r.rand.Intn(r.electionTimeout) } // checkQuorumActive returns true if the quorum is active from diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/raft/raftpb/raft.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/raft/raftpb/raft.pb.go index 319134cdeb6..41e619d655d 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/raft/raftpb/raft.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/raft/raftpb/raft.pb.go @@ -23,9 +23,9 @@ import ( "fmt" proto "github.com/gogo/protobuf/proto" -) -import math "math" + math "math" +) import io "io" diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/peer.go b/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/peer.go index 145c53fef5e..30b9c4cdca9 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/peer.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/peer.go @@ -92,9 +92,8 @@ type Peer interface { // It is only used when the stream has not been established. type peer struct { // id of the remote raft peer node - id types.ID - r Raft - v3demo bool + id types.ID + r Raft status *peerStatus @@ -118,13 +117,12 @@ type peer struct { stopc chan struct{} } -func startPeer(transport *Transport, urls types.URLs, local, to, cid types.ID, r Raft, fs *stats.FollowerStats, errorc chan error, v3demo bool) *peer { +func startPeer(transport *Transport, urls types.URLs, local, to, cid types.ID, r Raft, fs *stats.FollowerStats, errorc chan error) *peer { status := newPeerStatus(to) picker := newURLPicker(urls) p := &peer{ id: to, r: r, - v3demo: v3demo, status: status, picker: picker, msgAppV2Writer: startStreamWriter(to, status, fs, r), @@ -142,11 +140,23 @@ func startPeer(transport *Transport, urls types.URLs, local, to, cid types.ID, r go func() { for { select { - case mm := <-p.propc: + case mm := <-p.recvc: if err := r.Process(ctx, mm); err != nil { plog.Warningf("failed to process raft message (%v)", err) } - case mm := <-p.recvc: + case <-p.stopc: + return + } + } + }() + + // r.Process might block for processing proposal when there is no leader. + // Thus propc must be put into a separate routine with recvc to avoid blocking + // processing other raft messages. + go func() { + for { + select { + case mm := <-p.propc: if err := r.Process(ctx, mm); err != nil { plog.Warningf("failed to process raft message (%v)", err) } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/snapshot_sender.go b/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/snapshot_sender.go index 12e62d7c52d..a871b886abf 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/snapshot_sender.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/snapshot_sender.go @@ -124,7 +124,7 @@ func (s *snapshotSender) post(req *http.Request) (err error) { // close the response body when timeouts. // prevents from reading the body forever when the other side dies right after // successfully receives the request body. - time.AfterFunc(snapResponseReadTimeout, func() { resp.Body.Close() }) + time.AfterFunc(snapResponseReadTimeout, func() { httputil.GracefulClose(resp) }) body, err := ioutil.ReadAll(resp.Body) result <- responseAndError{resp, body, err} }() diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/stream.go b/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/stream.go index af8185f8226..1a76b89cc2f 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/stream.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/stream.go @@ -374,12 +374,6 @@ func (cr *streamReader) stop() { <-cr.done } -func (cr *streamReader) isWorking() bool { - cr.mu.Lock() - defer cr.mu.Unlock() - return cr.closer != nil -} - func (cr *streamReader) dial(t streamType) (io.ReadCloser, error) { u := cr.picker.pick() uu := u @@ -417,14 +411,14 @@ func (cr *streamReader) dial(t streamType) (io.ReadCloser, error) { rv := serverVersion(resp.Header) lv := semver.Must(semver.NewVersion(version.Version)) if compareMajorMinorVersion(rv, lv) == -1 && !checkStreamSupport(rv, t) { - resp.Body.Close() + httputil.GracefulClose(resp) cr.picker.unreachable(u) return nil, errUnsupportedStreamType } switch resp.StatusCode { case http.StatusGone: - resp.Body.Close() + httputil.GracefulClose(resp) cr.picker.unreachable(u) err := fmt.Errorf("the member has been permanently removed from the cluster") select { @@ -435,7 +429,7 @@ func (cr *streamReader) dial(t streamType) (io.ReadCloser, error) { case http.StatusOK: return resp.Body, nil case http.StatusNotFound: - resp.Body.Close() + httputil.GracefulClose(resp) cr.picker.unreachable(u) return nil, fmt.Errorf("remote member %s could not recognize local member", cr.remote) case http.StatusPreconditionFailed: @@ -444,7 +438,7 @@ func (cr *streamReader) dial(t streamType) (io.ReadCloser, error) { cr.picker.unreachable(u) return nil, err } - resp.Body.Close() + httputil.GracefulClose(resp) cr.picker.unreachable(u) switch strings.TrimSuffix(string(b), "\n") { @@ -459,7 +453,7 @@ func (cr *streamReader) dial(t streamType) (io.ReadCloser, error) { return nil, fmt.Errorf("unhandled error %q when precondition failed", string(b)) } default: - resp.Body.Close() + httputil.GracefulClose(resp) cr.picker.unreachable(u) return nil, fmt.Errorf("unhandled http status %d", resp.StatusCode) } @@ -500,8 +494,3 @@ func checkStreamSupport(v *semver.Version, t streamType) bool { } return false } - -func isNetworkTimeoutError(err error) bool { - nerr, ok := err.(net.Error) - return ok && nerr.Timeout() -} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/transport.go b/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/transport.go index b2654ef73d8..3c4ce3c194c 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/transport.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/transport.go @@ -111,7 +111,6 @@ type Transport struct { // When an error is received from ErrorC, user should stop raft state // machine and thus stop the Transport. ErrorC chan error - V3demo bool streamRt http.RoundTripper // roundTripper used by streams pipelineRt http.RoundTripper // roundTripper used by pipelines @@ -166,10 +165,11 @@ func (t *Transport) Send(msgs []raftpb.Message) { to := types.ID(m.To) t.mu.RLock() - p, ok := t.peers[to] + p, pok := t.peers[to] + g, rok := t.remotes[to] t.mu.RUnlock() - if ok { + if pok { if m.Type == raftpb.MsgApp { t.ServerStats.SendAppendReq(m.Size()) } @@ -177,8 +177,7 @@ func (t *Transport) Send(msgs []raftpb.Message) { continue } - g, ok := t.remotes[to] - if ok { + if rok { g.send(m) continue } @@ -232,7 +231,7 @@ func (t *Transport) AddPeer(id types.ID, us []string) { plog.Panicf("newURLs %+v should never fail: %+v", us, err) } fs := t.LeaderStats.Follower(id.String()) - t.peers[id] = startPeer(t, urls, t.ID, id, t.ClusterID, t.Raft, fs, t.ErrorC, t.V3demo) + t.peers[id] = startPeer(t, urls, t.ID, id, t.ClusterID, t.Raft, fs, t.ErrorC) addPeerToProber(t.prober, id.String(), us) } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/util.go b/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/util.go index 0797daf01e7..93c87f8f493 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/util.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/rafthttp/util.go @@ -15,6 +15,7 @@ package rafthttp import ( + "crypto/tls" "encoding/binary" "fmt" "io" @@ -38,8 +39,8 @@ var ( // NewListener returns a listener for raft message transfer between peers. // It uses timeout listener to identify broken streams promptly. -func NewListener(u url.URL, tlsInfo transport.TLSInfo) (net.Listener, error) { - return transport.NewTimeoutListener(u.Host, u.Scheme, tlsInfo, ConnReadTimeout, ConnWriteTimeout) +func NewListener(u url.URL, tlscfg *tls.Config) (net.Listener, error) { + return transport.NewTimeoutListener(u.Host, u.Scheme, tlscfg, ConnReadTimeout, ConnWriteTimeout) } // NewRoundTripper returns a roundTripper used to send requests diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/snap/snappb/snap.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/snap/snappb/snap.pb.go index 5d1d21ab31d..f83fd411a28 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/snap/snappb/snap.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/snap/snappb/snap.pb.go @@ -17,9 +17,9 @@ import ( "fmt" proto "github.com/gogo/protobuf/proto" -) -import math "math" + math "math" +) import io "io" diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/snap/snapshotter.go b/Godeps/_workspace/src/github.com/coreos/etcd/snap/snapshotter.go index 4e06483a88e..ab56d32dbc9 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/snap/snapshotter.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/snap/snapshotter.go @@ -45,6 +45,11 @@ var ( ErrEmptySnapshot = errors.New("snap: empty snapshot") ErrCRCMismatch = errors.New("snap: crc mismatch") crcTable = crc32.MakeTable(crc32.Castagnoli) + + // A map of valid files that can be present in the snap folder. + validFiles = map[string]bool{ + "db": true, + } ) type Snapshotter struct { @@ -175,7 +180,11 @@ func checkSuffix(names []string) []string { if strings.HasSuffix(names[i], snapSuffix) { snaps = append(snaps, names[i]) } else { - plog.Warningf("skipped unexpected non snapshot file %v", names[i]) + // If we find a file which is not a snapshot then check if it's + // a vaild file. If not throw out a warning. + if _, ok := validFiles[names[i]]; !ok { + plog.Warningf("skipped unexpected non snapshot file %v", names[i]) + } } } return snaps diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/storage/backend/backend.go b/Godeps/_workspace/src/github.com/coreos/etcd/storage/backend/backend.go index 689f1a43ee5..05c22162b68 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/storage/backend/backend.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/storage/backend/backend.go @@ -41,6 +41,15 @@ var ( InitialMmapSize = int64(10 * 1024 * 1024 * 1024) ) +const ( + // DefaultQuotaBytes is the number of bytes the backend Size may + // consume before exceeding the space quota. + DefaultQuotaBytes = int64(2 * 1024 * 1024 * 1024) // 2GB + // MaxQuotaBytes is the maximum number of bytes suggested for a backend + // quota. A larger quota may lead to degraded performance. + MaxQuotaBytes = int64(8 * 1024 * 1024 * 1024) // 8GB +) + type Backend interface { BatchTx() BatchTx Snapshot() Snapshot @@ -286,6 +295,7 @@ func defragdb(odb, tmpdb *bolt.DB, limit int) error { return err } tmpb = tmptx.Bucket(next) + count = 0 } err = tmpb.Put(k, v) if err != nil { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/storage/backend/batch_tx.go b/Godeps/_workspace/src/github.com/coreos/etcd/storage/backend/batch_tx.go index 387137124b0..d59833cd19e 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/storage/backend/batch_tx.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/storage/backend/batch_tx.go @@ -31,6 +31,7 @@ type BatchTx interface { UnsafeSeqPut(bucketName []byte, key []byte, value []byte) UnsafeRange(bucketName []byte, key, endKey []byte, limit int64) (keys [][]byte, vals [][]byte) UnsafeDelete(bucketName []byte, key []byte) + UnsafeForEach(bucketName []byte, visitor func(k, v []byte) error) error Commit() CommitAndStop() } @@ -122,6 +123,11 @@ func (t *batchTx) UnsafeDelete(bucketName []byte, key []byte) { t.pending++ } +// UnsafeForEach must be called holding the lock on the tx. +func (t *batchTx) UnsafeForEach(bucketName []byte, visitor func(k, v []byte) error) error { + return t.tx.Bucket(bucketName).ForEach(visitor) +} + // Commit commits a previous tx and begins a new writable one. func (t *batchTx) Commit() { t.Lock() diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/storage/consistent_watchable_store.go b/Godeps/_workspace/src/github.com/coreos/etcd/storage/consistent_watchable_store.go deleted file mode 100644 index 773b0a0c3f3..00000000000 --- a/Godeps/_workspace/src/github.com/coreos/etcd/storage/consistent_watchable_store.go +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2015 CoreOS, 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. - -package storage - -import ( - "encoding/binary" - "log" - - "github.com/coreos/etcd/lease" - "github.com/coreos/etcd/storage/backend" - "github.com/coreos/etcd/storage/storagepb" -) - -var ( - consistentIndexKeyName = []byte("consistent_index") -) - -// ConsistentIndexGetter is an interface that wraps the Get method. -// Consistent index is the offset of an entry in a consistent replicated log. -type ConsistentIndexGetter interface { - // ConsistentIndex returns the consistent index of current executing entry. - ConsistentIndex() uint64 -} - -type consistentWatchableStore struct { - *watchableStore - // The field is used to get the consistent index of current - // executing entry. - // When the store finishes executing current entry, it will - // put the index got from ConsistentIndexGetter into the - // underlying backend. This helps to recover consistent index - // when restoring. - ig ConsistentIndexGetter - - skip bool // indicate whether or not to skip an operation -} - -func New(b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter) ConsistentWatchableKV { - return newConsistentWatchableStore(b, le, ig) -} - -// newConsistentWatchableStore creates a new consistentWatchableStore with the give -// backend. -func newConsistentWatchableStore(b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter) *consistentWatchableStore { - return &consistentWatchableStore{ - watchableStore: newWatchableStore(b, le), - ig: ig, - } -} - -func (s *consistentWatchableStore) Put(key, value []byte, lease lease.LeaseID) (rev int64) { - id := s.TxnBegin() - rev, err := s.TxnPut(id, key, value, lease) - if err != nil { - log.Panicf("unexpected TxnPut error (%v)", err) - } - if err := s.TxnEnd(id); err != nil { - log.Panicf("unexpected TxnEnd error (%v)", err) - } - return rev -} - -func (s *consistentWatchableStore) DeleteRange(key, end []byte) (n, rev int64) { - id := s.TxnBegin() - n, rev, err := s.TxnDeleteRange(id, key, end) - if err != nil { - log.Panicf("unexpected TxnDeleteRange error (%v)", err) - } - if err := s.TxnEnd(id); err != nil { - log.Panicf("unexpected TxnEnd error (%v)", err) - } - return n, rev -} - -func (s *consistentWatchableStore) TxnBegin() int64 { - id := s.watchableStore.TxnBegin() - - // If the consistent index of executing entry is not larger than store - // consistent index, skip all operations in this txn. - s.skip = s.ig.ConsistentIndex() <= s.consistentIndex() - - if !s.skip { - // TODO: avoid this unnecessary allocation - bs := make([]byte, 8) - binary.BigEndian.PutUint64(bs, s.ig.ConsistentIndex()) - // put the index into the underlying backend - // tx has been locked in TxnBegin, so there is no need to lock it again - s.watchableStore.store.tx.UnsafePut(metaBucketName, consistentIndexKeyName, bs) - } - - return id -} - -func (s *consistentWatchableStore) TxnRange(txnID int64, key, end []byte, limit, rangeRev int64) (kvs []storagepb.KeyValue, rev int64, err error) { - if s.skip { - return nil, 0, nil - } - return s.watchableStore.TxnRange(txnID, key, end, limit, rangeRev) -} - -func (s *consistentWatchableStore) TxnPut(txnID int64, key, value []byte, lease lease.LeaseID) (rev int64, err error) { - if s.skip { - return 0, nil - } - return s.watchableStore.TxnPut(txnID, key, value, lease) -} - -func (s *consistentWatchableStore) TxnDeleteRange(txnID int64, key, end []byte) (n, rev int64, err error) { - if s.skip { - return 0, 0, nil - } - return s.watchableStore.TxnDeleteRange(txnID, key, end) -} - -func (s *consistentWatchableStore) TxnEnd(txnID int64) error { - // reset skip var - s.skip = false - return s.watchableStore.TxnEnd(txnID) -} - -func (s *consistentWatchableStore) consistentIndex() uint64 { - // get the index - // tx has been locked in TxnBegin, so there is no need to lock it again - _, vs := s.watchableStore.store.tx.UnsafeRange(metaBucketName, consistentIndexKeyName, nil, 0) - if len(vs) == 0 { - return 0 - } - return binary.BigEndian.Uint64(vs[0]) -} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/storage/key_index.go b/Godeps/_workspace/src/github.com/coreos/etcd/storage/key_index.go index 55016946479..e8a344ec21e 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/storage/key_index.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/storage/key_index.go @@ -131,14 +131,7 @@ func (ki *keyIndex) get(atRev int64) (modified, created revision, ver int64, err return revision{}, revision{}, 0, ErrRevisionNotFound } - f := func(rev revision) bool { - if rev.main <= atRev { - return false - } - return true - } - - n := g.walk(f) + n := g.walk(func(rev revision) bool { return rev.main > atRev }) if n != -1 { return g.revs[n], g.created, g.ver - int64(len(g.revs)-n-1), nil } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/storage/kv.go b/Godeps/_workspace/src/github.com/coreos/etcd/storage/kv.go index cd63a354ce4..33d26e29e52 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/storage/kv.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/storage/kv.go @@ -67,7 +67,7 @@ type KV interface { TxnPut(txnID int64, key, value []byte, lease lease.LeaseID) (rev int64, err error) TxnDeleteRange(txnID int64, key, end []byte) (n, rev int64, err error) - Compact(rev int64) error + Compact(rev int64) (<-chan struct{}, error) // Hash retrieves the hash of KV state. // This method is designed for consistency checking purpose. @@ -101,4 +101,6 @@ type Watchable interface { // this entry are skipped and return empty response. type ConsistentWatchableKV interface { WatchableKV + // ConsistentIndex returns the current consistent index of the KV. + ConsistentIndex() uint64 } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/storage/kvstore.go b/Godeps/_workspace/src/github.com/coreos/etcd/storage/kvstore.go index a86aa8e261b..e9fceb7da56 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/storage/kvstore.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/storage/kvstore.go @@ -15,6 +15,7 @@ package storage import ( + "encoding/binary" "errors" "log" "math" @@ -40,6 +41,7 @@ var ( markBytePosition = markedRevBytesLen - 1 markTombstone byte = 't' + consistentIndexKeyName = []byte("consistent_index") scheduledCompactKeyName = []byte("scheduledCompactRev") finishedCompactKeyName = []byte("finishedCompactRev") @@ -49,9 +51,18 @@ var ( ErrCanceled = errors.New("storage: watcher is canceled") ) +// ConsistentIndexGetter is an interface that wraps the Get method. +// Consistent index is the offset of an entry in a consistent replicated log. +type ConsistentIndexGetter interface { + // ConsistentIndex returns the consistent index of current executing entry. + ConsistentIndex() uint64 +} + type store struct { mu sync.Mutex // guards the following + ig ConsistentIndexGetter + b backend.Backend kvindex index @@ -72,9 +83,10 @@ type store struct { // NewStore returns a new store. It is useful to create a store inside // storage pkg. It should only be used for testing externally. -func NewStore(b backend.Backend, le lease.Lessor) *store { +func NewStore(b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter) *store { s := &store{ b: b, + ig: ig, kvindex: newTreeIndex(), le: le, @@ -155,6 +167,7 @@ func (s *store) TxnBegin() int64 { s.currentRev.sub = 0 s.tx = s.b.BatchTx() s.tx.Lock() + s.saveIndex() s.txnID = rand.Int63() return s.txnID @@ -218,14 +231,32 @@ func (s *store) TxnDeleteRange(txnID int64, key, end []byte) (n, rev int64, err return n, rev, nil } -func (s *store) Compact(rev int64) error { +func (s *store) compactBarrier(ctx context.Context, ch chan struct{}) { + if ctx == nil || ctx.Err() != nil { + s.mu.Lock() + select { + case <-s.stopc: + default: + f := func(ctx context.Context) { s.compactBarrier(ctx, ch) } + s.fifoSched.Schedule(f) + } + s.mu.Unlock() + return + } + close(ch) +} + +func (s *store) Compact(rev int64) (<-chan struct{}, error) { s.mu.Lock() defer s.mu.Unlock() if rev <= s.compactMainRev { - return ErrCompacted + ch := make(chan struct{}) + f := func(ctx context.Context) { s.compactBarrier(ctx, ch) } + s.fifoSched.Schedule(f) + return ch, ErrCompacted } if rev > s.currentRev.main { - return ErrFutureRev + return nil, ErrFutureRev } start := time.Now() @@ -243,20 +274,23 @@ func (s *store) Compact(rev int64) error { s.b.ForceCommit() keep := s.kvindex.Compact(rev) - + ch := make(chan struct{}) var j = func(ctx context.Context) { - select { - case <-ctx.Done(): + if ctx.Err() != nil { + s.compactBarrier(ctx, ch) return - default: } - s.scheduleCompaction(rev, keep) + if !s.scheduleCompaction(rev, keep) { + s.compactBarrier(nil, ch) + return + } + close(ch) } s.fifoSched.Schedule(j) indexCompactionPauseDurations.Observe(float64(time.Now().Sub(start) / time.Millisecond)) - return nil + return ch, nil } func (s *store) Hash() (uint32, error) { @@ -341,16 +375,21 @@ func (s *store) restore() error { } _, scheduledCompactBytes := tx.UnsafeRange(metaBucketName, scheduledCompactKeyName, nil, 0) + scheduledCompact := int64(0) if len(scheduledCompactBytes) != 0 { - scheduledCompact := bytesToRev(scheduledCompactBytes[0]).main - if scheduledCompact > s.compactMainRev { - log.Printf("storage: resume scheduled compaction at %d", scheduledCompact) - go s.Compact(scheduledCompact) + scheduledCompact = bytesToRev(scheduledCompactBytes[0]).main + if scheduledCompact <= s.compactMainRev { + scheduledCompact = 0 } } tx.Unlock() + if scheduledCompact != 0 { + s.Compact(scheduledCompact) + log.Printf("storage: resume scheduled compaction at %d", scheduledCompact) + } + return nil } @@ -545,6 +584,31 @@ func (s *store) getChanges() []storagepb.KeyValue { return changes } +func (s *store) saveIndex() { + if s.ig == nil { + return + } + tx := s.tx + // TODO: avoid this unnecessary allocation + bs := make([]byte, 8) + binary.BigEndian.PutUint64(bs, s.ig.ConsistentIndex()) + // put the index into the underlying backend + // tx has been locked in TxnBegin, so there is no need to lock it again + tx.UnsafePut(metaBucketName, consistentIndexKeyName, bs) +} + +func (s *store) ConsistentIndex() uint64 { + // TODO: cache index in a uint64 field? + tx := s.b.BatchTx() + tx.Lock() + defer tx.Unlock() + _, vs := tx.UnsafeRange(metaBucketName, consistentIndexKeyName, nil, 0) + if len(vs) == 0 { + return 0 + } + return binary.BigEndian.Uint64(vs[0]) +} + // appendMarkTombstone appends tombstone mark to normal revision bytes. func appendMarkTombstone(b []byte) []byte { if len(b) != revBytesLen { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/storage/kvstore_compaction.go b/Godeps/_workspace/src/github.com/coreos/etcd/storage/kvstore_compaction.go index 840430a8b83..a7b9cc8ad5a 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/storage/kvstore_compaction.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/storage/kvstore_compaction.go @@ -19,7 +19,7 @@ import ( "time" ) -func (s *store) scheduleCompaction(compactMainRev int64, keep map[revision]struct{}) { +func (s *store) scheduleCompaction(compactMainRev int64, keep map[revision]struct{}) bool { totalStart := time.Now() defer dbCompactionTotalDurations.Observe(float64(time.Now().Sub(totalStart) / time.Millisecond)) @@ -48,7 +48,7 @@ func (s *store) scheduleCompaction(compactMainRev int64, keep map[revision]struc revToBytes(revision{main: compactMainRev}, rbytes) tx.UnsafePut(metaBucketName, finishedCompactKeyName, rbytes) tx.Unlock() - return + return true } // update last @@ -59,7 +59,7 @@ func (s *store) scheduleCompaction(compactMainRev int64, keep map[revision]struc select { case <-time.After(100 * time.Millisecond): case <-s.stopc: - return + return false } } } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/storage/storagepb/kv.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/storage/storagepb/kv.pb.go index 02588904c9e..2987b9be6cb 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/storage/storagepb/kv.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/storage/storagepb/kv.pb.go @@ -18,9 +18,9 @@ import ( "fmt" proto "github.com/gogo/protobuf/proto" -) -import math "math" + math "math" +) import io "io" diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/storage/watchable_store.go b/Godeps/_workspace/src/github.com/coreos/etcd/storage/watchable_store.go index 375e11e287b..818fcafcbb4 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/storage/watchable_store.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/storage/watchable_store.go @@ -58,9 +58,13 @@ type watchableStore struct { // cancel operations. type cancelFunc func() -func newWatchableStore(b backend.Backend, le lease.Lessor) *watchableStore { +func New(b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter) ConsistentWatchableKV { + return newWatchableStore(b, le, ig) +} + +func newWatchableStore(b backend.Backend, le lease.Lessor, ig ConsistentIndexGetter) *watchableStore { s := &watchableStore{ - store: NewStore(b, le), + store: NewStore(b, le, ig), unsynced: newWatcherGroup(), synced: newWatcherGroup(), stopc: make(chan struct{}), diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/storage/watcher_group.go b/Godeps/_workspace/src/github.com/coreos/etcd/storage/watcher_group.go index 345ac61dd49..3f8f8cf3b1d 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/storage/watcher_group.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/storage/watcher_group.go @@ -143,13 +143,6 @@ func (w watcherSetByKey) delete(wa *watcher) bool { return false } -type interval struct { - begin string - end string -} - -type watcherSetByInterval map[interval]watcherSet - // watcherGroup is a collection of watchers organized by their ranges type watcherGroup struct { // keyWatchers has the watchers that watch on a single key diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/version/version.go b/Godeps/_workspace/src/github.com/coreos/etcd/version/version.go index 95c9a28570c..7b9daf0ba20 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/version/version.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/version/version.go @@ -29,7 +29,7 @@ import ( var ( // MinClusterVersion is the min cluster version this etcd binary is compatible with. MinClusterVersion = "2.2.0" - Version = "2.3.0" + Version = "2.3.0+git" // Git SHA Value will be set during build GitSHA = "Not provided (use ./build instead of go build)" diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/wal/decoder.go b/Godeps/_workspace/src/github.com/coreos/etcd/wal/decoder.go index f75c919fba6..0678ab74f69 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/wal/decoder.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/wal/decoder.go @@ -28,32 +28,53 @@ import ( ) type decoder struct { - mu sync.Mutex - br *bufio.Reader + mu sync.Mutex + brs []*bufio.Reader - c io.Closer - crc hash.Hash32 + // lastValidOff file offset following the last valid decoded record + lastValidOff int64 + crc hash.Hash32 } -func newDecoder(rc io.ReadCloser) *decoder { +func newDecoder(r ...io.Reader) *decoder { + readers := make([]*bufio.Reader, len(r)) + for i := range r { + readers[i] = bufio.NewReader(r[i]) + } return &decoder{ - br: bufio.NewReader(rc), - c: rc, + brs: readers, crc: crc.New(0, crcTable), } } func (d *decoder) decode(rec *walpb.Record) error { + rec.Reset() d.mu.Lock() defer d.mu.Unlock() + return d.decodeRecord(rec) +} - rec.Reset() - l, err := readInt64(d.br) +func (d *decoder) decodeRecord(rec *walpb.Record) error { + if len(d.brs) == 0 { + return io.EOF + } + + l, err := readInt64(d.brs[0]) + if err == io.EOF || (err == nil && l == 0) { + // hit end of file or preallocated space + d.brs = d.brs[1:] + if len(d.brs) == 0 { + return io.EOF + } + d.lastValidOff = 0 + return d.decodeRecord(rec) + } if err != nil { return err } + data := make([]byte, l) - if _, err = io.ReadFull(d.br, data); err != nil { + if _, err = io.ReadFull(d.brs[0], data); err != nil { // ReadFull returns io.EOF only if no bytes were read // the decoder should treat this as an ErrUnexpectedEOF instead. if err == io.EOF { @@ -64,12 +85,17 @@ func (d *decoder) decode(rec *walpb.Record) error { if err := rec.Unmarshal(data); err != nil { return err } + // skip crc checking if the record type is crcType - if rec.Type == crcType { - return nil + if rec.Type != crcType { + d.crc.Write(rec.Data) + if err := rec.Validate(d.crc.Sum32()); err != nil { + return err + } } - d.crc.Write(rec.Data) - return rec.Validate(d.crc.Sum32()) + // record decoded as valid; point last valid offset to end of record + d.lastValidOff += l + 8 + return nil } func (d *decoder) updateCRC(prevCrc uint32) { @@ -80,9 +106,7 @@ func (d *decoder) lastCRC() uint32 { return d.crc.Sum32() } -func (d *decoder) close() error { - return d.c.Close() -} +func (d *decoder) lastOffset() int64 { return d.lastValidOff } func mustUnmarshalEntry(d []byte) raftpb.Entry { var e raftpb.Entry diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/wal/file_pipeline.go b/Godeps/_workspace/src/github.com/coreos/etcd/wal/file_pipeline.go new file mode 100644 index 00000000000..6db9f66d74c --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/wal/file_pipeline.go @@ -0,0 +1,95 @@ +// Copyright 2016 CoreOS, 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. + +package wal + +import ( + "fmt" + "os" + "path" + + "github.com/coreos/etcd/pkg/fileutil" +) + +// filePipeline pipelines allocating disk space +type filePipeline struct { + // dir to put files + dir string + // size of files to make, in bytes + size int64 + // count number of files generated + count int + + filec chan *fileutil.LockedFile + errc chan error + donec chan struct{} +} + +func newFilePipeline(dir string, fileSize int64) *filePipeline { + fp := &filePipeline{ + dir: dir, + size: fileSize, + filec: make(chan *fileutil.LockedFile), + errc: make(chan error, 1), + donec: make(chan struct{}), + } + go fp.run() + return fp +} + +// Open returns a fresh file for writing +func (fp *filePipeline) Open() (f *fileutil.LockedFile, err error) { + select { + case f = <-fp.filec: + case err = <-fp.errc: + } + return +} + +func (fp *filePipeline) Close() error { + close(fp.donec) + return <-fp.errc +} + +func (fp *filePipeline) alloc() (f *fileutil.LockedFile, err error) { + fpath := path.Join(fp.dir, fmt.Sprintf("%d.tmp", fp.count)) + if f, err = fileutil.LockFile(fpath, os.O_CREATE|os.O_WRONLY, 0600); err != nil { + return nil, err + } + if err = fileutil.Preallocate(f.File, fp.size, true); err != nil { + plog.Errorf("failed to allocate space when creating new wal file (%v)", err) + f.Close() + return nil, err + } + fp.count++ + return f, nil +} + +func (fp *filePipeline) run() { + defer close(fp.errc) + for { + f, err := fp.alloc() + if err != nil { + fp.errc <- err + return + } + select { + case fp.filec <- f: + case <-fp.donec: + os.Remove(f.Name()) + f.Close() + return + } + } +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/wal/multi_readcloser.go b/Godeps/_workspace/src/github.com/coreos/etcd/wal/multi_readcloser.go deleted file mode 100644 index 513c6d17d94..00000000000 --- a/Godeps/_workspace/src/github.com/coreos/etcd/wal/multi_readcloser.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015 CoreOS, 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. - -package wal - -import "io" - -type multiReadCloser struct { - closers []io.Closer - reader io.Reader -} - -func (mc *multiReadCloser) Close() error { - var err error - for i := range mc.closers { - err = mc.closers[i].Close() - } - return err -} - -func (mc *multiReadCloser) Read(p []byte) (int, error) { - return mc.reader.Read(p) -} - -func MultiReadCloser(readClosers ...io.ReadCloser) io.ReadCloser { - cs := make([]io.Closer, len(readClosers)) - rs := make([]io.Reader, len(readClosers)) - for i := range readClosers { - cs[i] = readClosers[i] - rs[i] = readClosers[i] - } - r := io.MultiReader(rs...) - return &multiReadCloser{cs, r} -} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/wal/repair.go b/Godeps/_workspace/src/github.com/coreos/etcd/wal/repair.go index bcc22ef0817..eceebff3cea 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/wal/repair.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/wal/repair.go @@ -36,7 +36,6 @@ func Repair(dirpath string) bool { rec := &walpb.Record{} decoder := newDecoder(f) - defer decoder.close() for { err := decoder.decode(rec) switch err { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/wal/wal.go b/Godeps/_workspace/src/github.com/coreos/etcd/wal/wal.go index f9a58ca38b8..3e5db72323e 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/wal/wal.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/wal/wal.go @@ -70,16 +70,16 @@ type WAL struct { metadata []byte // metadata recorded at the head of each WAL state raftpb.HardState // hardstate recorded at the head of WAL - start walpb.Snapshot // snapshot to start reading - decoder *decoder // decoder to decode records + start walpb.Snapshot // snapshot to start reading + decoder *decoder // decoder to decode records + readClose func() error // closer for decode reader mu sync.Mutex - f *os.File // underlay file opened for appending, sync - seq uint64 // sequence of the wal file currently used for writes enti uint64 // index of the last entry saved to the wal encoder *encoder // encoder to encode records - locks []fileutil.Lock // the file locks the WAL is holding (the name is increasing) + locks []*fileutil.LockedFile // the locked files the WAL holds (the name is increasing) + fp *filePipeline } // Create creates a WAL ready for appending records. The given metadata is @@ -94,26 +94,24 @@ func Create(dirpath string, metadata []byte) (*WAL, error) { } p := path.Join(dirpath, walName(0, 0)) - f, err := os.OpenFile(p, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0600) + f, err := fileutil.LockFile(p, os.O_WRONLY|os.O_CREATE, 0600) if err != nil { return nil, err } - l, err := fileutil.NewLock(f.Name()) - if err != nil { + if _, err := f.Seek(0, os.SEEK_END); err != nil { return nil, err } - if err = l.Lock(); err != nil { + if err := fileutil.Preallocate(f.File, segmentSizeBytes, true); err != nil { return nil, err } w := &WAL{ dir: dirpath, metadata: metadata, - seq: 0, - f: f, encoder: newEncoder(f, 0), + fp: newFilePipeline(dirpath, segmentSizeBytes), } - w.locks = append(w.locks, l) + w.locks = append(w.locks, f) if err := w.saveCrc(0); err != nil { return nil, err } @@ -157,60 +155,59 @@ func openAtIndex(dirpath string, snap walpb.Snapshot, write bool) (*WAL, error) return nil, ErrFileNotFound } - // open the wal files for reading + // open the wal files rcs := make([]io.ReadCloser, 0) - ls := make([]fileutil.Lock, 0) + rs := make([]io.Reader, 0) + ls := make([]*fileutil.LockedFile, 0) for _, name := range names[nameIndex:] { - f, err := os.Open(path.Join(dirpath, name)) - if err != nil { - return nil, err - } - l, err := fileutil.NewLock(f.Name()) - if err != nil { - return nil, err - } - err = l.TryLock() - if err != nil { - if write { + p := path.Join(dirpath, name) + if write { + l, err := fileutil.TryLockFile(p, os.O_RDWR, 0600) + if err != nil { + closeAll(rcs...) return nil, err } + ls = append(ls, l) + rcs = append(rcs, l) + } else { + rf, err := os.OpenFile(p, os.O_RDONLY, 0600) + if err != nil { + closeAll(rcs...) + return nil, err + } + ls = append(ls, nil) + rcs = append(rcs, rf) } - rcs = append(rcs, f) - ls = append(ls, l) + rs = append(rs, rcs[len(rcs)-1]) } - rc := MultiReadCloser(rcs...) + + closer := func() error { return closeAll(rcs...) } // create a WAL ready for reading w := &WAL{ - dir: dirpath, - start: snap, - decoder: newDecoder(rc), - locks: ls, + dir: dirpath, + start: snap, + decoder: newDecoder(rs...), + readClose: closer, + locks: ls, } if write { - // open the last wal file for appending - seq, _, err := parseWalName(names[len(names)-1]) - if err != nil { - rc.Close() - return nil, err - } - last := path.Join(dirpath, names[len(names)-1]) + // write reuses the file descriptors from read; don't close so + // WAL can append without dropping the file lock + w.readClose = nil - f, err := os.OpenFile(last, os.O_WRONLY|os.O_APPEND, 0) - if err != nil { - rc.Close() + if _, _, err := parseWalName(path.Base(w.tail().Name())); err != nil { + closer() return nil, err } - err = fileutil.Preallocate(f, segmentSizeBytes) - if err != nil { - rc.Close() + // don't resize file for preallocation in case tail is corrupted + if err := fileutil.Preallocate(w.tail().File, segmentSizeBytes, false); err != nil { + closer() plog.Errorf("failed to allocate space when creating new wal file (%v)", err) return nil, err } - - w.f = f - w.seq = seq + w.fp = newFilePipeline(w.dir, segmentSizeBytes) } return w, nil @@ -275,7 +272,7 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb. } } - switch w.f { + switch w.tail() { case nil: // We do not have to read out all entries in read mode. // The last record maybe a partial written one, so @@ -298,17 +295,21 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb. } // close decoder, disable reading - w.decoder.close() + if w.readClose != nil { + w.readClose() + w.readClose = nil + } w.start = walpb.Snapshot{} w.metadata = metadata - if w.f != nil { + if w.tail() != nil { // create encoder (chain crc with the decoder), enable appending - w.encoder = newEncoder(w.f, w.decoder.lastCRC()) - w.decoder = nil + _, err = w.tail().Seek(w.decoder.lastOffset(), os.SEEK_SET) + w.encoder = newEncoder(w.tail(), w.decoder.lastCRC()) lastIndexSaved.Set(float64(w.enti)) } + w.decoder = nil return metadata, state, ents, err } @@ -317,27 +318,30 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb. // cut first creates a temp wal file and writes necessary headers into it. // Then cut atomically rename temp wal file to a wal file. func (w *WAL) cut() error { - // close old wal file + // close old wal file; truncate to avoid wasting space if an early cut + off, serr := w.tail().Seek(0, os.SEEK_CUR) + if serr != nil { + return serr + } + if err := w.tail().Truncate(off); err != nil { + return err + } if err := w.sync(); err != nil { return err } - if err := w.f.Close(); err != nil { - return err - } - fpath := path.Join(w.dir, walName(w.seq+1, w.enti+1)) - ftpath := fpath + ".tmp" + fpath := path.Join(w.dir, walName(w.seq()+1, w.enti+1)) // create a temp wal file with name sequence + 1, or truncate the existing one - ft, err := os.OpenFile(ftpath, os.O_WRONLY|os.O_APPEND|os.O_CREATE|os.O_TRUNC, 0600) + newTail, err := w.fp.Open() if err != nil { return err } // update writer and save the previous crc - w.f = ft + w.locks = append(w.locks, newTail) prevCrc := w.encoder.crc.Sum32() - w.encoder = newEncoder(w.f, prevCrc) + w.encoder = newEncoder(w.tail(), prevCrc) if err = w.saveCrc(prevCrc); err != nil { return err } @@ -347,46 +351,32 @@ func (w *WAL) cut() error { if err = w.saveState(&w.state); err != nil { return err } - // close temp wal file + // atomically move temp wal file to wal file if err = w.sync(); err != nil { return err } - if err = w.f.Close(); err != nil { - return err - } - // atomically move temp wal file to wal file - if err = os.Rename(ftpath, fpath); err != nil { - return err - } - - // open the wal file and update writer again - f, err := os.OpenFile(fpath, os.O_WRONLY|os.O_APPEND, 0600) + off, err = w.tail().Seek(0, os.SEEK_CUR) if err != nil { return err } - if err = fileutil.Preallocate(f, segmentSizeBytes); err != nil { - plog.Errorf("failed to allocate space when creating new wal file (%v)", err) + + if err = os.Rename(newTail.Name(), fpath); err != nil { + return err + } + newTail.Close() + + if newTail, err = fileutil.LockFile(fpath, os.O_WRONLY, 0600); err != nil { + return err + } + if _, err = newTail.Seek(off, os.SEEK_SET); err != nil { return err } - w.f = f + w.locks[len(w.locks)-1] = newTail + prevCrc = w.encoder.crc.Sum32() - w.encoder = newEncoder(w.f, prevCrc) - - // lock the new wal file - l, err := fileutil.NewLock(f.Name()) - if err != nil { - return err - } - - if err := l.Lock(); err != nil { - return err - } - w.locks = append(w.locks, l) - - // increase the wal seq - w.seq++ + w.encoder = newEncoder(w.tail(), prevCrc) plog.Infof("segmented wal file %v is created", fpath) return nil @@ -399,7 +389,7 @@ func (w *WAL) sync() error { } } start := time.Now() - err := fileutil.Fdatasync(w.f) + err := fileutil.Fdatasync(w.tail().File) syncDurations.Observe(float64(time.Since(start)) / float64(time.Second)) return err } @@ -438,8 +428,10 @@ func (w *WAL) ReleaseLockTo(index uint64) error { } for i := 0; i < smaller; i++ { - w.locks[i].Unlock() - w.locks[i].Destroy() + if w.locks[i] == nil { + continue + } + w.locks[i].Close() } w.locks = w.locks[smaller:] @@ -450,22 +442,22 @@ func (w *WAL) Close() error { w.mu.Lock() defer w.mu.Unlock() - if w.f != nil { + if w.fp != nil { + w.fp.Close() + w.fp = nil + } + + if w.tail() != nil { if err := w.sync(); err != nil { return err } - if err := w.f.Close(); err != nil { - return err - } } for _, l := range w.locks { - err := l.Unlock() - if err != nil { - plog.Errorf("failed to unlock during closing wal: %s", err) + if l == nil { + continue } - err = l.Destroy() - if err != nil { - plog.Errorf("failed to destroy lock during closing wal: %s", err) + if err := l.Close(); err != nil { + plog.Errorf("failed to unlock during closing wal: %s", err) } } return nil @@ -514,16 +506,17 @@ func (w *WAL) Save(st raftpb.HardState, ents []raftpb.Entry) error { return err } - fstat, err := w.f.Stat() + curOff, err := w.tail().Seek(0, os.SEEK_CUR) if err != nil { return err } - if fstat.Size() < segmentSizeBytes { + if curOff < segmentSizeBytes { if mustSync { return w.sync() } return nil } + // TODO: add a test for this code path when refactoring the tests return w.cut() } @@ -549,6 +542,25 @@ func (w *WAL) saveCrc(prevCrc uint32) error { return w.encoder.encode(&walpb.Record{Type: crcType, Crc: prevCrc}) } +func (w *WAL) tail() *fileutil.LockedFile { + if len(w.locks) > 0 { + return w.locks[len(w.locks)-1] + } + return nil +} + +func (w *WAL) seq() uint64 { + t := w.tail() + if t == nil { + return 0 + } + seq, _, err := parseWalName(path.Base(t.Name())) + if err != nil { + plog.Fatalf("bad wal name %s (%v)", t.Name(), err) + } + return seq +} + func mustSync(st, prevst raftpb.HardState, entsnum int) bool { // Persistent state on all servers: // (Updated on stable storage before responding to RPCs) @@ -560,3 +572,12 @@ func mustSync(st, prevst raftpb.HardState, entsnum int) bool { } return false } + +func closeAll(rcs ...io.ReadCloser) error { + for _, f := range rcs { + if err := f.Close(); err != nil { + return err + } + } + return nil +} diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/wal/walpb/record.pb.go b/Godeps/_workspace/src/github.com/coreos/etcd/wal/walpb/record.pb.go index 638bdc3b69f..7ae042a51c7 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/wal/walpb/record.pb.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/wal/walpb/record.pb.go @@ -18,9 +18,9 @@ import ( "fmt" proto "github.com/gogo/protobuf/proto" -) -import math "math" + math "math" +) import io "io" diff --git a/Godeps/_workspace/src/github.com/coreos/go-systemd/journal/journal.go b/Godeps/_workspace/src/github.com/coreos/go-systemd/journal/journal.go deleted file mode 100644 index 6c3f5b94df3..00000000000 --- a/Godeps/_workspace/src/github.com/coreos/go-systemd/journal/journal.go +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2015 CoreOS, 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. - -// Package journal provides write bindings to the local systemd journal. -// It is implemented in pure Go and connects to the journal directly over its -// unix socket. -// -// To read from the journal, see the "sdjournal" package, which wraps the -// sd-journal a C API. -// -// http://www.freedesktop.org/software/systemd/man/systemd-journald.service.html -package journal - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "io" - "io/ioutil" - "net" - "os" - "strconv" - "strings" - "syscall" -) - -// Priority of a journal message -type Priority int - -const ( - PriEmerg Priority = iota - PriAlert - PriCrit - PriErr - PriWarning - PriNotice - PriInfo - PriDebug -) - -var conn net.Conn - -func init() { - var err error - conn, err = net.Dial("unixgram", "/run/systemd/journal/socket") - if err != nil { - conn = nil - } -} - -// Enabled returns true if the local systemd journal is available for logging -func Enabled() bool { - return conn != nil -} - -// Send a message to the local systemd journal. vars is a map of journald -// fields to values. Fields must be composed of uppercase letters, numbers, -// and underscores, but must not start with an underscore. Within these -// restrictions, any arbitrary field name may be used. Some names have special -// significance: see the journalctl documentation -// (http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html) -// for more details. vars may be nil. -func Send(message string, priority Priority, vars map[string]string) error { - if conn == nil { - return journalError("could not connect to journald socket") - } - - data := new(bytes.Buffer) - appendVariable(data, "PRIORITY", strconv.Itoa(int(priority))) - appendVariable(data, "MESSAGE", message) - for k, v := range vars { - appendVariable(data, k, v) - } - - _, err := io.Copy(conn, data) - if err != nil && isSocketSpaceError(err) { - file, err := tempFd() - if err != nil { - return journalError(err.Error()) - } - _, err = io.Copy(file, data) - if err != nil { - return journalError(err.Error()) - } - - rights := syscall.UnixRights(int(file.Fd())) - - /* this connection should always be a UnixConn, but better safe than sorry */ - unixConn, ok := conn.(*net.UnixConn) - if !ok { - return journalError("can't send file through non-Unix connection") - } - unixConn.WriteMsgUnix([]byte{}, rights, nil) - } else if err != nil { - return journalError(err.Error()) - } - return nil -} - -// Print prints a message to the local systemd journal using Send(). -func Print(priority Priority, format string, a ...interface{}) error { - return Send(fmt.Sprintf(format, a...), priority, nil) -} - -func appendVariable(w io.Writer, name, value string) { - if !validVarName(name) { - journalError("variable name contains invalid character, ignoring") - } - if strings.ContainsRune(value, '\n') { - /* When the value contains a newline, we write: - * - the variable name, followed by a newline - * - the size (in 64bit little endian format) - * - the data, followed by a newline - */ - fmt.Fprintln(w, name) - binary.Write(w, binary.LittleEndian, uint64(len(value))) - fmt.Fprintln(w, value) - } else { - /* just write the variable and value all on one line */ - fmt.Fprintf(w, "%s=%s\n", name, value) - } -} - -func validVarName(name string) bool { - /* The variable name must be in uppercase and consist only of characters, - * numbers and underscores, and may not begin with an underscore. (from the docs) - */ - - valid := name[0] != '_' - for _, c := range name { - valid = valid && ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_' - } - return valid -} - -func isSocketSpaceError(err error) bool { - opErr, ok := err.(*net.OpError) - if !ok { - return false - } - - sysErr, ok := opErr.Err.(syscall.Errno) - if !ok { - return false - } - - return sysErr == syscall.EMSGSIZE || sysErr == syscall.ENOBUFS -} - -func tempFd() (*os.File, error) { - file, err := ioutil.TempFile("/dev/shm/", "journal.XXXXX") - if err != nil { - return nil, err - } - syscall.Unlink(file.Name()) - if err != nil { - return nil, err - } - return file, nil -} - -func journalError(s string) error { - s = "journal error: " + s - fmt.Fprintln(os.Stderr, s) - return errors.New(s) -} diff --git a/Godeps/_workspace_aux/src/github.com/beorn7/perks/LICENSE b/Godeps/_workspace_aux/src/github.com/beorn7/perks/LICENSE deleted file mode 100644 index 339177be663..00000000000 --- a/Godeps/_workspace_aux/src/github.com/beorn7/perks/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (C) 2013 Blake Mizerany - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Godeps/_workspace_aux/src/github.com/daviddengcn/go-colortext/LICENSE b/Godeps/_workspace_aux/src/github.com/daviddengcn/go-colortext/LICENSE deleted file mode 100644 index 974ec4202b7..00000000000 --- a/Godeps/_workspace_aux/src/github.com/daviddengcn/go-colortext/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2015, David Deng -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -* Neither the name of go-colortext nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace_aux/src/github.com/gogo/protobuf/README b/Godeps/_workspace_aux/src/github.com/gogo/protobuf/README deleted file mode 100644 index b00bb9303eb..00000000000 --- a/Godeps/_workspace_aux/src/github.com/gogo/protobuf/README +++ /dev/null @@ -1,208 +0,0 @@ -GoGoProtobuf http://github.com/gogo/protobuf extends -GoProtobuf http://github.com/golang/protobuf - -# Go support for Protocol Buffers - -Google's data interchange format. -Copyright 2010 The Go Authors. -https://github.com/golang/protobuf - -This package and the code it generates requires at least Go 1.4. - -This software implements Go bindings for protocol buffers. For -information about protocol buffers themselves, see - https://developers.google.com/protocol-buffers/ - -## Installation ## - -To use this software, you must: -- Install the standard C++ implementation of protocol buffers from - https://developers.google.com/protocol-buffers/ -- Of course, install the Go compiler and tools from - https://golang.org/ - See - https://golang.org/doc/install - for details or, if you are using gccgo, follow the instructions at - https://golang.org/doc/install/gccgo -- Grab the code from the repository and install the proto package. - The simplest way is to run `go get -u github.com/golang/protobuf/{proto,protoc-gen-go}`. - The compiler plugin, protoc-gen-go, will be installed in $GOBIN, - defaulting to $GOPATH/bin. It must be in your $PATH for the protocol - compiler, protoc, to find it. - -This software has two parts: a 'protocol compiler plugin' that -generates Go source files that, once compiled, can access and manage -protocol buffers; and a library that implements run-time support for -encoding (marshaling), decoding (unmarshaling), and accessing protocol -buffers. - -There is support for gRPC in Go using protocol buffers. -See the note at the bottom of this file for details. - -There are no insertion points in the plugin. - -GoGoProtobuf provides extensions for protocol buffers and GoProtobuf -see http://github.com/gogo/protobuf/gogoproto/doc.go - -## Using protocol buffers with Go ## - -Once the software is installed, there are two steps to using it. -First you must compile the protocol buffer definitions and then import -them, with the support library, into your program. - -To compile the protocol buffer definition, run protoc with the --gogo_out -parameter set to the directory you want to output the Go code to. - - protoc --gogo_out=. *.proto - -The generated files will be suffixed .pb.go. See the Test code below -for an example using such a file. - -The package comment for the proto library contains text describing -the interface provided in Go for protocol buffers. Here is an edited -version. - -If you are using any gogo.proto extensions you will need to specify the -proto_path to include the descriptor.proto and gogo.proto. -gogo.proto is located in github.com/gogo/protobuf/gogoproto -This should be fine, since your import is the same. -descriptor.proto is located in either github.com/gogo/protobuf/protobuf -or code.google.com/p/protobuf/trunk/src/ -Its import is google/protobuf/descriptor.proto so it might need some help. - - protoc --gogo_out=. -I=.:github.com/gogo/protobuf/protobuf *.proto - -========== - -The proto package converts data structures to and from the -wire format of protocol buffers. It works in concert with the -Go source code generated for .proto files by the protocol compiler. - -A summary of the properties of the protocol buffer interface -for a protocol buffer variable v: - - - Names are turned from camel_case to CamelCase for export. - - There are no methods on v to set fields; just treat - them as structure fields. - - There are getters that return a field's value if set, - and return the field's default value if unset. - The getters work even if the receiver is a nil message. - - The zero value for a struct is its correct initialization state. - All desired fields must be set before marshaling. - - A Reset() method will restore a protobuf struct to its zero state. - - Non-repeated fields are pointers to the values; nil means unset. - That is, optional or required field int32 f becomes F *int32. - - Repeated fields are slices. - - Helper functions are available to aid the setting of fields. - Helpers for getting values are superseded by the - GetFoo methods and their use is deprecated. - msg.Foo = proto.String("hello") // set field - - Constants are defined to hold the default values of all fields that - have them. They have the form Default_StructName_FieldName. - Because the getter methods handle defaulted values, - direct use of these constants should be rare. - - Enums are given type names and maps from names to values. - Enum values are prefixed with the enum's type name. Enum types have - a String method, and a Enum method to assist in message construction. - - Nested groups and enums have type names prefixed with the name of - the surrounding message type. - - Extensions are given descriptor names that start with E_, - followed by an underscore-delimited list of the nested messages - that contain it (if any) followed by the CamelCased name of the - extension field itself. HasExtension, ClearExtension, GetExtension - and SetExtension are functions for manipulating extensions. - - Oneof field sets are given a single field in their message, - with distinguished wrapper types for each possible field value. - - Marshal and Unmarshal are functions to encode and decode the wire format. - -When the .proto file specifies `syntax="proto3"`, there are some differences: - - - Non-repeated fields of non-message type are values instead of pointers. - - Getters are only generated for message and oneof fields. - - Enum types do not get an Enum method. - -Consider file test.proto, containing - -```proto - package example; - - enum FOO { X = 17; }; - - message Test { - required string label = 1; - optional int32 type = 2 [default=77]; - repeated int64 reps = 3; - optional group OptionalGroup = 4 { - required string RequiredField = 5; - } - } -``` - -To create and play with a Test object from the example package, - -```go - package main - - import ( - "log" - - "github.com/gogo/protobuf/proto" - "path/to/example" - ) - - func main() { - test := &example.Test { - Label: proto.String("hello"), - Type: proto.Int32(17), - Reps: []int64{1, 2, 3}, - Optionalgroup: &example.Test_OptionalGroup { - RequiredField: proto.String("good bye"), - }, - } - data, err := proto.Marshal(test) - if err != nil { - log.Fatal("marshaling error: ", err) - } - newTest := &example.Test{} - err = proto.Unmarshal(data, newTest) - if err != nil { - log.Fatal("unmarshaling error: ", err) - } - // Now test and newTest contain the same data. - if test.GetLabel() != newTest.GetLabel() { - log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) - } - // etc. - } -``` - - -## Parameters ## - -To pass extra parameters to the plugin, use a comma-separated -parameter list separated from the output directory by a colon: - - - protoc --gogo_out=plugins=grpc,import_path=mypackage:. *.proto - - -- `import_prefix=xxx` - a prefix that is added onto the beginning of - all imports. Useful for things like generating protos in a - subdirectory, or regenerating vendored protobufs in-place. -- `import_path=foo/bar` - used as the package if no input files - declare `go_package`. If it contains slashes, everything up to the - rightmost slash is ignored. -- `plugins=plugin1+plugin2` - specifies the list of sub-plugins to - load. The only plugin in this repo is `grpc`. -- `Mfoo/bar.proto=quux/shme` - declares that foo/bar.proto is - associated with Go package quux/shme. This is subject to the - import_prefix parameter. - -## gRPC Support ## - -If a proto file specifies RPC services, protoc-gen-go can be instructed to -generate code compatible with gRPC (http://www.grpc.io/). To do this, pass -the `plugins` parameter to protoc-gen-go; the usual way is to insert it into -the --go_out argument to protoc: - - protoc --gogo_out=plugins=grpc:. *.proto diff --git a/Godeps/_workspace_aux/src/github.com/golang/protobuf/README.md b/Godeps/_workspace_aux/src/github.com/golang/protobuf/README.md deleted file mode 100644 index 8fdc89b4d90..00000000000 --- a/Godeps/_workspace_aux/src/github.com/golang/protobuf/README.md +++ /dev/null @@ -1,199 +0,0 @@ -# Go support for Protocol Buffers - -Google's data interchange format. -Copyright 2010 The Go Authors. -https://github.com/golang/protobuf - -This package and the code it generates requires at least Go 1.4. - -This software implements Go bindings for protocol buffers. For -information about protocol buffers themselves, see - https://developers.google.com/protocol-buffers/ - -## Installation ## - -To use this software, you must: -- Install the standard C++ implementation of protocol buffers from - https://developers.google.com/protocol-buffers/ -- Of course, install the Go compiler and tools from - https://golang.org/ - See - https://golang.org/doc/install - for details or, if you are using gccgo, follow the instructions at - https://golang.org/doc/install/gccgo -- Grab the code from the repository and install the proto package. - The simplest way is to run `go get -u github.com/golang/protobuf/{proto,protoc-gen-go}`. - The compiler plugin, protoc-gen-go, will be installed in $GOBIN, - defaulting to $GOPATH/bin. It must be in your $PATH for the protocol - compiler, protoc, to find it. - -This software has two parts: a 'protocol compiler plugin' that -generates Go source files that, once compiled, can access and manage -protocol buffers; and a library that implements run-time support for -encoding (marshaling), decoding (unmarshaling), and accessing protocol -buffers. - -There is support for gRPC in Go using protocol buffers. -See the note at the bottom of this file for details. - -There are no insertion points in the plugin. - - -## Using protocol buffers with Go ## - -Once the software is installed, there are two steps to using it. -First you must compile the protocol buffer definitions and then import -them, with the support library, into your program. - -To compile the protocol buffer definition, run protoc with the --go_out -parameter set to the directory you want to output the Go code to. - - protoc --go_out=. *.proto - -The generated files will be suffixed .pb.go. See the Test code below -for an example using such a file. - - -The package comment for the proto library contains text describing -the interface provided in Go for protocol buffers. Here is an edited -version. - -========== - -The proto package converts data structures to and from the -wire format of protocol buffers. It works in concert with the -Go source code generated for .proto files by the protocol compiler. - -A summary of the properties of the protocol buffer interface -for a protocol buffer variable v: - - - Names are turned from camel_case to CamelCase for export. - - There are no methods on v to set fields; just treat - them as structure fields. - - There are getters that return a field's value if set, - and return the field's default value if unset. - The getters work even if the receiver is a nil message. - - The zero value for a struct is its correct initialization state. - All desired fields must be set before marshaling. - - A Reset() method will restore a protobuf struct to its zero state. - - Non-repeated fields are pointers to the values; nil means unset. - That is, optional or required field int32 f becomes F *int32. - - Repeated fields are slices. - - Helper functions are available to aid the setting of fields. - Helpers for getting values are superseded by the - GetFoo methods and their use is deprecated. - msg.Foo = proto.String("hello") // set field - - Constants are defined to hold the default values of all fields that - have them. They have the form Default_StructName_FieldName. - Because the getter methods handle defaulted values, - direct use of these constants should be rare. - - Enums are given type names and maps from names to values. - Enum values are prefixed with the enum's type name. Enum types have - a String method, and a Enum method to assist in message construction. - - Nested groups and enums have type names prefixed with the name of - the surrounding message type. - - Extensions are given descriptor names that start with E_, - followed by an underscore-delimited list of the nested messages - that contain it (if any) followed by the CamelCased name of the - extension field itself. HasExtension, ClearExtension, GetExtension - and SetExtension are functions for manipulating extensions. - - Oneof field sets are given a single field in their message, - with distinguished wrapper types for each possible field value. - - Marshal and Unmarshal are functions to encode and decode the wire format. - -When the .proto file specifies `syntax="proto3"`, there are some differences: - - - Non-repeated fields of non-message type are values instead of pointers. - - Getters are only generated for message and oneof fields. - - Enum types do not get an Enum method. - -Consider file test.proto, containing - -```proto - package example; - - enum FOO { X = 17; }; - - message Test { - required string label = 1; - optional int32 type = 2 [default=77]; - repeated int64 reps = 3; - optional group OptionalGroup = 4 { - required string RequiredField = 5; - } - } -``` - -To create and play with a Test object from the example package, - -```go - package main - - import ( - "log" - - "github.com/golang/protobuf/proto" - "path/to/example" - ) - - func main() { - test := &example.Test { - Label: proto.String("hello"), - Type: proto.Int32(17), - Reps: []int64{1, 2, 3}, - Optionalgroup: &example.Test_OptionalGroup { - RequiredField: proto.String("good bye"), - }, - } - data, err := proto.Marshal(test) - if err != nil { - log.Fatal("marshaling error: ", err) - } - newTest := &example.Test{} - err = proto.Unmarshal(data, newTest) - if err != nil { - log.Fatal("unmarshaling error: ", err) - } - // Now test and newTest contain the same data. - if test.GetLabel() != newTest.GetLabel() { - log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) - } - // etc. - } -``` - -## Parameters ## - -To pass extra parameters to the plugin, use a comma-separated -parameter list separated from the output directory by a colon: - - - protoc --go_out=plugins=grpc,import_path=mypackage:. *.proto - - -- `import_prefix=xxx` - a prefix that is added onto the beginning of - all imports. Useful for things like generating protos in a - subdirectory, or regenerating vendored protobufs in-place. -- `import_path=foo/bar` - used as the package if no input files - declare `go_package`. If it contains slashes, everything up to the - rightmost slash is ignored. -- `plugins=plugin1+plugin2` - specifies the list of sub-plugins to - load. The only plugin in this repo is `grpc`. -- `Mfoo/bar.proto=quux/shme` - declares that foo/bar.proto is - associated with Go package quux/shme. This is subject to the - import_prefix parameter. - -## gRPC Support ## - -If a proto file specifies RPC services, protoc-gen-go can be instructed to -generate code compatible with gRPC (http://www.grpc.io/). To do this, pass -the `plugins` parameter to protoc-gen-go; the usual way is to insert it into -the --go_out argument to protoc: - - protoc --go_out=plugins=grpc:. *.proto - -## Plugins ## - -The `protoc-gen-go/generator` package exposes a plugin interface, -which is used by the gRPC code generation. This interface is not -supported and is subject to incompatible changes without notice. diff --git a/Godeps/_workspace_aux/src/github.com/matttproud/golang_protobuf_extensions/NOTICE b/Godeps/_workspace_aux/src/github.com/matttproud/golang_protobuf_extensions/NOTICE deleted file mode 100644 index 5d8cb5b72e7..00000000000 --- a/Godeps/_workspace_aux/src/github.com/matttproud/golang_protobuf_extensions/NOTICE +++ /dev/null @@ -1 +0,0 @@ -Copyright 2012 Matt T. Proud (matt.proud@gmail.com) diff --git a/Godeps/_workspace_aux/src/github.com/stretchr/testify/README.md b/Godeps/_workspace_aux/src/github.com/stretchr/testify/README.md deleted file mode 100644 index aaf2aa0a8bf..00000000000 --- a/Godeps/_workspace_aux/src/github.com/stretchr/testify/README.md +++ /dev/null @@ -1,332 +0,0 @@ -Testify - Thou Shalt Write Tests -================================ - -[![Build Status](https://travis-ci.org/stretchr/testify.svg)](https://travis-ci.org/stretchr/testify) - -Go code (golang) set of packages that provide many tools for testifying that your code will behave as you intend. - -Features include: - - * [Easy assertions](#assert-package) - * [Mocking](#mock-package) - * [HTTP response trapping](#http-package) - * [Testing suite interfaces and functions](#suite-package) - -Get started: - - * Install testify with [one line of code](#installation), or [update it with another](#staying-up-to-date) - * For an introduction to writing test code in Go, see http://golang.org/doc/code.html#Testing - * Check out the API Documentation http://godoc.org/github.com/stretchr/testify - * To make your testing life easier, check out our other project, [gorc](http://github.com/stretchr/gorc) - * A little about [Test-Driven Development (TDD)](http://en.wikipedia.org/wiki/Test-driven_development) - - - -[`assert`](http://godoc.org/github.com/stretchr/testify/assert "API documentation") package -------------------------------------------------------------------------------------------- - -The `assert` package provides some helpful methods that allow you to write better test code in Go. - - * Prints friendly, easy to read failure descriptions - * Allows for very readable code - * Optionally annotate each assertion with a message - -See it in action: - -```go -package yours - -import ( - "testing" - "github.com/stretchr/testify/assert" -) - -func TestSomething(t *testing.T) { - - // assert equality - assert.Equal(t, 123, 123, "they should be equal") - - // assert inequality - assert.NotEqual(t, 123, 456, "they should not be equal") - - // assert for nil (good for errors) - assert.Nil(t, object) - - // assert for not nil (good when you expect something) - if assert.NotNil(t, object) { - - // now we know that object isn't nil, we are safe to make - // further assertions without causing any errors - assert.Equal(t, "Something", object.Value) - - } - -} -``` - - * Every assert func takes the `testing.T` object as the first argument. This is how it writes the errors out through the normal `go test` capabilities. - * Every assert func returns a bool indicating whether the assertion was successful or not, this is useful for if you want to go on making further assertions under certain conditions. - -if you assert many times, use the below: - -```go -package yours - -import ( - "testing" - "github.com/stretchr/testify/assert" -) - -func TestSomething(t *testing.T) { - assert := assert.New(t) - - // assert equality - assert.Equal(123, 123, "they should be equal") - - // assert inequality - assert.NotEqual(123, 456, "they should not be equal") - - // assert for nil (good for errors) - assert.Nil(object) - - // assert for not nil (good when you expect something) - if assert.NotNil(object) { - - // now we know that object isn't nil, we are safe to make - // further assertions without causing any errors - assert.Equal("Something", object.Value) - } -} -``` - -[`require`](http://godoc.org/github.com/stretchr/testify/require "API documentation") package ---------------------------------------------------------------------------------------------- - -The `require` package provides same global functions as the `assert` package, but instead of returning a boolean result they terminate current test. - -See [t.FailNow](http://golang.org/pkg/testing/#T.FailNow) for details. - - -[`http`](http://godoc.org/github.com/stretchr/testify/http "API documentation") package ---------------------------------------------------------------------------------------- - -The `http` package contains test objects useful for testing code that relies on the `net/http` package. Check out the [(deprecated) API documentation for the `http` package](http://godoc.org/github.com/stretchr/testify/http). - -We recommend you use [httptest](http://golang.org/pkg/net/http/httptest) instead. - -[`mock`](http://godoc.org/github.com/stretchr/testify/mock "API documentation") package ----------------------------------------------------------------------------------------- - -The `mock` package provides a mechanism for easily writing mock objects that can be used in place of real objects when writing test code. - -An example test function that tests a piece of code that relies on an external object `testObj`, can setup expectations (testify) and assert that they indeed happened: - -```go -package yours - -import ( - "testing" - "github.com/stretchr/testify/mock" -) - -/* - Test objects -*/ - -// MyMockedObject is a mocked object that implements an interface -// that describes an object that the code I am testing relies on. -type MyMockedObject struct{ - mock.Mock -} - -// DoSomething is a method on MyMockedObject that implements some interface -// and just records the activity, and returns what the Mock object tells it to. -// -// In the real object, this method would do something useful, but since this -// is a mocked object - we're just going to stub it out. -// -// NOTE: This method is not being tested here, code that uses this object is. -func (m *MyMockedObject) DoSomething(number int) (bool, error) { - - args := m.Called(number) - return args.Bool(0), args.Error(1) - -} - -/* - Actual test functions -*/ - -// TestSomething is an example of how to use our test object to -// make assertions about some target code we are testing. -func TestSomething(t *testing.T) { - - // create an instance of our test object - testObj := new(MyMockedObject) - - // setup expectations - testObj.On("DoSomething", 123).Return(true, nil) - - // call the code we are testing - targetFuncThatDoesSomethingWithObj(testObj) - - // assert that the expectations were met - testObj.AssertExpectations(t) - -} -``` - -For more information on how to write mock code, check out the [API documentation for the `mock` package](http://godoc.org/github.com/stretchr/testify/mock). - -You can use the [mockery tool](http://github.com/vektra/mockery) to autogenerate the mock code against an interface as well, making using mocks much quicker. - -[`suite`](http://godoc.org/github.com/stretchr/testify/suite "API documentation") package ------------------------------------------------------------------------------------------ - -The `suite` package provides functionality that you might be used to from more common object oriented languages. With it, you can build a testing suite as a struct, build setup/teardown methods and testing methods on your struct, and run them with 'go test' as per normal. - -An example suite is shown below: - -```go -// Basic imports -import ( - "testing" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/suite" -) - -// Define the suite, and absorb the built-in basic suite -// functionality from testify - including a T() method which -// returns the current testing context -type ExampleTestSuite struct { - suite.Suite - VariableThatShouldStartAtFive int -} - -// Make sure that VariableThatShouldStartAtFive is set to five -// before each test -func (suite *ExampleTestSuite) SetupTest() { - suite.VariableThatShouldStartAtFive = 5 -} - -// All methods that begin with "Test" are run as tests within a -// suite. -func (suite *ExampleTestSuite) TestExample() { - assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive) -} - -// In order for 'go test' to run this suite, we need to create -// a normal test function and pass our suite to suite.Run -func TestExampleTestSuite(t *testing.T) { - suite.Run(t, new(ExampleTestSuite)) -} -``` - -For a more complete example, using all of the functionality provided by the suite package, look at our [example testing suite](https://github.com/stretchr/testify/blob/master/suite/suite_test.go) - -For more information on writing suites, check out the [API documentation for the `suite` package](http://godoc.org/github.com/stretchr/testify/suite). - -`Suite` object has assertion methods: - -```go -// Basic imports -import ( - "testing" - "github.com/stretchr/testify/suite" -) - -// Define the suite, and absorb the built-in basic suite -// functionality from testify - including assertion methods. -type ExampleTestSuite struct { - suite.Suite - VariableThatShouldStartAtFive int -} - -// Make sure that VariableThatShouldStartAtFive is set to five -// before each test -func (suite *ExampleTestSuite) SetupTest() { - suite.VariableThatShouldStartAtFive = 5 -} - -// All methods that begin with "Test" are run as tests within a -// suite. -func (suite *ExampleTestSuite) TestExample() { - suite.Equal(suite.VariableThatShouldStartAtFive, 5) -} - -// In order for 'go test' to run this suite, we need to create -// a normal test function and pass our suite to suite.Run -func TestExampleTestSuite(t *testing.T) { - suite.Run(t, new(ExampleTestSuite)) -} -``` - ------- - -Installation -============ - -To install Testify, use `go get`: - - * Latest version: go get github.com/stretchr/testify - * Specific version: go get gopkg.in/stretchr/testify.v1 - -This will then make the following packages available to you: - - github.com/stretchr/testify/assert - github.com/stretchr/testify/mock - github.com/stretchr/testify/http - -Import the `testify/assert` package into your code using this template: - -```go -package yours - -import ( - "testing" - "github.com/stretchr/testify/assert" -) - -func TestSomething(t *testing.T) { - - assert.True(t, true, "True is true!") - -} -``` - ------- - -Staying up to date -================== - -To update Testify to the latest version, use `go get -u github.com/stretchr/testify`. - ------- - -Version History -=============== - - * 1.0 - New package versioning strategy adopted. - ------- - -Contributing -============ - -Please feel free to submit issues, fork the repository and send pull requests! - -When submitting an issue, we ask that you please include a complete test function that demonstrates the issue. Extra credit for those using Testify to write the test code that demonstrates it. - ------- - -Licence -======= -Copyright (c) 2012 - 2013 Mat Ryer and Tyler Bunnell - -Please consider promoting this project if you find it useful. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.