Merge pull request #24496 from euank/rkt-finished-at
Automatic merge from submit-queue rkt: Return `FinishedAt` for pod This is implemented via touching a file on stop as a hook in the systemd unit. The ctime of this file is then used to get the `finishedAt` time in the future. In addition, this changes the `startedAt` and `createdAt` to use the api server's results rather than the annotations it previously used. It's possible we might want to move this into the api in the future. Fixes #23887 I did the following manual testing: ``` $ cat ./examples/output/exit-output.yml apiVersion: v1 kind: Pod metadata: labels: name: exit name: exit-output spec: restartPolicy: Never containers: - name: exit image: busybox command: ["sh", "-c", "echo Exiting in 60; sleep 60; echo goodbye"] $ kubectl create -f ./examples/exit/exit-output.yaml $ # wait $ kubectl describe pod exit-output | grep State -A 4 State: Terminated Reason: Completed Exit Code: 0 Started: Tue, 19 Apr 2016 13:23:13 -0700 Finished: Tue, 19 Apr 2016 13:24:13 -0700 $ kubectl logs exit-output Exiting in 60 goodbye ``` I double checked as well that the file at `/var/lib/kubelet/pods/$id/finished-$id` existed and looked as expected. This is related to https://github.com/coreos/rkt/issues/1789#issuecomment-207111814 and follows https://github.com/kubernetes/kubernetes/pull/24367 + https://github.com/coreos/rkt/issues/2445 cc @jonboulle @iaguis @yifan-gu @kubernetes/sig-node
This commit is contained in:
		
							
								
								
									
										8
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								Godeps/Godeps.json
									
									
									
										generated
									
									
									
								
							@@ -391,8 +391,8 @@
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/coreos/rkt/api/v1alpha",
 | 
								"ImportPath": "github.com/coreos/rkt/api/v1alpha",
 | 
				
			||||||
			"Comment": "v1.2.1-24-ge568957",
 | 
								"Comment": "v1.4.0",
 | 
				
			||||||
			"Rev": "e56895779706097a5fdfc7099003d105cc325638"
 | 
								"Rev": "f5b69782d120a7ae5ada8f2ebad97a014a98ebd5"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/cpuguy83/go-md2man/md2man",
 | 
								"ImportPath": "github.com/cpuguy83/go-md2man/md2man",
 | 
				
			||||||
@@ -653,6 +653,10 @@
 | 
				
			|||||||
			"ImportPath": "github.com/golang/groupcache/lru",
 | 
								"ImportPath": "github.com/golang/groupcache/lru",
 | 
				
			||||||
			"Rev": "604ed5785183e59ae2789449d89e73f3a2a77987"
 | 
								"Rev": "604ed5785183e59ae2789449d89e73f3a2a77987"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"ImportPath": "github.com/golang/mock/gomock",
 | 
				
			||||||
 | 
								"Rev": "bd3c8e81be01eef76d4b503f5e687d2d1354d2d9"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"ImportPath": "github.com/golang/protobuf/proto",
 | 
								"ImportPath": "github.com/golang/protobuf/proto",
 | 
				
			||||||
			"Rev": "b982704f8bb716bb608144408cff30e15fbde841"
 | 
								"Rev": "b982704f8bb716bb608144408cff30e15fbde841"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										207
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										207
									
								
								Godeps/LICENSES
									
									
									
										generated
									
									
									
								
							@@ -25386,6 +25386,213 @@ third-party archives.
 | 
				
			|||||||
   limitations under the License.
 | 
					   limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					================================================================================
 | 
				
			||||||
 | 
					= Godeps/_workspace/src/github.com/golang/mock/gomock 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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
================================================================================
 | 
					================================================================================
 | 
				
			||||||
= Godeps/_workspace/src/github.com/golang/protobuf/proto licensed under: =
 | 
					= Godeps/_workspace/src/github.com/golang/protobuf/proto licensed under: =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -9,3 +9,13 @@ For more information, see:
 | 
				
			|||||||
- #1359
 | 
					- #1359
 | 
				
			||||||
- #1468
 | 
					- #1468
 | 
				
			||||||
- [API Service Subcommand](../../Documentation/subcommands/api-service.md)
 | 
					- [API Service Subcommand](../../Documentation/subcommands/api-service.md)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Protobuf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The rkt gRPC API uses Protocol Buffers for its services.
 | 
				
			||||||
 | 
					In order to rebuild the generated code make sure you have protobuf 3.0.0 installed (https://github.com/google/protobuf)
 | 
				
			||||||
 | 
					and execute from the top-level directory:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					$ make protobuf
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										199
									
								
								Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/api.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										199
									
								
								Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/api.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -338,6 +338,18 @@ type Pod struct {
 | 
				
			|||||||
	Manifest []byte `protobuf:"bytes,6,opt,name=manifest,proto3" json:"manifest,omitempty"`
 | 
						Manifest []byte `protobuf:"bytes,6,opt,name=manifest,proto3" json:"manifest,omitempty"`
 | 
				
			||||||
	// Annotations on this pod.
 | 
						// Annotations on this pod.
 | 
				
			||||||
	Annotations []*KeyValue `protobuf:"bytes,7,rep,name=annotations" json:"annotations,omitempty"`
 | 
						Annotations []*KeyValue `protobuf:"bytes,7,rep,name=annotations" json:"annotations,omitempty"`
 | 
				
			||||||
 | 
						// Cgroup of the pod, empty if the pod is not running.
 | 
				
			||||||
 | 
						Cgroup string `protobuf:"bytes,8,opt,name=cgroup" json:"cgroup,omitempty"`
 | 
				
			||||||
 | 
						// Timestamp of when the pod is created, nanoseconds since epoch.
 | 
				
			||||||
 | 
						// Zero if the pod is not created.
 | 
				
			||||||
 | 
						CreatedAt int64 `protobuf:"varint,9,opt,name=created_at" json:"created_at,omitempty"`
 | 
				
			||||||
 | 
						// Timestamp of when the pod is started, nanoseconds since epoch.
 | 
				
			||||||
 | 
						// Zero if the pod is not started.
 | 
				
			||||||
 | 
						StartedAt int64 `protobuf:"varint,10,opt,name=started_at" json:"started_at,omitempty"`
 | 
				
			||||||
 | 
						// Timestamp of when the pod is moved to exited-garbage/garbage,
 | 
				
			||||||
 | 
						// in nanoseconds since epoch.
 | 
				
			||||||
 | 
						// Zero if the pod is not moved to exited-garbage/garbage yet.
 | 
				
			||||||
 | 
						GcMarkedAt int64 `protobuf:"varint,11,opt,name=gc_marked_at" json:"gc_marked_at,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *Pod) Reset()                    { *m = Pod{} }
 | 
					func (m *Pod) Reset()                    { *m = Pod{} }
 | 
				
			||||||
@@ -393,6 +405,8 @@ type PodFilter struct {
 | 
				
			|||||||
	NetworkNames []string `protobuf:"bytes,5,rep,name=network_names" json:"network_names,omitempty"`
 | 
						NetworkNames []string `protobuf:"bytes,5,rep,name=network_names" json:"network_names,omitempty"`
 | 
				
			||||||
	// If not empty, the pods that have all of the annotations will be returned.
 | 
						// If not empty, the pods that have all of the annotations will be returned.
 | 
				
			||||||
	Annotations []*KeyValue `protobuf:"bytes,6,rep,name=annotations" json:"annotations,omitempty"`
 | 
						Annotations []*KeyValue `protobuf:"bytes,6,rep,name=annotations" json:"annotations,omitempty"`
 | 
				
			||||||
 | 
						// If not empty, the pods whose cgroup are listed will be returned.
 | 
				
			||||||
 | 
						Cgroups []string `protobuf:"bytes,7,rep,name=cgroups" json:"cgroups,omitempty"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *PodFilter) Reset()                    { *m = PodFilter{} }
 | 
					func (m *PodFilter) Reset()                    { *m = PodFilter{} }
 | 
				
			||||||
@@ -1124,95 +1138,98 @@ var _PublicAPI_serviceDesc = grpc.ServiceDesc{
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var fileDescriptor0 = []byte{
 | 
					var fileDescriptor0 = []byte{
 | 
				
			||||||
	// 1430 bytes of a gzipped FileDescriptorProto
 | 
						// 1481 bytes of a gzipped FileDescriptorProto
 | 
				
			||||||
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x57, 0xdb, 0x6e, 0xdb, 0x46,
 | 
						0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x57, 0xcd, 0x72, 0xdb, 0x46,
 | 
				
			||||||
	0x13, 0x8e, 0x0e, 0xd4, 0x61, 0xa4, 0xc8, 0xd2, 0xda, 0x89, 0x65, 0xe5, 0xe4, 0xf0, 0xff, 0x1b,
 | 
						0x12, 0x36, 0x7f, 0xc0, 0x9f, 0x26, 0x4d, 0x91, 0x23, 0xd9, 0xa2, 0xe8, 0x3f, 0x19, 0xbb, 0xeb,
 | 
				
			||||||
	0xa4, 0xbe, 0x70, 0x5b, 0x27, 0xcd, 0x4d, 0x81, 0x22, 0x8a, 0x4d, 0x1b, 0x6a, 0x6c, 0x49, 0x50,
 | 
						0xf2, 0xea, 0xa0, 0xdd, 0xc8, 0x8e, 0x2f, 0xa9, 0x4a, 0x99, 0x96, 0x20, 0x15, 0x63, 0x89, 0x64,
 | 
				
			||||||
	0x94, 0xa0, 0xb9, 0x22, 0x68, 0x69, 0xe5, 0x10, 0xa1, 0x48, 0x96, 0xa4, 0x9c, 0xb8, 0x97, 0x7d,
 | 
						0xd1, 0xb4, 0x2b, 0x3e, 0xa1, 0x20, 0x72, 0x28, 0xa3, 0x04, 0x02, 0x08, 0x00, 0xca, 0x56, 0x8e,
 | 
				
			||||||
	0x81, 0x3e, 0x42, 0xfb, 0x16, 0x05, 0x7a, 0xd3, 0x77, 0x29, 0xd0, 0xf7, 0xe8, 0xec, 0x72, 0x49,
 | 
						0x39, 0xe5, 0x96, 0x47, 0xc8, 0x33, 0xe4, 0x94, 0x63, 0xde, 0x25, 0x55, 0x79, 0x8f, 0xf4, 0x0c,
 | 
				
			||||||
	0x2e, 0x29, 0xea, 0xa2, 0x77, 0xe6, 0xcc, 0xec, 0x37, 0xdf, 0xcc, 0xce, 0x7c, 0x2b, 0x43, 0xdd,
 | 
						0x06, 0xc0, 0x00, 0x04, 0x0f, 0xb9, 0x89, 0xdd, 0x3d, 0x5f, 0x7f, 0xdd, 0xd3, 0xfd, 0x0d, 0x04,
 | 
				
			||||||
	0x70, 0xcd, 0x43, 0xd7, 0x73, 0x02, 0x87, 0x54, 0xaf, 0xbf, 0x31, 0x2c, 0xf7, 0x83, 0xa1, 0xbe,
 | 
						0x75, 0xc3, 0x35, 0x0f, 0x5d, 0xcf, 0x09, 0x1c, 0x52, 0xbd, 0xf9, 0xca, 0xb0, 0xdc, 0x4f, 0x86,
 | 
				
			||||||
	0x84, 0xc6, 0x60, 0x69, 0x5c, 0xd1, 0x53, 0xc7, 0x5b, 0x1a, 0x01, 0xd9, 0x87, 0x72, 0x70, 0xe3,
 | 
						0xfa, 0x1a, 0x1a, 0x83, 0xa5, 0x71, 0x45, 0x4f, 0x1d, 0x6f, 0x69, 0x04, 0x64, 0x1f, 0xca, 0xc1,
 | 
				
			||||||
	0xd2, 0x6e, 0x61, 0xbf, 0xf0, 0xb4, 0x75, 0x44, 0x0e, 0x45, 0xd8, 0x21, 0x8f, 0x99, 0xa2, 0x87,
 | 
						0xad, 0x4b, 0xbb, 0x85, 0xfd, 0xc2, 0xf3, 0xd6, 0x11, 0x39, 0x14, 0x61, 0x87, 0x3c, 0x66, 0x8a,
 | 
				
			||||||
	0x6c, 0x41, 0xf5, 0x9a, 0x7a, 0xbe, 0xe9, 0xd8, 0xdd, 0x22, 0x06, 0xd5, 0xd5, 0xbf, 0x0a, 0xa0,
 | 
						0x1e, 0xb2, 0x05, 0xd5, 0x1b, 0xea, 0xf9, 0xa6, 0x63, 0x77, 0x8b, 0x18, 0x54, 0x57, 0xff, 0x28,
 | 
				
			||||||
	0x70, 0x37, 0xf9, 0x12, 0x1a, 0x97, 0x86, 0x4f, 0xf5, 0x05, 0xc7, 0xe2, 0x18, 0x8d, 0xa3, 0x9d,
 | 
						0x80, 0xc2, 0xdd, 0xe4, 0xbf, 0xd0, 0xb8, 0x34, 0x7c, 0xaa, 0x2f, 0x38, 0x16, 0xc7, 0x68, 0x1c,
 | 
				
			||||||
	0x34, 0x86, 0xc8, 0x03, 0x50, 0x34, 0xe7, 0x21, 0x00, 0x69, 0x42, 0xd9, 0x36, 0x96, 0xb4, 0x5b,
 | 
						0xed, 0xa4, 0x31, 0x44, 0x1e, 0x80, 0xa2, 0x39, 0x0f, 0x01, 0x48, 0x13, 0xca, 0xb6, 0xb1, 0xa4,
 | 
				
			||||||
	0xe2, 0x5f, 0x12, 0x7e, 0x99, 0x1b, 0xba, 0xd0, 0x36, 0x97, 0xae, 0xe3, 0x05, 0x7a, 0x60, 0x2e,
 | 
						0xdd, 0x12, 0xff, 0x25, 0xe1, 0x97, 0xb9, 0xa1, 0x0b, 0x6d, 0x73, 0xe9, 0x3a, 0x5e, 0xa0, 0x07,
 | 
				
			||||||
	0xa9, 0x1f, 0x18, 0x4b, 0xb7, 0xab, 0xa0, 0xa7, 0x44, 0xda, 0x50, 0x5b, 0x1a, 0xb6, 0xb9, 0x40,
 | 
						0xe6, 0x92, 0xfa, 0x81, 0xb1, 0x74, 0xbb, 0x0a, 0x7a, 0x4a, 0xa4, 0x0d, 0xb5, 0xa5, 0x61, 0x9b,
 | 
				
			||||||
	0x63, 0xb7, 0x82, 0x96, 0x26, 0x83, 0xf2, 0xcd, 0x9f, 0x69, 0xb7, 0xca, 0xfd, 0x4f, 0xa0, 0x61,
 | 
						0x0b, 0x34, 0x76, 0x2b, 0x68, 0x69, 0x32, 0x28, 0xdf, 0xfc, 0x91, 0x76, 0xab, 0xdc, 0xff, 0x0c,
 | 
				
			||||||
	0xd8, 0xb6, 0x13, 0x18, 0x01, 0xa2, 0xf9, 0xdd, 0xda, 0x7e, 0x09, 0xf9, 0x74, 0x62, 0x3e, 0xaf,
 | 
						0x1a, 0x86, 0x6d, 0x3b, 0x81, 0x11, 0x20, 0x9a, 0xdf, 0xad, 0xed, 0x97, 0x90, 0x4f, 0x27, 0xe6,
 | 
				
			||||||
	0xe9, 0xcd, 0x3b, 0xc3, 0x5a, 0x51, 0xf5, 0x19, 0x54, 0x87, 0x34, 0xf8, 0xe4, 0x78, 0x1f, 0x63,
 | 
						0xf3, 0x96, 0xde, 0x7e, 0x30, 0xac, 0x15, 0x55, 0x5f, 0x40, 0x75, 0x48, 0x83, 0xcf, 0x8e, 0x77,
 | 
				
			||||||
	0x2e, 0x85, 0x88, 0x99, 0xe9, 0x5e, 0x3f, 0x4f, 0x78, 0xe2, 0xd7, 0x8b, 0x90, 0xa7, 0xfa, 0x6b,
 | 
						0x1d, 0x73, 0x29, 0x44, 0xcc, 0x4c, 0xf7, 0xe6, 0x65, 0xc2, 0x13, 0x7f, 0xbd, 0x0a, 0x79, 0xaa,
 | 
				
			||||||
	0x01, 0x4a, 0x7d, 0xd7, 0xcd, 0x9c, 0x78, 0x00, 0x8a, 0xc9, 0xca, 0xe4, 0x47, 0x1a, 0x47, 0xad,
 | 
						0xbf, 0x14, 0xa0, 0xd4, 0x77, 0xdd, 0xcc, 0x89, 0x47, 0xa0, 0x98, 0xac, 0x4c, 0x7e, 0xa4, 0x71,
 | 
				
			||||||
	0x74, 0xf1, 0xd8, 0x5e, 0x05, 0x0b, 0x08, 0xc2, 0x5a, 0x5b, 0x12, 0x17, 0x44, 0x7a, 0xc3, 0x1c,
 | 
						0xd4, 0x4a, 0x17, 0x8f, 0xed, 0x55, 0xb0, 0x80, 0x20, 0xac, 0xb5, 0x25, 0x71, 0x41, 0xa4, 0x77,
 | 
				
			||||||
	0xa4, 0x03, 0x75, 0xfa, 0xd9, 0x0c, 0xf4, 0x99, 0x33, 0xa7, 0xbc, 0x01, 0x9d, 0x6c, 0x19, 0xca,
 | 
						0xcc, 0x41, 0x3a, 0x50, 0xa7, 0x5f, 0xcc, 0x40, 0x9f, 0x39, 0x73, 0xca, 0x1b, 0xd0, 0xc9, 0x96,
 | 
				
			||||||
	0xa6, 0x32, 0xfe, 0x44, 0x46, 0x63, 0x67, 0x2e, 0x7a, 0x1b, 0xf2, 0x69, 0x40, 0xc9, 0x15, 0x8d,
 | 
						0xa1, 0x6c, 0x2a, 0xe3, 0xe7, 0x22, 0x94, 0xc6, 0xce, 0x5c, 0xf4, 0x36, 0xe4, 0xd3, 0x80, 0x92,
 | 
				
			||||||
	0xee, 0x6c, 0xce, 0x8e, 0xa7, 0xc2, 0xec, 0x3d, 0x28, 0x1b, 0xae, 0xeb, 0x63, 0x62, 0x96, 0xa3,
 | 
						0x2b, 0x1a, 0xdd, 0xd9, 0x9c, 0x1d, 0x4f, 0x85, 0xd9, 0x7b, 0x50, 0x36, 0x5c, 0xd7, 0xc7, 0xc4,
 | 
				
			||||||
	0x29, 0xd3, 0x23, 0x2a, 0xd4, 0xec, 0xb0, 0x4b, 0x11, 0x87, 0x76, 0xec, 0x8f, 0xda, 0xb7, 0x7e,
 | 
						0x2c, 0x47, 0x53, 0xa6, 0x47, 0x54, 0xa8, 0xd9, 0x61, 0x97, 0x22, 0x0e, 0xed, 0xd8, 0x1f, 0xb5,
 | 
				
			||||||
	0x23, 0x19, 0xf2, 0xd5, 0x4d, 0xe4, 0x9f, 0x40, 0x2d, 0xfa, 0x9b, 0x91, 0xc6, 0xbf, 0x45, 0x05,
 | 
						0x6f, 0xfd, 0x46, 0x32, 0xe4, 0xab, 0x1b, 0xc8, 0x93, 0x16, 0x54, 0x66, 0x57, 0x9e, 0xb3, 0x72,
 | 
				
			||||||
	0xb7, 0x41, 0xb9, 0x66, 0x56, 0x31, 0x6d, 0xbf, 0x17, 0xa0, 0x8e, 0x74, 0x4f, 0x4d, 0x2b, 0xa0,
 | 
						0xf1, 0x9a, 0x18, 0x71, 0xac, 0x62, 0xe6, 0x51, 0xe4, 0x34, 0xd7, 0x71, 0x94, 0xea, 0xfc, 0x3e,
 | 
				
			||||||
	0x1e, 0x8b, 0x34, 0xe7, 0x3e, 0x46, 0x96, 0x30, 0xf2, 0x31, 0x54, 0x78, 0x79, 0x3e, 0x86, 0x96,
 | 
						0xd1, 0x86, 0xfc, 0x3d, 0x61, 0x03, 0x6e, 0xdb, 0x81, 0xe6, 0xd5, 0x4c, 0x5f, 0x1a, 0xde, 0x75,
 | 
				
			||||||
	0xf2, 0xeb, 0xeb, 0xb0, 0x1d, 0x70, 0x75, 0x76, 0x61, 0x3e, 0x76, 0x81, 0x9d, 0x42, 0x13, 0xbf,
 | 
						0x68, 0x6d, 0x30, 0xab, 0xfa, 0x0c, 0x6a, 0x31, 0x32, 0xb6, 0x00, 0xff, 0x16, 0xfd, 0xb8, 0x0b,
 | 
				
			||||||
	0x31, 0x9d, 0x01, 0x95, 0xb9, 0xe9, 0x0e, 0xdc, 0x16, 0x95, 0x8a, 0x48, 0x85, 0x9b, 0x33, 0xa5,
 | 
						0xca, 0x0d, 0xb3, 0x8a, 0xd9, 0xfd, 0xad, 0x00, 0x75, 0x2c, 0xfe, 0xd4, 0xb4, 0x02, 0xea, 0xb1,
 | 
				
			||||||
	0x54, 0x36, 0x95, 0xf2, 0x77, 0x21, 0xda, 0xa9, 0x1c, 0x92, 0xd8, 0x21, 0xd7, 0xa3, 0x0b, 0xf3,
 | 
						0x48, 0x73, 0xee, 0x63, 0x64, 0x09, 0x23, 0x9f, 0x42, 0x85, 0x37, 0xcb, 0xc7, 0xd0, 0x52, 0x7e,
 | 
				
			||||||
	0xb3, 0xa0, 0x59, 0x27, 0x78, 0x5f, 0x7c, 0x6b, 0x64, 0x52, 0x18, 0xf5, 0x91, 0xde, 0x20, 0x83,
 | 
						0xb7, 0x3a, 0x6c, 0xa3, 0x5c, 0x9d, 0x5d, 0xbf, 0x8f, 0x3d, 0x65, 0xa7, 0xd0, 0xc4, 0xef, 0x5f,
 | 
				
			||||||
	0x98, 0x13, 0x16, 0x67, 0x19, 0x97, 0xd4, 0xda, 0x7c, 0xff, 0xe4, 0x2e, 0xb4, 0xc2, 0x45, 0xa1,
 | 
						0x67, 0x40, 0x65, 0x6e, 0xba, 0x07, 0x77, 0x45, 0xdf, 0x44, 0xa4, 0xc2, 0xcd, 0x99, 0xc6, 0x54,
 | 
				
			||||||
	0x73, 0xdd, 0x58, 0x60, 0x66, 0x7e, 0x05, 0x25, 0xb2, 0x0b, 0x5b, 0xb1, 0xfd, 0x92, 0xe2, 0x72,
 | 
						0x36, 0x35, 0x06, 0xf7, 0x21, 0x6c, 0x4c, 0xd8, 0xbc, 0xba, 0xfa, 0x67, 0x21, 0x5a, 0xd9, 0x1c,
 | 
				
			||||||
	0xfe, 0xc7, 0xfd, 0x60, 0x0c, 0x17, 0x2b, 0xcb, 0x12, 0x0c, 0xeb, 0x8c, 0x8f, 0xfa, 0x1b, 0x16,
 | 
						0xd6, 0x78, 0x01, 0xae, 0x47, 0x17, 0xe6, 0x17, 0xc1, 0x9b, 0x37, 0x92, 0x2f, 0xa5, 0xcc, 0x12,
 | 
				
			||||||
	0x79, 0x66, 0x39, 0x97, 0x86, 0x75, 0x6a, 0x19, 0x57, 0x3e, 0x2b, 0x72, 0x6e, 0x7a, 0xe2, 0xce,
 | 
						0xa3, 0xae, 0xe9, 0x2d, 0x52, 0x8a, 0x49, 0x62, 0xb5, 0x96, 0x71, 0x49, 0xad, 0xcd, 0xe3, 0x45,
 | 
				
			||||||
	0xf6, 0xa0, 0xe3, 0xdf, 0xf8, 0x01, 0x5d, 0xe2, 0x18, 0xdb, 0x0b, 0xf3, 0x4a, 0x67, 0xae, 0x62,
 | 
						0xee, 0x43, 0x2b, 0xdc, 0x43, 0xd6, 0xe8, 0x05, 0x66, 0xe6, 0x37, 0x5c, 0x22, 0xbb, 0xb0, 0x15,
 | 
				
			||||||
	0xb4, 0xcd, 0x96, 0x33, 0x33, 0x2c, 0xd9, 0x13, 0x2e, 0x3e, 0xd2, 0x5c, 0xf9, 0xd4, 0x93, 0x1d,
 | 
						0xdb, 0x2f, 0x29, 0xee, 0xfe, 0x3f, 0x5c, 0x3f, 0xc6, 0x70, 0xb1, 0xb2, 0x2c, 0xc1, 0xb0, 0xce,
 | 
				
			||||||
	0xa1, 0x00, 0xb0, 0xba, 0x6c, 0x9f, 0xce, 0x56, 0x1e, 0x4a, 0x0b, 0x4b, 0xc6, 0xd7, 0x9f, 0xed,
 | 
						0x8b, 0xfc, 0x15, 0x8b, 0x3c, 0xb3, 0x9c, 0x4b, 0xc3, 0x3a, 0xb5, 0x8c, 0x2b, 0x9f, 0x15, 0x39,
 | 
				
			||||||
	0xda, 0x9d, 0xc0, 0x5b, 0xf9, 0x81, 0x8e, 0xad, 0xf2, 0xf5, 0x85, 0xe7, 0x2c, 0xf5, 0x0f, 0x41,
 | 
						0x37, 0x3d, 0x71, 0x89, 0x7b, 0xd0, 0xf1, 0x6f, 0xfd, 0x80, 0x2e, 0x71, 0x4b, 0xec, 0x85, 0x79,
 | 
				
			||||||
	0xe0, 0xfa, 0xbc, 0xec, 0x9a, 0xea, 0x41, 0x79, 0x60, 0x2f, 0x1c, 0xb2, 0x0d, 0x0d, 0xef, 0x63,
 | 
						0xa5, 0x33, 0x57, 0x31, 0x12, 0x0b, 0xcb, 0x99, 0x19, 0x96, 0xec, 0x09, 0x75, 0x05, 0x69, 0xae,
 | 
				
			||||||
	0xa0, 0x47, 0xa2, 0x12, 0x32, 0xdc, 0x81, 0x26, 0x0e, 0xc2, 0x4c, 0x4f, 0x49, 0x19, 0x0b, 0x45,
 | 
						0x7c, 0xea, 0xc9, 0x8e, 0x50, 0x5f, 0x58, 0x5d, 0xb6, 0x4f, 0x67, 0x2b, 0x0f, 0x95, 0x8b, 0x25,
 | 
				
			||||||
	0x89, 0x8c, 0x8d, 0x21, 0xaf, 0x03, 0x68, 0x5e, 0xf1, 0x42, 0x45, 0xf2, 0x72, 0x46, 0xd6, 0xa4,
 | 
						0xe3, 0xea, 0xc2, 0x56, 0xf9, 0x5e, 0xe0, 0xad, 0xfc, 0x40, 0xc7, 0x56, 0xf9, 0xfa, 0xc2, 0x73,
 | 
				
			||||||
	0x2e, 0x60, 0x4e, 0x45, 0xbb, 0xa6, 0xf6, 0x66, 0x1d, 0xe5, 0x5e, 0xae, 0xa3, 0x19, 0x05, 0x64,
 | 
						0x96, 0xfa, 0xa7, 0x20, 0x70, 0x7d, 0x5e, 0x76, 0x4d, 0xf5, 0xa0, 0x3c, 0xb0, 0x17, 0x0e, 0xd9,
 | 
				
			||||||
	0xf4, 0x45, 0x42, 0xfc, 0x62, 0x4a, 0xc7, 0x13, 0x95, 0xc8, 0x23, 0x28, 0xcf, 0x8d, 0xc0, 0xd8,
 | 
						0x86, 0x86, 0x77, 0x1d, 0xe8, 0x91, 0x66, 0x85, 0x0c, 0x71, 0x2a, 0x71, 0x32, 0x66, 0x7a, 0x4a,
 | 
				
			||||||
	0xbc, 0xf6, 0x01, 0x34, 0x38, 0xaa, 0x98, 0xb6, 0xc7, 0xa0, 0xb0, 0xcc, 0xe1, 0xbc, 0xe5, 0xa7,
 | 
						0x29, 0x59, 0x28, 0x2a, 0x70, 0x6c, 0x0c, 0x79, 0x1d, 0xe0, 0x00, 0xf3, 0x42, 0x45, 0xf2, 0x72,
 | 
				
			||||||
	0x16, 0x03, 0x19, 0x8e, 0x1f, 0xee, 0x97, 0x3c, 0x79, 0xc8, 0xcb, 0x37, 0xed, 0x19, 0xd5, 0x25,
 | 
						0x46, 0x35, 0xa5, 0x2e, 0x60, 0x4e, 0x45, 0xbb, 0xa1, 0xf6, 0x66, 0x99, 0xe6, 0x5e, 0x2e, 0xd3,
 | 
				
			||||||
	0x0a, 0x68, 0x5b, 0xd9, 0x81, 0x69, 0x85, 0x36, 0xae, 0xbd, 0x6a, 0x1b, 0x5a, 0x67, 0x34, 0x60,
 | 
						0x19, 0x81, 0x65, 0xf4, 0x45, 0x42, 0xfc, 0xc5, 0x84, 0x94, 0x27, 0x2a, 0x91, 0x27, 0x50, 0x9e,
 | 
				
			||||||
	0x0d, 0x9e, 0xd0, 0x9f, 0x56, 0xb8, 0xef, 0xea, 0x21, 0x6c, 0xc5, 0x16, 0xdf, 0xc5, 0x81, 0xa2,
 | 
						0x1b, 0x81, 0xb1, 0x59, 0x55, 0x02, 0x68, 0x70, 0x54, 0x31, 0x6d, 0x4f, 0x41, 0x61, 0x99, 0xc3,
 | 
				
			||||||
	0xe4, 0x1e, 0x2a, 0x26, 0x7e, 0x8b, 0x97, 0xe0, 0x76, 0x22, 0x86, 0x68, 0x54, 0x4f, 0x61, 0xeb,
 | 
						0x79, 0xcb, 0x4f, 0x2d, 0x06, 0x32, 0x1c, 0x3f, 0x5c, 0x38, 0x79, 0xf2, 0xd8, 0x0a, 0x9b, 0xf6,
 | 
				
			||||||
	0xdc, 0xf4, 0x03, 0xdc, 0x4d, 0x5f, 0x40, 0x90, 0xff, 0x41, 0x75, 0xc1, 0xab, 0x08, 0xd9, 0x37,
 | 
						0x8c, 0xea, 0x12, 0x05, 0xb4, 0xad, 0xec, 0xc0, 0xb4, 0x42, 0x1b, 0x97, 0x76, 0xb5, 0x0d, 0xad,
 | 
				
			||||||
	0x24, 0xf6, 0xc9, 0xce, 0xb7, 0xa0, 0x32, 0xa7, 0x81, 0x61, 0x5a, 0xbc, 0x79, 0x35, 0xcc, 0xdb,
 | 
						0x33, 0x1a, 0xb0, 0x06, 0x4f, 0xe8, 0x0f, 0x2b, 0x94, 0x13, 0xf5, 0x10, 0xb6, 0x62, 0x8b, 0xef,
 | 
				
			||||||
	0x4e, 0x70, 0x44, 0x62, 0xd4, 0x31, 0xd7, 0x99, 0x47, 0x28, 0x4d, 0x19, 0x45, 0x7d, 0x04, 0x9d,
 | 
						0xe2, 0x40, 0x51, 0xf2, 0x00, 0x05, 0x19, 0x7f, 0x8b, 0x87, 0xe6, 0x6e, 0xa2, 0xb5, 0x68, 0x54,
 | 
				
			||||||
	0x81, 0xed, 0xbb, 0x74, 0xc6, 0x8e, 0x44, 0x99, 0x25, 0xcd, 0x54, 0xbf, 0x02, 0x22, 0x07, 0x08,
 | 
						0x4f, 0x61, 0xeb, 0xdc, 0xf4, 0x03, 0x5c, 0x56, 0x5f, 0x40, 0x90, 0x7f, 0x41, 0x75, 0xc1, 0xab,
 | 
				
			||||||
	0xc8, 0x3d, 0x54, 0x52, 0x67, 0x2e, 0x4a, 0x49, 0x23, 0xfe, 0x00, 0x1d, 0xc6, 0x80, 0xef, 0x7c,
 | 
						0x08, 0xd9, 0x37, 0x24, 0xf6, 0x89, 0x08, 0xa0, 0x10, 0xcd, 0x69, 0x60, 0x98, 0x16, 0x6f, 0x5e,
 | 
				
			||||||
	0x5c, 0xcb, 0x17, 0xd9, 0x5a, 0xb2, 0x0f, 0x61, 0x7e, 0x35, 0xcf, 0x81, 0xc8, 0x58, 0x22, 0xf9,
 | 
						0x0d, 0xf3, 0xb6, 0x13, 0x1c, 0x91, 0x18, 0x65, 0xd2, 0x75, 0xe6, 0x11, 0x4a, 0x53, 0x46, 0x51,
 | 
				
			||||||
	0x43, 0xa8, 0x70, 0x91, 0x8a, 0xb0, 0x32, 0xef, 0x8a, 0xfa, 0x18, 0xb6, 0x05, 0x65, 0xfe, 0x9d,
 | 
						0x9f, 0x40, 0x67, 0x60, 0xfb, 0x2e, 0x9d, 0xb1, 0x23, 0x51, 0x66, 0x49, 0x92, 0xd5, 0xff, 0x01,
 | 
				
			||||||
	0x57, 0xd5, 0xb7, 0xb0, 0x93, 0x0e, 0x11, 0xd0, 0xf1, 0x8b, 0x55, 0xc8, 0x7b, 0xb1, 0xd4, 0xef,
 | 
						0x91, 0x03, 0x04, 0xe4, 0x1e, 0x0a, 0xb5, 0x33, 0x17, 0xa5, 0xa4, 0x11, 0xbf, 0x83, 0x0e, 0x63,
 | 
				
			||||||
	0x60, 0x9b, 0xf1, 0xa1, 0x36, 0x1f, 0x9f, 0xb8, 0xba, 0xff, 0x43, 0x25, 0xac, 0x6e, 0xed, 0x95,
 | 
						0xc0, 0x77, 0x3e, 0xae, 0xe5, 0x3f, 0xd9, 0x5a, 0xb2, 0xef, 0x6c, 0x7e, 0x35, 0x2f, 0x81, 0xc8,
 | 
				
			||||||
	0x97, 0x66, 0x51, 0x7d, 0x01, 0x3b, 0xe9, 0xc3, 0x49, 0x39, 0x94, 0x5b, 0xd6, 0xca, 0xe1, 0x81,
 | 
						0x58, 0x22, 0xf9, 0x63, 0xa8, 0x70, 0xd5, 0x8a, 0xb0, 0x32, 0xcf, 0x96, 0xfa, 0x14, 0xb6, 0x05,
 | 
				
			||||||
	0xea, 0x0d, 0x1f, 0xae, 0x73, 0xe7, 0x2a, 0xce, 0x87, 0x6d, 0xc2, 0xee, 0xeb, 0xf1, 0xbb, 0x86,
 | 
						0x65, 0xfe, 0x3b, 0xaf, 0xaa, 0xaf, 0x61, 0x27, 0x1d, 0x22, 0xa0, 0xe3, 0x07, 0xb1, 0x90, 0xf7,
 | 
				
			||||||
	0x02, 0x19, 0x09, 0xb9, 0xd8, 0x21, 0x9c, 0x63, 0xcb, 0xb4, 0xf9, 0x1c, 0x17, 0x9e, 0x2a, 0xec,
 | 
						0x20, 0xaa, 0xdf, 0xc0, 0x36, 0xe3, 0x43, 0x6d, 0x3e, 0x3e, 0x71, 0x75, 0xff, 0x86, 0x4a, 0x58,
 | 
				
			||||||
	0xc0, 0xc2, 0xb1, 0x2c, 0xe7, 0x13, 0x9f, 0xe1, 0x5a, 0x66, 0xae, 0x95, 0x9c, 0xb9, 0xe6, 0x62,
 | 
						0xdd, 0xda, 0x47, 0x84, 0x34, 0x8b, 0xea, 0x2b, 0xd8, 0x49, 0x1f, 0x4e, 0xca, 0xa1, 0xdc, 0xb2,
 | 
				
			||||||
	0xa9, 0xee, 0xf3, 0x29, 0x0e, 0x53, 0x0b, 0xb6, 0x31, 0x32, 0x57, 0xf0, 0x03, 0x0a, 0xf5, 0xe4,
 | 
						0x56, 0x0e, 0x0f, 0x54, 0x6f, 0xf9, 0x70, 0x9d, 0x3b, 0x57, 0x71, 0x3e, 0x6c, 0x13, 0x76, 0x5f,
 | 
				
			||||||
	0xd7, 0x50, 0x17, 0xbb, 0x7a, 0xd1, 0x3f, 0xd3, 0xf4, 0xe9, 0xfb, 0xb1, 0xa6, 0xbf, 0x1d, 0x9e,
 | 
						0x8f, 0x9f, 0x4d, 0x14, 0xc8, 0x48, 0xd9, 0xc5, 0x0e, 0xe1, 0x1c, 0x5b, 0xa6, 0xcd, 0xe7, 0xb8,
 | 
				
			||||||
	0x68, 0xa7, 0x83, 0xa1, 0x76, 0xd2, 0xbe, 0x85, 0x5a, 0xb2, 0x25, 0x79, 0xfa, 0xe3, 0xf1, 0x71,
 | 
						0xf0, 0x5c, 0x61, 0x07, 0x16, 0x8e, 0x65, 0x39, 0x9f, 0xf9, 0x0c, 0xd7, 0x32, 0x73, 0xad, 0xe4,
 | 
				
			||||||
	0xbb, 0x80, 0x2f, 0x4b, 0x47, 0x32, 0x9e, 0x8c, 0x8e, 0x5f, 0x6b, 0x93, 0x76, 0x11, 0x89, 0xb4,
 | 
						0xcc, 0x35, 0x17, 0x4b, 0x75, 0x9f, 0x4f, 0x71, 0x98, 0x5a, 0xb0, 0x8d, 0x91, 0xb9, 0x82, 0x1f,
 | 
				
			||||||
	0x24, 0xf3, 0xe8, 0x78, 0xd0, 0x2e, 0x1d, 0x8c, 0xa1, 0x16, 0xff, 0x28, 0xd8, 0x85, 0x6d, 0x04,
 | 
						0x50, 0xa8, 0x27, 0x1f, 0x5b, 0x5d, 0xec, 0xea, 0x45, 0xff, 0x4c, 0xd3, 0xa7, 0x1f, 0xc7, 0x9a,
 | 
				
			||||||
	0xd0, 0xdf, 0x4c, 0xfb, 0xd3, 0x74, 0x12, 0xc4, 0x4b, 0x1c, 0x93, 0xb7, 0xc3, 0xe1, 0x60, 0x78,
 | 
						0xfe, 0x7e, 0x78, 0xa2, 0x9d, 0x0e, 0x86, 0xda, 0x49, 0xfb, 0x0e, 0x6a, 0xc9, 0x96, 0xe4, 0xe9,
 | 
				
			||||||
	0x86, 0x69, 0x76, 0xa0, 0x9d, 0x98, 0xb5, 0x1f, 0x07, 0x53, 0x0c, 0x2e, 0x1e, 0xfc, 0x53, 0x80,
 | 
						0x8f, 0xc7, 0xc7, 0xed, 0x02, 0x3e, 0x35, 0x1d, 0xc9, 0x78, 0x32, 0x3a, 0x7e, 0xab, 0x4d, 0xda,
 | 
				
			||||||
	0x5a, 0xfc, 0x12, 0x22, 0xe4, 0x78, 0x74, 0x92, 0x03, 0x89, 0x67, 0x13, 0x87, 0x76, 0xf1, 0x6a,
 | 
						0x45, 0x24, 0xd2, 0x92, 0xcc, 0xa3, 0xe3, 0x41, 0xbb, 0x74, 0x30, 0x86, 0x5a, 0xfc, 0xcd, 0xb1,
 | 
				
			||||||
	0xf2, 0x7e, 0x84, 0x88, 0xa9, 0xf0, 0xf1, 0x44, 0x1b, 0xf7, 0x27, 0x2c, 0x55, 0x11, 0xc5, 0x99,
 | 
						0x0b, 0xdb, 0x08, 0xa0, 0xbf, 0x9b, 0xf6, 0xa7, 0xe9, 0x24, 0x88, 0x97, 0x38, 0x26, 0xef, 0x87,
 | 
				
			||||||
	0x64, 0x1d, 0x08, 0x53, 0x62, 0xcc, 0x12, 0x7b, 0xc4, 0xac, 0x8c, 0xd3, 0xb6, 0x97, 0x98, 0xfb,
 | 
						0xc3, 0xc1, 0xf0, 0x0c, 0xd3, 0xec, 0x40, 0x3b, 0x31, 0x6b, 0xdf, 0x0f, 0xa6, 0x18, 0x5c, 0x3c,
 | 
				
			||||||
	0xaf, 0x46, 0x13, 0xa4, 0x16, 0x1d, 0x6b, 0x2b, 0x99, 0xe4, 0x21, 0xf1, 0x4a, 0x3a, 0xc7, 0x89,
 | 
						0xf8, 0xab, 0x00, 0xb5, 0xf8, 0x69, 0x44, 0xc8, 0xf1, 0xe8, 0x24, 0x07, 0x12, 0xcf, 0x26, 0x0e,
 | 
				
			||||||
	0x76, 0xae, 0x4d, 0x19, 0x58, 0x35, 0x9d, 0xe3, 0xac, 0x3f, 0x79, 0x85, 0x2d, 0x6c, 0xd7, 0x0e,
 | 
						0xed, 0xe2, 0xcd, 0xe4, 0xe3, 0x08, 0x11, 0x53, 0xe1, 0xe3, 0x89, 0x36, 0xee, 0x4f, 0x58, 0xaa,
 | 
				
			||||||
	0xfe, 0x28, 0x42, 0x3d, 0x11, 0x3b, 0xbc, 0x21, 0xed, 0x9d, 0x36, 0x9c, 0xae, 0xdf, 0xd0, 0x3d,
 | 
						0x22, 0x8a, 0x33, 0xc9, 0x3a, 0x10, 0xa6, 0xc4, 0x98, 0x25, 0xf6, 0x88, 0x59, 0x19, 0xa7, 0x6d,
 | 
				
			||||||
	0xd8, 0x95, 0x3c, 0x0c, 0x29, 0xe6, 0x5f, 0xc0, 0x5f, 0x3b, 0x0f, 0xf3, 0x9d, 0x11, 0x6b, 0xac,
 | 
						0x2f, 0x31, 0xf7, 0xdf, 0x8c, 0x26, 0x48, 0x2d, 0x3a, 0xd6, 0x56, 0x32, 0xc9, 0x43, 0xe2, 0x95,
 | 
				
			||||||
	0xbd, 0x07, 0x77, 0x33, 0x31, 0x48, 0x85, 0xfb, 0x4a, 0x28, 0x17, 0x77, 0x32, 0x3e, 0x51, 0x4e,
 | 
						0x74, 0x8e, 0x13, 0xed, 0x5c, 0x9b, 0x32, 0xb0, 0x6a, 0x3a, 0xc7, 0x59, 0x7f, 0xf2, 0x06, 0x5b,
 | 
				
			||||||
	0x19, 0x77, 0x67, 0x3f, 0xe3, 0x12, 0xdc, 0xf5, 0xe3, 0xd1, 0xf9, 0xb9, 0x76, 0xcc, 0xa2, 0x94,
 | 
						0xd8, 0xae, 0x1d, 0xfc, 0x5e, 0x84, 0x7a, 0x22, 0x76, 0x78, 0x43, 0xda, 0x07, 0x6d, 0x38, 0x5d,
 | 
				
			||||||
	0x0c, 0xb8, 0xb8, 0xce, 0x49, 0xd8, 0x90, 0x34, 0x38, 0xf3, 0x09, 0xf0, 0x2a, 0x6b, 0xb0, 0xe4,
 | 
						0xbf, 0xa1, 0x07, 0xb0, 0x2b, 0x79, 0x18, 0x52, 0xcc, 0xbf, 0x80, 0x1f, 0x53, 0x8f, 0xf3, 0x9d,
 | 
				
			||||||
	0x0a, 0xa7, 0x6a, 0x70, 0x31, 0x0e, 0x29, 0xd7, 0xc8, 0x7d, 0xe8, 0xae, 0xb9, 0x27, 0xda, 0xc5,
 | 
						0x11, 0x6b, 0xac, 0xbd, 0x07, 0xf7, 0x33, 0x31, 0x48, 0x85, 0xfb, 0x4a, 0x28, 0x17, 0xf7, 0x32,
 | 
				
			||||||
	0xe8, 0x1d, 0x7a, 0xeb, 0x47, 0xbf, 0x94, 0xf1, 0xc7, 0xd5, 0xea, 0xd2, 0x32, 0x67, 0xfd, 0xf1,
 | 
						0x3e, 0x51, 0x4e, 0x19, 0x77, 0x67, 0x3f, 0xe3, 0x12, 0xdc, 0xf5, 0xe3, 0xd1, 0xf9, 0xb9, 0x76,
 | 
				
			||||||
	0x80, 0x7c, 0x0f, 0x55, 0x21, 0xe8, 0x64, 0x37, 0x79, 0xed, 0x52, 0xa2, 0xdf, 0xeb, 0xae, 0x3b,
 | 
						0xcc, 0xa2, 0x94, 0x0c, 0xb8, 0xb8, 0xce, 0x49, 0xd8, 0x90, 0x34, 0x38, 0xf3, 0x09, 0xf0, 0x2a,
 | 
				
			||||||
	0xc2, 0xad, 0x51, 0x6f, 0x91, 0x3e, 0xd4, 0x22, 0x61, 0x26, 0x49, 0x5c, 0x46, 0xf3, 0x7b, 0x7b,
 | 
						0x6b, 0xb0, 0xe4, 0x0a, 0xa7, 0x6a, 0x70, 0x31, 0x0e, 0x29, 0xd7, 0xc8, 0x43, 0xe8, 0xae, 0xb9,
 | 
				
			||||||
	0x39, 0x9e, 0x18, 0xe2, 0x0c, 0x20, 0x91, 0x62, 0xd2, 0x93, 0x1e, 0x90, 0x8c, 0x80, 0xf7, 0xee,
 | 
						0x27, 0xda, 0xc5, 0xe8, 0x03, 0x7a, 0xeb, 0x47, 0x3f, 0x95, 0xf1, 0x6b, 0x6b, 0x75, 0x69, 0x99,
 | 
				
			||||||
	0xe5, 0xfa, 0x64, 0xa0, 0x44, 0x56, 0x25, 0xa0, 0x35, 0xdd, 0x96, 0x80, 0xd6, 0x75, 0x18, 0x81,
 | 
						0xb3, 0xfe, 0x78, 0x40, 0xbe, 0x85, 0xaa, 0x10, 0x74, 0xb2, 0x9b, 0xbc, 0x76, 0x29, 0xd1, 0xef,
 | 
				
			||||||
	0x2e, 0xa0, 0x29, 0xcb, 0x28, 0xb9, 0x9f, 0xcd, 0x2b, 0x0b, 0x70, 0xef, 0xc1, 0x06, 0x6f, 0x0c,
 | 
						0x75, 0xd7, 0x1d, 0xe1, 0xd6, 0xa8, 0x77, 0x48, 0x1f, 0x6a, 0x91, 0x30, 0x93, 0x24, 0x2e, 0xa3,
 | 
				
			||||||
	0x37, 0x82, 0xa6, 0xac, 0x90, 0x12, 0x5c, 0x8e, 0xea, 0x4a, 0x70, 0x79, 0xb2, 0xaa, 0xde, 0xfa,
 | 
						0xf9, 0xbd, 0xbd, 0x1c, 0x4f, 0x0c, 0x71, 0x06, 0x90, 0x48, 0x31, 0xe9, 0x49, 0x0f, 0x48, 0x46,
 | 
				
			||||||
	0xba, 0x40, 0x5e, 0xf2, 0x4b, 0x63, 0xfa, 0x95, 0xbe, 0x34, 0x49, 0x4c, 0xd3, 0x97, 0x26, 0x4b,
 | 
						0xc0, 0x7b, 0x0f, 0x72, 0x7d, 0x32, 0x50, 0x22, 0xab, 0x12, 0xd0, 0x9a, 0x6e, 0x4b, 0x40, 0xeb,
 | 
				
			||||||
	0x1d, 0x43, 0xb8, 0xac, 0xf0, 0xff, 0x10, 0x9f, 0xfd, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xca, 0x1c,
 | 
						0x3a, 0x8c, 0x40, 0x17, 0xd0, 0x94, 0x65, 0x94, 0x3c, 0xcc, 0xe6, 0x95, 0x05, 0xb8, 0xf7, 0x68,
 | 
				
			||||||
	0xe0, 0x93, 0x2e, 0x0e, 0x00, 0x00,
 | 
						0x83, 0x37, 0x86, 0x1b, 0x41, 0x53, 0x56, 0x48, 0x09, 0x2e, 0x47, 0x75, 0x25, 0xb8, 0x3c, 0x59,
 | 
				
			||||||
 | 
						0x55, 0xef, 0xfc, 0xbf, 0x40, 0x5e, 0xf3, 0x4b, 0x63, 0xfa, 0x95, 0xbe, 0x34, 0x49, 0x4c, 0xd3,
 | 
				
			||||||
 | 
						0x97, 0x26, 0x4b, 0x1d, 0x43, 0xb8, 0xac, 0xf0, 0x7f, 0x40, 0x5f, 0xfc, 0x1d, 0x00, 0x00, 0xff,
 | 
				
			||||||
 | 
						0xff, 0x4d, 0xcd, 0xc6, 0xd5, 0x8d, 0x0e, 0x00, 0x00,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/api.proto
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								Godeps/_workspace/src/github.com/coreos/rkt/api/v1alpha/api.proto
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -12,9 +12,6 @@
 | 
				
			|||||||
// See the License for the specific language governing permissions and
 | 
					// See the License for the specific language governing permissions and
 | 
				
			||||||
// limitations under the License.
 | 
					// limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// To compile, run 'protoc -I api/v1alpha api/v1alpha/api.proto --go_out=plugins=grpc:api/v1alpha' in rkt root directory.
 | 
					 | 
				
			||||||
// The protoc version must be 3.0.0.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// *************************************************** //
 | 
					// *************************************************** //
 | 
				
			||||||
// ************ WARNING - HERE BE DRAGONS ************ //
 | 
					// ************ WARNING - HERE BE DRAGONS ************ //
 | 
				
			||||||
//                                                     //
 | 
					//                                                     //
 | 
				
			||||||
@@ -172,6 +169,22 @@ message Pod {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // Annotations on this pod.
 | 
					        // Annotations on this pod.
 | 
				
			||||||
        repeated KeyValue annotations = 7;
 | 
					        repeated KeyValue annotations = 7;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Cgroup of the pod, empty if the pod is not running.
 | 
				
			||||||
 | 
					        string cgroup = 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Timestamp of when the pod is created, nanoseconds since epoch.
 | 
				
			||||||
 | 
					        // Zero if the pod is not created.
 | 
				
			||||||
 | 
					        int64 created_at = 9;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Timestamp of when the pod is started, nanoseconds since epoch.
 | 
				
			||||||
 | 
					        // Zero if the pod is not started.
 | 
				
			||||||
 | 
					        int64 started_at = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Timestamp of when the pod is moved to exited-garbage/garbage,
 | 
				
			||||||
 | 
					        // in nanoseconds since epoch.
 | 
				
			||||||
 | 
					        // Zero if the pod is not moved to exited-garbage/garbage yet.
 | 
				
			||||||
 | 
					        int64 gc_marked_at = 11;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
message KeyValue {
 | 
					message KeyValue {
 | 
				
			||||||
@@ -201,6 +214,9 @@ message PodFilter {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        // If not empty, the pods that have all of the annotations will be returned.
 | 
					        // If not empty, the pods that have all of the annotations will be returned.
 | 
				
			||||||
        repeated KeyValue annotations = 6;
 | 
					        repeated KeyValue annotations = 6;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // If not empty, the pods whose cgroup are listed will be returned.
 | 
				
			||||||
 | 
					        repeated string cgroups = 7;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ImageFilter defines the condition that the returned images need to satisfy in ListImages().
 | 
					// ImageFilter defines the condition that the returned images need to satisfy in ListImages().
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										202
									
								
								Godeps/_workspace/src/github.com/golang/mock/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								Godeps/_workspace/src/github.com/golang/mock/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -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.
 | 
				
			||||||
							
								
								
									
										268
									
								
								Godeps/_workspace/src/github.com/golang/mock/gomock/call.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										268
									
								
								Godeps/_workspace/src/github.com/golang/mock/gomock/call.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,268 @@
 | 
				
			|||||||
 | 
					// Copyright 2010 Google 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 gomock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"reflect"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Call represents an expected call to a mock.
 | 
				
			||||||
 | 
					type Call struct {
 | 
				
			||||||
 | 
						t TestReporter // for triggering test failures on invalid call setup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						receiver interface{}   // the receiver of the method call
 | 
				
			||||||
 | 
						method   string        // the name of the method
 | 
				
			||||||
 | 
						args     []Matcher     // the args
 | 
				
			||||||
 | 
						rets     []interface{} // the return values (if any)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						preReqs []*Call // prerequisite calls
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Expectations
 | 
				
			||||||
 | 
						minCalls, maxCalls int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						numCalls int // actual number made
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Actions
 | 
				
			||||||
 | 
						doFunc  reflect.Value
 | 
				
			||||||
 | 
						setArgs map[int]reflect.Value
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AnyTimes allows the expectation to be called 0 or more times
 | 
				
			||||||
 | 
					func (c *Call) AnyTimes() *Call {
 | 
				
			||||||
 | 
						c.minCalls, c.maxCalls = 0, 1e8 // close enough to infinity
 | 
				
			||||||
 | 
						return c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MinTimes requires the call to occur at least n times. If AnyTimes or MaxTimes have not been called, MinTimes also
 | 
				
			||||||
 | 
					// sets the maximum number of calls to infinity.
 | 
				
			||||||
 | 
					func (c *Call) MinTimes(n int) *Call {
 | 
				
			||||||
 | 
						c.minCalls = n
 | 
				
			||||||
 | 
						if c.maxCalls == 1 {
 | 
				
			||||||
 | 
							c.maxCalls = 1e8
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MaxTimes limits the number of calls to n times. If AnyTimes or MinTimes have not been called, MaxTimes also
 | 
				
			||||||
 | 
					// sets the minimum number of calls to 0.
 | 
				
			||||||
 | 
					func (c *Call) MaxTimes(n int) *Call {
 | 
				
			||||||
 | 
						c.maxCalls = n
 | 
				
			||||||
 | 
						if c.minCalls == 1 {
 | 
				
			||||||
 | 
							c.minCalls = 0
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Do declares the action to run when the call is matched.
 | 
				
			||||||
 | 
					// It takes an interface{} argument to support n-arity functions.
 | 
				
			||||||
 | 
					func (c *Call) Do(f interface{}) *Call {
 | 
				
			||||||
 | 
						// TODO: Check arity and types here, rather than dying badly elsewhere.
 | 
				
			||||||
 | 
						c.doFunc = reflect.ValueOf(f)
 | 
				
			||||||
 | 
						return c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Call) Return(rets ...interface{}) *Call {
 | 
				
			||||||
 | 
						mt := c.methodType()
 | 
				
			||||||
 | 
						if len(rets) != mt.NumOut() {
 | 
				
			||||||
 | 
							c.t.Fatalf("wrong number of arguments to Return for %T.%v: got %d, want %d",
 | 
				
			||||||
 | 
								c.receiver, c.method, len(rets), mt.NumOut())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for i, ret := range rets {
 | 
				
			||||||
 | 
							if got, want := reflect.TypeOf(ret), mt.Out(i); got == want {
 | 
				
			||||||
 | 
								// Identical types; nothing to do.
 | 
				
			||||||
 | 
							} else if got == nil {
 | 
				
			||||||
 | 
								// Nil needs special handling.
 | 
				
			||||||
 | 
								switch want.Kind() {
 | 
				
			||||||
 | 
								case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
 | 
				
			||||||
 | 
									// ok
 | 
				
			||||||
 | 
								default:
 | 
				
			||||||
 | 
									c.t.Fatalf("argument %d to Return for %T.%v is nil, but %v is not nillable",
 | 
				
			||||||
 | 
										i, c.receiver, c.method, want)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else if got.AssignableTo(want) {
 | 
				
			||||||
 | 
								// Assignable type relation. Make the assignment now so that the generated code
 | 
				
			||||||
 | 
								// can return the values with a type assertion.
 | 
				
			||||||
 | 
								v := reflect.New(want).Elem()
 | 
				
			||||||
 | 
								v.Set(reflect.ValueOf(ret))
 | 
				
			||||||
 | 
								rets[i] = v.Interface()
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								c.t.Fatalf("wrong type of argument %d to Return for %T.%v: %v is not assignable to %v",
 | 
				
			||||||
 | 
									i, c.receiver, c.method, got, want)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c.rets = rets
 | 
				
			||||||
 | 
						return c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Call) Times(n int) *Call {
 | 
				
			||||||
 | 
						c.minCalls, c.maxCalls = n, n
 | 
				
			||||||
 | 
						return c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SetArg declares an action that will set the nth argument's value,
 | 
				
			||||||
 | 
					// indirected through a pointer.
 | 
				
			||||||
 | 
					func (c *Call) SetArg(n int, value interface{}) *Call {
 | 
				
			||||||
 | 
						if c.setArgs == nil {
 | 
				
			||||||
 | 
							c.setArgs = make(map[int]reflect.Value)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						mt := c.methodType()
 | 
				
			||||||
 | 
						// TODO: This will break on variadic methods.
 | 
				
			||||||
 | 
						// We will need to check those at invocation time.
 | 
				
			||||||
 | 
						if n < 0 || n >= mt.NumIn() {
 | 
				
			||||||
 | 
							c.t.Fatalf("SetArg(%d, ...) called for a method with %d args", n, mt.NumIn())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Permit setting argument through an interface.
 | 
				
			||||||
 | 
						// In the interface case, we don't (nay, can't) check the type here.
 | 
				
			||||||
 | 
						at := mt.In(n)
 | 
				
			||||||
 | 
						switch at.Kind() {
 | 
				
			||||||
 | 
						case reflect.Ptr:
 | 
				
			||||||
 | 
							dt := at.Elem()
 | 
				
			||||||
 | 
							if vt := reflect.TypeOf(value); !vt.AssignableTo(dt) {
 | 
				
			||||||
 | 
								c.t.Fatalf("SetArg(%d, ...) argument is a %v, not assignable to %v", n, vt, dt)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case reflect.Interface:
 | 
				
			||||||
 | 
							// nothing to do
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							c.t.Fatalf("SetArg(%d, ...) referring to argument of non-pointer non-interface type %v", n, at)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						c.setArgs[n] = reflect.ValueOf(value)
 | 
				
			||||||
 | 
						return c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// isPreReq returns true if other is a direct or indirect prerequisite to c.
 | 
				
			||||||
 | 
					func (c *Call) isPreReq(other *Call) bool {
 | 
				
			||||||
 | 
						for _, preReq := range c.preReqs {
 | 
				
			||||||
 | 
							if other == preReq || preReq.isPreReq(other) {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// After declares that the call may only match after preReq has been exhausted.
 | 
				
			||||||
 | 
					func (c *Call) After(preReq *Call) *Call {
 | 
				
			||||||
 | 
						if preReq.isPreReq(c) {
 | 
				
			||||||
 | 
							msg := fmt.Sprintf(
 | 
				
			||||||
 | 
								"Loop in call order: %v is a prerequisite to %v (possibly indirectly).",
 | 
				
			||||||
 | 
								c, preReq,
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
							panic(msg)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						c.preReqs = append(c.preReqs, preReq)
 | 
				
			||||||
 | 
						return c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Returns true iff the minimum number of calls have been made.
 | 
				
			||||||
 | 
					func (c *Call) satisfied() bool {
 | 
				
			||||||
 | 
						return c.numCalls >= c.minCalls
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Returns true iff the maximum number of calls have been made.
 | 
				
			||||||
 | 
					func (c *Call) exhausted() bool {
 | 
				
			||||||
 | 
						return c.numCalls >= c.maxCalls
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Call) String() string {
 | 
				
			||||||
 | 
						args := make([]string, len(c.args))
 | 
				
			||||||
 | 
						for i, arg := range c.args {
 | 
				
			||||||
 | 
							args[i] = arg.String()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						arguments := strings.Join(args, ", ")
 | 
				
			||||||
 | 
						return fmt.Sprintf("%T.%v(%s)", c.receiver, c.method, arguments)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Tests if the given call matches the expected call.
 | 
				
			||||||
 | 
					func (c *Call) matches(args []interface{}) bool {
 | 
				
			||||||
 | 
						if len(args) != len(c.args) {
 | 
				
			||||||
 | 
							return false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for i, m := range c.args {
 | 
				
			||||||
 | 
							if !m.Matches(args[i]) {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check that all prerequisite calls have been satisfied.
 | 
				
			||||||
 | 
						for _, preReqCall := range c.preReqs {
 | 
				
			||||||
 | 
							if !preReqCall.satisfied() {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// dropPrereqs tells the expected Call to not re-check prerequite calls any
 | 
				
			||||||
 | 
					// longer, and to return its current set.
 | 
				
			||||||
 | 
					func (c *Call) dropPrereqs() (preReqs []*Call) {
 | 
				
			||||||
 | 
						preReqs = c.preReqs
 | 
				
			||||||
 | 
						c.preReqs = nil
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Call) call(args []interface{}) (rets []interface{}, action func()) {
 | 
				
			||||||
 | 
						c.numCalls++
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Actions
 | 
				
			||||||
 | 
						if c.doFunc.IsValid() {
 | 
				
			||||||
 | 
							doArgs := make([]reflect.Value, len(args))
 | 
				
			||||||
 | 
							ft := c.doFunc.Type()
 | 
				
			||||||
 | 
							for i := 0; i < ft.NumIn(); i++ {
 | 
				
			||||||
 | 
								if args[i] != nil {
 | 
				
			||||||
 | 
									doArgs[i] = reflect.ValueOf(args[i])
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									// Use the zero value for the arg.
 | 
				
			||||||
 | 
									doArgs[i] = reflect.Zero(ft.In(i))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							action = func() { c.doFunc.Call(doArgs) }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for n, v := range c.setArgs {
 | 
				
			||||||
 | 
							reflect.ValueOf(args[n]).Elem().Set(v)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rets = c.rets
 | 
				
			||||||
 | 
						if rets == nil {
 | 
				
			||||||
 | 
							// Synthesize the zero value for each of the return args' types.
 | 
				
			||||||
 | 
							mt := c.methodType()
 | 
				
			||||||
 | 
							rets = make([]interface{}, mt.NumOut())
 | 
				
			||||||
 | 
							for i := 0; i < mt.NumOut(); i++ {
 | 
				
			||||||
 | 
								rets[i] = reflect.Zero(mt.Out(i)).Interface()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *Call) methodType() reflect.Type {
 | 
				
			||||||
 | 
						recv := reflect.ValueOf(c.receiver)
 | 
				
			||||||
 | 
						for i := 0; i < recv.Type().NumMethod(); i++ {
 | 
				
			||||||
 | 
							if recv.Type().Method(i).Name == c.method {
 | 
				
			||||||
 | 
								return recv.Method(i).Type()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						panic(fmt.Sprintf("gomock: failed finding method %s on %T", c.method, c.receiver))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// InOrder declares that the given calls should occur in order.
 | 
				
			||||||
 | 
					func InOrder(calls ...*Call) {
 | 
				
			||||||
 | 
						for i := 1; i < len(calls); i++ {
 | 
				
			||||||
 | 
							calls[i].After(calls[i-1])
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										76
									
								
								Godeps/_workspace/src/github.com/golang/mock/gomock/callset.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								Godeps/_workspace/src/github.com/golang/mock/gomock/callset.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
				
			|||||||
 | 
					// Copyright 2011 Google 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 gomock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// callSet represents a set of expected calls, indexed by receiver and method
 | 
				
			||||||
 | 
					// name.
 | 
				
			||||||
 | 
					type callSet map[interface{}]map[string][]*Call
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Add adds a new expected call.
 | 
				
			||||||
 | 
					func (cs callSet) Add(call *Call) {
 | 
				
			||||||
 | 
						methodMap, ok := cs[call.receiver]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							methodMap = make(map[string][]*Call)
 | 
				
			||||||
 | 
							cs[call.receiver] = methodMap
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						methodMap[call.method] = append(methodMap[call.method], call)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Remove removes an expected call.
 | 
				
			||||||
 | 
					func (cs callSet) Remove(call *Call) {
 | 
				
			||||||
 | 
						methodMap, ok := cs[call.receiver]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sl := methodMap[call.method]
 | 
				
			||||||
 | 
						for i, c := range sl {
 | 
				
			||||||
 | 
							if c == call {
 | 
				
			||||||
 | 
								// quick removal; we don't need to maintain call order
 | 
				
			||||||
 | 
								if len(sl) > 1 {
 | 
				
			||||||
 | 
									sl[i] = sl[len(sl)-1]
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								methodMap[call.method] = sl[:len(sl)-1]
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FindMatch searches for a matching call. Returns nil if no call matched.
 | 
				
			||||||
 | 
					func (cs callSet) FindMatch(receiver interface{}, method string, args []interface{}) *Call {
 | 
				
			||||||
 | 
						methodMap, ok := cs[receiver]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						calls, ok := methodMap[method]
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Search through the unordered set of calls expected on a method on a
 | 
				
			||||||
 | 
						// receiver.
 | 
				
			||||||
 | 
						for _, call := range calls {
 | 
				
			||||||
 | 
							// A call should not normally still be here if exhausted,
 | 
				
			||||||
 | 
							// but it can happen if, for instance, .Times(0) was used.
 | 
				
			||||||
 | 
							// Pretend the call doesn't match.
 | 
				
			||||||
 | 
							if call.exhausted() {
 | 
				
			||||||
 | 
								continue
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if call.matches(args) {
 | 
				
			||||||
 | 
								return call
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										167
									
								
								Godeps/_workspace/src/github.com/golang/mock/gomock/controller.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								Godeps/_workspace/src/github.com/golang/mock/gomock/controller.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,167 @@
 | 
				
			|||||||
 | 
					// Copyright 2010 Google 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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GoMock - a mock framework for Go.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Standard usage:
 | 
				
			||||||
 | 
					//   (1) Define an interface that you wish to mock.
 | 
				
			||||||
 | 
					//         type MyInterface interface {
 | 
				
			||||||
 | 
					//           SomeMethod(x int64, y string)
 | 
				
			||||||
 | 
					//         }
 | 
				
			||||||
 | 
					//   (2) Use mockgen to generate a mock from the interface.
 | 
				
			||||||
 | 
					//   (3) Use the mock in a test:
 | 
				
			||||||
 | 
					//         func TestMyThing(t *testing.T) {
 | 
				
			||||||
 | 
					//           mockCtrl := gomock.NewController(t)
 | 
				
			||||||
 | 
					//           defer mockCtrl.Finish()
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//           mockObj := something.NewMockMyInterface(mockCtrl)
 | 
				
			||||||
 | 
					//           mockObj.EXPECT().SomeMethod(4, "blah")
 | 
				
			||||||
 | 
					//           // pass mockObj to a real object and play with it.
 | 
				
			||||||
 | 
					//         }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// By default, expected calls are not enforced to run in any particular order.
 | 
				
			||||||
 | 
					// Call order dependency can be enforced by use of InOrder and/or Call.After.
 | 
				
			||||||
 | 
					// Call.After can create more varied call order dependencies, but InOrder is
 | 
				
			||||||
 | 
					// often more convenient.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The following examples create equivalent call order dependencies.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Example of using Call.After to chain expected call order:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     firstCall := mockObj.EXPECT().SomeMethod(1, "first")
 | 
				
			||||||
 | 
					//     secondCall := mockObj.EXPECT().SomeMethod(2, "second").After(firstCall)
 | 
				
			||||||
 | 
					//     mockObj.EXPECT().SomeMethod(3, "third").After(secondCall)
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Example of using InOrder to declare expected call order:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     gomock.InOrder(
 | 
				
			||||||
 | 
					//         mockObj.EXPECT().SomeMethod(1, "first"),
 | 
				
			||||||
 | 
					//         mockObj.EXPECT().SomeMethod(2, "second"),
 | 
				
			||||||
 | 
					//         mockObj.EXPECT().SomeMethod(3, "third"),
 | 
				
			||||||
 | 
					//     )
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// TODO:
 | 
				
			||||||
 | 
					//	- Handle different argument/return types (e.g. ..., chan, map, interface).
 | 
				
			||||||
 | 
					package gomock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A TestReporter is something that can be used to report test failures.
 | 
				
			||||||
 | 
					// It is satisfied by the standard library's *testing.T.
 | 
				
			||||||
 | 
					type TestReporter interface {
 | 
				
			||||||
 | 
						Errorf(format string, args ...interface{})
 | 
				
			||||||
 | 
						Fatalf(format string, args ...interface{})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A Controller represents the top-level control of a mock ecosystem.
 | 
				
			||||||
 | 
					// It defines the scope and lifetime of mock objects, as well as their expectations.
 | 
				
			||||||
 | 
					// It is safe to call Controller's methods from multiple goroutines.
 | 
				
			||||||
 | 
					type Controller struct {
 | 
				
			||||||
 | 
						mu            sync.Mutex
 | 
				
			||||||
 | 
						t             TestReporter
 | 
				
			||||||
 | 
						expectedCalls callSet
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewController(t TestReporter) *Controller {
 | 
				
			||||||
 | 
						return &Controller{
 | 
				
			||||||
 | 
							t:             t,
 | 
				
			||||||
 | 
							expectedCalls: make(callSet),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...interface{}) *Call {
 | 
				
			||||||
 | 
						// TODO: check arity, types.
 | 
				
			||||||
 | 
						margs := make([]Matcher, len(args))
 | 
				
			||||||
 | 
						for i, arg := range args {
 | 
				
			||||||
 | 
							if m, ok := arg.(Matcher); ok {
 | 
				
			||||||
 | 
								margs[i] = m
 | 
				
			||||||
 | 
							} else if arg == nil {
 | 
				
			||||||
 | 
								// Handle nil specially so that passing a nil interface value
 | 
				
			||||||
 | 
								// will match the typed nils of concrete args.
 | 
				
			||||||
 | 
								margs[i] = Nil()
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								margs[i] = Eq(arg)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctrl.mu.Lock()
 | 
				
			||||||
 | 
						defer ctrl.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						call := &Call{t: ctrl.t, receiver: receiver, method: method, args: margs, minCalls: 1, maxCalls: 1}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctrl.expectedCalls.Add(call)
 | 
				
			||||||
 | 
						return call
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ctrl *Controller) Call(receiver interface{}, method string, args ...interface{}) []interface{} {
 | 
				
			||||||
 | 
						ctrl.mu.Lock()
 | 
				
			||||||
 | 
						defer ctrl.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expected := ctrl.expectedCalls.FindMatch(receiver, method, args)
 | 
				
			||||||
 | 
						if expected == nil {
 | 
				
			||||||
 | 
							ctrl.t.Fatalf("no matching expected call: %T.%v(%v)", receiver, method, args)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Two things happen here:
 | 
				
			||||||
 | 
						// * the matching call no longer needs to check prerequite calls,
 | 
				
			||||||
 | 
						// * and the prerequite calls are no longer expected, so remove them.
 | 
				
			||||||
 | 
						preReqCalls := expected.dropPrereqs()
 | 
				
			||||||
 | 
						for _, preReqCall := range preReqCalls {
 | 
				
			||||||
 | 
							ctrl.expectedCalls.Remove(preReqCall)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rets, action := expected.call(args)
 | 
				
			||||||
 | 
						if expected.exhausted() {
 | 
				
			||||||
 | 
							ctrl.expectedCalls.Remove(expected)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Don't hold the lock while doing the call's action (if any)
 | 
				
			||||||
 | 
						// so that actions may execute concurrently.
 | 
				
			||||||
 | 
						// We use the deferred Unlock to capture any panics that happen above;
 | 
				
			||||||
 | 
						// here we add a deferred Lock to balance it.
 | 
				
			||||||
 | 
						ctrl.mu.Unlock()
 | 
				
			||||||
 | 
						defer ctrl.mu.Lock()
 | 
				
			||||||
 | 
						if action != nil {
 | 
				
			||||||
 | 
							action()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return rets
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ctrl *Controller) Finish() {
 | 
				
			||||||
 | 
						ctrl.mu.Lock()
 | 
				
			||||||
 | 
						defer ctrl.mu.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// If we're currently panicking, probably because this is a deferred call,
 | 
				
			||||||
 | 
						// pass through the panic.
 | 
				
			||||||
 | 
						if err := recover(); err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check that all remaining expected calls are satisfied.
 | 
				
			||||||
 | 
						failures := false
 | 
				
			||||||
 | 
						for _, methodMap := range ctrl.expectedCalls {
 | 
				
			||||||
 | 
							for _, calls := range methodMap {
 | 
				
			||||||
 | 
								for _, call := range calls {
 | 
				
			||||||
 | 
									if !call.satisfied() {
 | 
				
			||||||
 | 
										ctrl.t.Errorf("missing call(s) to %v", call)
 | 
				
			||||||
 | 
										failures = true
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if failures {
 | 
				
			||||||
 | 
							ctrl.t.Fatalf("aborting test due to missing call(s)")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										97
									
								
								Godeps/_workspace/src/github.com/golang/mock/gomock/matchers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								Godeps/_workspace/src/github.com/golang/mock/gomock/matchers.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
				
			|||||||
 | 
					// Copyright 2010 Google 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 gomock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"reflect"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A Matcher is a representation of a class of values.
 | 
				
			||||||
 | 
					// It is used to represent the valid or expected arguments to a mocked method.
 | 
				
			||||||
 | 
					type Matcher interface {
 | 
				
			||||||
 | 
						// Matches returns whether y is a match.
 | 
				
			||||||
 | 
						Matches(x interface{}) bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// String describes what the matcher matches.
 | 
				
			||||||
 | 
						String() string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type anyMatcher struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (anyMatcher) Matches(x interface{}) bool {
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (anyMatcher) String() string {
 | 
				
			||||||
 | 
						return "is anything"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type eqMatcher struct {
 | 
				
			||||||
 | 
						x interface{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e eqMatcher) Matches(x interface{}) bool {
 | 
				
			||||||
 | 
						return reflect.DeepEqual(e.x, x)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e eqMatcher) String() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("is equal to %v", e.x)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type nilMatcher struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (nilMatcher) Matches(x interface{}) bool {
 | 
				
			||||||
 | 
						if x == nil {
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						v := reflect.ValueOf(x)
 | 
				
			||||||
 | 
						switch v.Kind() {
 | 
				
			||||||
 | 
						case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map,
 | 
				
			||||||
 | 
							reflect.Ptr, reflect.Slice:
 | 
				
			||||||
 | 
							return v.IsNil()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (nilMatcher) String() string {
 | 
				
			||||||
 | 
						return "is nil"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type notMatcher struct {
 | 
				
			||||||
 | 
						m Matcher
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (n notMatcher) Matches(x interface{}) bool {
 | 
				
			||||||
 | 
						return !n.m.Matches(x)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (n notMatcher) String() string {
 | 
				
			||||||
 | 
						// TODO: Improve this if we add a NotString method to the Matcher interface.
 | 
				
			||||||
 | 
						return "not(" + n.m.String() + ")"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Constructors
 | 
				
			||||||
 | 
					func Any() Matcher             { return anyMatcher{} }
 | 
				
			||||||
 | 
					func Eq(x interface{}) Matcher { return eqMatcher{x} }
 | 
				
			||||||
 | 
					func Nil() Matcher             { return nilMatcher{} }
 | 
				
			||||||
 | 
					func Not(x interface{}) Matcher {
 | 
				
			||||||
 | 
						if m, ok := x.(Matcher); ok {
 | 
				
			||||||
 | 
							return notMatcher{m}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return notMatcher{Eq(x)}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										49
									
								
								Godeps/_workspace/src/github.com/golang/mock/gomock/mock_matcher/mock_matcher.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								Godeps/_workspace/src/github.com/golang/mock/gomock/mock_matcher/mock_matcher.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					// Automatically generated by MockGen. DO NOT EDIT!
 | 
				
			||||||
 | 
					// Source: github.com/golang/mock/gomock (interfaces: Matcher)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package mock_gomock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						gomock "github.com/golang/mock/gomock"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Mock of Matcher interface
 | 
				
			||||||
 | 
					type MockMatcher struct {
 | 
				
			||||||
 | 
						ctrl     *gomock.Controller
 | 
				
			||||||
 | 
						recorder *_MockMatcherRecorder
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Recorder for MockMatcher (not exported)
 | 
				
			||||||
 | 
					type _MockMatcherRecorder struct {
 | 
				
			||||||
 | 
						mock *MockMatcher
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewMockMatcher(ctrl *gomock.Controller) *MockMatcher {
 | 
				
			||||||
 | 
						mock := &MockMatcher{ctrl: ctrl}
 | 
				
			||||||
 | 
						mock.recorder = &_MockMatcherRecorder{mock}
 | 
				
			||||||
 | 
						return mock
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_m *MockMatcher) EXPECT() *_MockMatcherRecorder {
 | 
				
			||||||
 | 
						return _m.recorder
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_m *MockMatcher) Matches(_param0 interface{}) bool {
 | 
				
			||||||
 | 
						ret := _m.ctrl.Call(_m, "Matches", _param0)
 | 
				
			||||||
 | 
						ret0, _ := ret[0].(bool)
 | 
				
			||||||
 | 
						return ret0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_mr *_MockMatcherRecorder) Matches(arg0 interface{}) *gomock.Call {
 | 
				
			||||||
 | 
						return _mr.mock.ctrl.RecordCall(_mr.mock, "Matches", arg0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_m *MockMatcher) String() string {
 | 
				
			||||||
 | 
						ret := _m.ctrl.Call(_m, "String")
 | 
				
			||||||
 | 
						ret0, _ := ret[0].(string)
 | 
				
			||||||
 | 
						return ret0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_mr *_MockMatcherRecorder) String() *gomock.Call {
 | 
				
			||||||
 | 
						return _mr.mock.ctrl.RecordCall(_mr.mock, "String")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -25,6 +25,7 @@ import (
 | 
				
			|||||||
	"k8s.io/kubernetes/pkg/client/record"
 | 
						"k8s.io/kubernetes/pkg/client/record"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/kubelet/util/format"
 | 
						"k8s.io/kubernetes/pkg/kubelet/util/format"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/runtime"
 | 
						"k8s.io/kubernetes/pkg/runtime"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/types"
 | 
				
			||||||
	hashutil "k8s.io/kubernetes/pkg/util/hash"
 | 
						hashutil "k8s.io/kubernetes/pkg/util/hash"
 | 
				
			||||||
	"k8s.io/kubernetes/third_party/golang/expansion"
 | 
						"k8s.io/kubernetes/third_party/golang/expansion"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,6 +43,7 @@ type RuntimeHelper interface {
 | 
				
			|||||||
	GenerateRunContainerOptions(pod *api.Pod, container *api.Container, podIP string) (*RunContainerOptions, error)
 | 
						GenerateRunContainerOptions(pod *api.Pod, container *api.Container, podIP string) (*RunContainerOptions, error)
 | 
				
			||||||
	GetClusterDNS(pod *api.Pod) (dnsServers []string, dnsSearches []string, err error)
 | 
						GetClusterDNS(pod *api.Pod) (dnsServers []string, dnsSearches []string, err error)
 | 
				
			||||||
	GeneratePodHostNameAndDomain(pod *api.Pod) (hostname string, hostDomain string)
 | 
						GeneratePodHostNameAndDomain(pod *api.Pod) (hostname string, hostDomain string)
 | 
				
			||||||
 | 
						GetPodDir(podUID types.UID) string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ShouldContainerBeRestarted checks whether a container needs to be restarted.
 | 
					// ShouldContainerBeRestarted checks whether a container needs to be restarted.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,6 +25,7 @@ import (
 | 
				
			|||||||
type OSInterface interface {
 | 
					type OSInterface interface {
 | 
				
			||||||
	Mkdir(path string, perm os.FileMode) error
 | 
						Mkdir(path string, perm os.FileMode) error
 | 
				
			||||||
	Symlink(oldname string, newname string) error
 | 
						Symlink(oldname string, newname string) error
 | 
				
			||||||
 | 
						Stat(path string) (os.FileInfo, error)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// RealOS is used to dispatch the real system level operaitons.
 | 
					// RealOS is used to dispatch the real system level operaitons.
 | 
				
			||||||
@@ -39,3 +40,8 @@ func (RealOS) Mkdir(path string, perm os.FileMode) error {
 | 
				
			|||||||
func (RealOS) Symlink(oldname string, newname string) error {
 | 
					func (RealOS) Symlink(oldname string, newname string) error {
 | 
				
			||||||
	return os.Symlink(oldname, newname)
 | 
						return os.Symlink(oldname, newname)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Stat will call os.Stat to get the FileInfo for a given path
 | 
				
			||||||
 | 
					func (RealOS) Stat(path string) (os.FileInfo, error) {
 | 
				
			||||||
 | 
						return os.Stat(path)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,12 +17,17 @@ limitations under the License.
 | 
				
			|||||||
package testing
 | 
					package testing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// FakeOS mocks out certain OS calls to avoid perturbing the filesystem
 | 
					// FakeOS mocks out certain OS calls to avoid perturbing the filesystem
 | 
				
			||||||
// on the test machine.
 | 
					// on the test machine.
 | 
				
			||||||
type FakeOS struct{}
 | 
					// If a member of the form `*Fn` is set, that function will be called in place
 | 
				
			||||||
 | 
					// of the real call.
 | 
				
			||||||
 | 
					type FakeOS struct {
 | 
				
			||||||
 | 
						StatFn func(string) (os.FileInfo, error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Mkdir is a fake call that just returns nil.
 | 
					// Mkdir is a fake call that just returns nil.
 | 
				
			||||||
func (FakeOS) Mkdir(path string, perm os.FileMode) error {
 | 
					func (FakeOS) Mkdir(path string, perm os.FileMode) error {
 | 
				
			||||||
@@ -33,3 +38,11 @@ func (FakeOS) Mkdir(path string, perm os.FileMode) error {
 | 
				
			|||||||
func (FakeOS) Symlink(oldname string, newname string) error {
 | 
					func (FakeOS) Symlink(oldname string, newname string) error {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Stat is a fake that returns an error
 | 
				
			||||||
 | 
					func (f FakeOS) Stat(path string) (os.FileInfo, error) {
 | 
				
			||||||
 | 
						if f.StatFn != nil {
 | 
				
			||||||
 | 
							return f.StatFn(path)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil, errors.New("unimplemented testing mock")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -93,6 +93,10 @@ func (f *fakeRuntimeHelper) GeneratePodHostNameAndDomain(pod *api.Pod) (string,
 | 
				
			|||||||
	return "", ""
 | 
						return "", ""
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (f *fakeRuntimeHelper) GetPodDir(types.UID) string {
 | 
				
			||||||
 | 
						return ""
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func createTestDockerManager(fakeHTTPClient *fakeHTTP, fakeDocker *FakeDockerClient) (*DockerManager, *FakeDockerClient) {
 | 
					func createTestDockerManager(fakeHTTPClient *fakeHTTP, fakeDocker *FakeDockerClient) (*DockerManager, *FakeDockerClient) {
 | 
				
			||||||
	if fakeHTTPClient == nil {
 | 
						if fakeHTTPClient == nil {
 | 
				
			||||||
		fakeHTTPClient = &fakeHTTP{}
 | 
							fakeHTTPClient = &fakeHTTP{}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -72,6 +72,7 @@ import (
 | 
				
			|||||||
	"k8s.io/kubernetes/pkg/util/atomic"
 | 
						"k8s.io/kubernetes/pkg/util/atomic"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/util/bandwidth"
 | 
						"k8s.io/kubernetes/pkg/util/bandwidth"
 | 
				
			||||||
	utilerrors "k8s.io/kubernetes/pkg/util/errors"
 | 
						utilerrors "k8s.io/kubernetes/pkg/util/errors"
 | 
				
			||||||
 | 
						utilexec "k8s.io/kubernetes/pkg/util/exec"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/util/flowcontrol"
 | 
						"k8s.io/kubernetes/pkg/util/flowcontrol"
 | 
				
			||||||
	kubeio "k8s.io/kubernetes/pkg/util/io"
 | 
						kubeio "k8s.io/kubernetes/pkg/util/io"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/util/mount"
 | 
						"k8s.io/kubernetes/pkg/util/mount"
 | 
				
			||||||
@@ -426,6 +427,8 @@ func NewMainKubelet(
 | 
				
			|||||||
			klet.livenessManager,
 | 
								klet.livenessManager,
 | 
				
			||||||
			klet.volumeManager,
 | 
								klet.volumeManager,
 | 
				
			||||||
			klet.httpClient,
 | 
								klet.httpClient,
 | 
				
			||||||
 | 
								utilexec.New(),
 | 
				
			||||||
 | 
								kubecontainer.RealOS{},
 | 
				
			||||||
			imageBackOff,
 | 
								imageBackOff,
 | 
				
			||||||
			serializeImagePulls,
 | 
								serializeImagePulls,
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
@@ -830,8 +833,12 @@ func (kl *Kubelet) getPluginDir(pluginName string) string {
 | 
				
			|||||||
	return path.Join(kl.getPluginsDir(), pluginName)
 | 
						return path.Join(kl.getPluginsDir(), pluginName)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// getPodDir returns the full path to the per-pod data directory for the
 | 
					// GetPodDir returns the full path to the per-pod data directory for the
 | 
				
			||||||
// specified pod.  This directory may not exist if the pod does not exist.
 | 
					// specified pod. This directory may not exist if the pod does not exist.
 | 
				
			||||||
 | 
					func (kl *Kubelet) GetPodDir(podUID types.UID) string {
 | 
				
			||||||
 | 
						return kl.getPodDir(podUID)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (kl *Kubelet) getPodDir(podUID types.UID) string {
 | 
					func (kl *Kubelet) getPodDir(podUID types.UID) string {
 | 
				
			||||||
	// Backwards compat.  The "old" stuff should be removed before 1.0
 | 
						// Backwards compat.  The "old" stuff should be removed before 1.0
 | 
				
			||||||
	// release.  The thinking here is this:
 | 
						// release.  The thinking here is this:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,7 @@ import (
 | 
				
			|||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api"
 | 
						"k8s.io/kubernetes/pkg/api"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/types"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/coreos/go-systemd/dbus"
 | 
						"github.com/coreos/go-systemd/dbus"
 | 
				
			||||||
	rktapi "github.com/coreos/rkt/api/v1alpha"
 | 
						rktapi "github.com/coreos/rkt/api/v1alpha"
 | 
				
			||||||
@@ -166,3 +167,7 @@ func (f *fakeRuntimeHelper) GetClusterDNS(pod *api.Pod) ([]string, []string, err
 | 
				
			|||||||
func (f *fakeRuntimeHelper) GeneratePodHostNameAndDomain(pod *api.Pod) (string, string) {
 | 
					func (f *fakeRuntimeHelper) GeneratePodHostNameAndDomain(pod *api.Pod) (string, string) {
 | 
				
			||||||
	return f.hostName, f.hostDomain
 | 
						return f.hostName, f.hostDomain
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (f *fakeRuntimeHelper) GetPodDir(podUID types.UID) string {
 | 
				
			||||||
 | 
						return "/poddir/" + string(podUID)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										109
									
								
								pkg/kubelet/rkt/mock_os/mockfileinfo.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								pkg/kubelet/rkt/mock_os/mockfileinfo.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					Copyright 2016 The Kubernetes Authors All rights reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Generated via: mockgen os FileInfo
 | 
				
			||||||
 | 
					// Edited to include required boilerplate
 | 
				
			||||||
 | 
					// Source: os (interfaces: FileInfo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package mock_os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						os "os"
 | 
				
			||||||
 | 
						time "time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						gomock "github.com/golang/mock/gomock"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Mock of FileInfo interface
 | 
				
			||||||
 | 
					type MockFileInfo struct {
 | 
				
			||||||
 | 
						ctrl     *gomock.Controller
 | 
				
			||||||
 | 
						recorder *_MockFileInfoRecorder
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Recorder for MockFileInfo (not exported)
 | 
				
			||||||
 | 
					type _MockFileInfoRecorder struct {
 | 
				
			||||||
 | 
						mock *MockFileInfo
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewMockFileInfo(ctrl *gomock.Controller) *MockFileInfo {
 | 
				
			||||||
 | 
						mock := &MockFileInfo{ctrl: ctrl}
 | 
				
			||||||
 | 
						mock.recorder = &_MockFileInfoRecorder{mock}
 | 
				
			||||||
 | 
						return mock
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_m *MockFileInfo) EXPECT() *_MockFileInfoRecorder {
 | 
				
			||||||
 | 
						return _m.recorder
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_m *MockFileInfo) IsDir() bool {
 | 
				
			||||||
 | 
						ret := _m.ctrl.Call(_m, "IsDir")
 | 
				
			||||||
 | 
						ret0, _ := ret[0].(bool)
 | 
				
			||||||
 | 
						return ret0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_mr *_MockFileInfoRecorder) IsDir() *gomock.Call {
 | 
				
			||||||
 | 
						return _mr.mock.ctrl.RecordCall(_mr.mock, "IsDir")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_m *MockFileInfo) ModTime() time.Time {
 | 
				
			||||||
 | 
						ret := _m.ctrl.Call(_m, "ModTime")
 | 
				
			||||||
 | 
						ret0, _ := ret[0].(time.Time)
 | 
				
			||||||
 | 
						return ret0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_mr *_MockFileInfoRecorder) ModTime() *gomock.Call {
 | 
				
			||||||
 | 
						return _mr.mock.ctrl.RecordCall(_mr.mock, "ModTime")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_m *MockFileInfo) Mode() os.FileMode {
 | 
				
			||||||
 | 
						ret := _m.ctrl.Call(_m, "Mode")
 | 
				
			||||||
 | 
						ret0, _ := ret[0].(os.FileMode)
 | 
				
			||||||
 | 
						return ret0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_mr *_MockFileInfoRecorder) Mode() *gomock.Call {
 | 
				
			||||||
 | 
						return _mr.mock.ctrl.RecordCall(_mr.mock, "Mode")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_m *MockFileInfo) Name() string {
 | 
				
			||||||
 | 
						ret := _m.ctrl.Call(_m, "Name")
 | 
				
			||||||
 | 
						ret0, _ := ret[0].(string)
 | 
				
			||||||
 | 
						return ret0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_mr *_MockFileInfoRecorder) Name() *gomock.Call {
 | 
				
			||||||
 | 
						return _mr.mock.ctrl.RecordCall(_mr.mock, "Name")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_m *MockFileInfo) Size() int64 {
 | 
				
			||||||
 | 
						ret := _m.ctrl.Call(_m, "Size")
 | 
				
			||||||
 | 
						ret0, _ := ret[0].(int64)
 | 
				
			||||||
 | 
						return ret0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_mr *_MockFileInfoRecorder) Size() *gomock.Call {
 | 
				
			||||||
 | 
						return _mr.mock.ctrl.RecordCall(_mr.mock, "Size")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_m *MockFileInfo) Sys() interface{} {
 | 
				
			||||||
 | 
						ret := _m.ctrl.Call(_m, "Sys")
 | 
				
			||||||
 | 
						ret0, _ := ret[0].(interface{})
 | 
				
			||||||
 | 
						return ret0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (_mr *_MockFileInfoRecorder) Sys() *gomock.Call {
 | 
				
			||||||
 | 
						return _mr.mock.ctrl.RecordCall(_mr.mock, "Sys")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -25,6 +25,7 @@ import (
 | 
				
			|||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"os/exec"
 | 
						"os/exec"
 | 
				
			||||||
	"path"
 | 
						"path"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
@@ -76,13 +77,11 @@ const (
 | 
				
			|||||||
	unitRktID             = "RktID"
 | 
						unitRktID             = "RktID"
 | 
				
			||||||
	unitRestartCount      = "RestartCount"
 | 
						unitRestartCount      = "RestartCount"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	k8sRktKubeletAnno      = "rkt.kubernetes.io/managed-by-kubelet"
 | 
						k8sRktKubeletAnno                = "rkt.kubernetes.io/managed-by-kubelet"
 | 
				
			||||||
	k8sRktKubeletAnnoValue = "true"
 | 
						k8sRktKubeletAnnoValue           = "true"
 | 
				
			||||||
	k8sRktUIDAnno          = "rkt.kubernetes.io/uid"
 | 
						k8sRktUIDAnno                    = "rkt.kubernetes.io/uid"
 | 
				
			||||||
	k8sRktNameAnno         = "rkt.kubernetes.io/name"
 | 
						k8sRktNameAnno                   = "rkt.kubernetes.io/name"
 | 
				
			||||||
	k8sRktNamespaceAnno    = "rkt.kubernetes.io/namespace"
 | 
						k8sRktNamespaceAnno              = "rkt.kubernetes.io/namespace"
 | 
				
			||||||
	//TODO: remove the creation time annotation once this is closed: https://github.com/coreos/rkt/issues/1789
 | 
					 | 
				
			||||||
	k8sRktCreationTimeAnno           = "rkt.kubernetes.io/created"
 | 
					 | 
				
			||||||
	k8sRktContainerHashAnno          = "rkt.kubernetes.io/container-hash"
 | 
						k8sRktContainerHashAnno          = "rkt.kubernetes.io/container-hash"
 | 
				
			||||||
	k8sRktRestartCountAnno           = "rkt.kubernetes.io/restart-count"
 | 
						k8sRktRestartCountAnno           = "rkt.kubernetes.io/restart-count"
 | 
				
			||||||
	k8sRktTerminationMessagePathAnno = "rkt.kubernetes.io/termination-message-path"
 | 
						k8sRktTerminationMessagePathAnno = "rkt.kubernetes.io/termination-message-path"
 | 
				
			||||||
@@ -128,6 +127,11 @@ type Runtime struct {
 | 
				
			|||||||
	volumeGetter        volumeGetter
 | 
						volumeGetter        volumeGetter
 | 
				
			||||||
	imagePuller         kubecontainer.ImagePuller
 | 
						imagePuller         kubecontainer.ImagePuller
 | 
				
			||||||
	runner              kubecontainer.HandlerRunner
 | 
						runner              kubecontainer.HandlerRunner
 | 
				
			||||||
 | 
						execer              utilexec.Interface
 | 
				
			||||||
 | 
						os                  kubecontainer.OSInterface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// used for a systemd Exec, which requires the full path.
 | 
				
			||||||
 | 
						touchPath string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	versions versions
 | 
						versions versions
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -151,6 +155,8 @@ func New(
 | 
				
			|||||||
	livenessManager proberesults.Manager,
 | 
						livenessManager proberesults.Manager,
 | 
				
			||||||
	volumeGetter volumeGetter,
 | 
						volumeGetter volumeGetter,
 | 
				
			||||||
	httpClient kubetypes.HttpGetter,
 | 
						httpClient kubetypes.HttpGetter,
 | 
				
			||||||
 | 
						execer utilexec.Interface,
 | 
				
			||||||
 | 
						os kubecontainer.OSInterface,
 | 
				
			||||||
	imageBackOff *flowcontrol.Backoff,
 | 
						imageBackOff *flowcontrol.Backoff,
 | 
				
			||||||
	serializeImagePulls bool,
 | 
						serializeImagePulls bool,
 | 
				
			||||||
) (*Runtime, error) {
 | 
					) (*Runtime, error) {
 | 
				
			||||||
@@ -170,12 +176,17 @@ func New(
 | 
				
			|||||||
	if config.Path == "" {
 | 
						if config.Path == "" {
 | 
				
			||||||
		// No default rkt path was set, so try to find one in $PATH.
 | 
							// No default rkt path was set, so try to find one in $PATH.
 | 
				
			||||||
		var err error
 | 
							var err error
 | 
				
			||||||
		config.Path, err = exec.LookPath("rkt")
 | 
							config.Path, err = execer.LookPath("rkt")
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, fmt.Errorf("cannot find rkt binary: %v", err)
 | 
								return nil, fmt.Errorf("cannot find rkt binary: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						touchPath, err := execer.LookPath("touch")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("cannot find touch binary: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rkt := &Runtime{
 | 
						rkt := &Runtime{
 | 
				
			||||||
		systemd:             systemd,
 | 
							systemd:             systemd,
 | 
				
			||||||
		apisvcConn:          apisvcConn,
 | 
							apisvcConn:          apisvcConn,
 | 
				
			||||||
@@ -187,6 +198,8 @@ func New(
 | 
				
			|||||||
		recorder:            recorder,
 | 
							recorder:            recorder,
 | 
				
			||||||
		livenessManager:     livenessManager,
 | 
							livenessManager:     livenessManager,
 | 
				
			||||||
		volumeGetter:        volumeGetter,
 | 
							volumeGetter:        volumeGetter,
 | 
				
			||||||
 | 
							execer:              execer,
 | 
				
			||||||
 | 
							touchPath:           touchPath,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rkt.config, err = rkt.getConfig(rkt.config)
 | 
						rkt.config, err = rkt.getConfig(rkt.config)
 | 
				
			||||||
@@ -541,7 +554,6 @@ func (r *Runtime) makePodManifest(pod *api.Pod, pullSecrets []api.Secret) (*appc
 | 
				
			|||||||
	manifest.Annotations.Set(*appctypes.MustACIdentifier(k8sRktUIDAnno), string(pod.UID))
 | 
						manifest.Annotations.Set(*appctypes.MustACIdentifier(k8sRktUIDAnno), string(pod.UID))
 | 
				
			||||||
	manifest.Annotations.Set(*appctypes.MustACIdentifier(k8sRktNameAnno), pod.Name)
 | 
						manifest.Annotations.Set(*appctypes.MustACIdentifier(k8sRktNameAnno), pod.Name)
 | 
				
			||||||
	manifest.Annotations.Set(*appctypes.MustACIdentifier(k8sRktNamespaceAnno), pod.Namespace)
 | 
						manifest.Annotations.Set(*appctypes.MustACIdentifier(k8sRktNamespaceAnno), pod.Namespace)
 | 
				
			||||||
	manifest.Annotations.Set(*appctypes.MustACIdentifier(k8sRktCreationTimeAnno), strconv.FormatInt(time.Now().Unix(), 10))
 | 
					 | 
				
			||||||
	manifest.Annotations.Set(*appctypes.MustACIdentifier(k8sRktRestartCountAnno), strconv.Itoa(restartCount))
 | 
						manifest.Annotations.Set(*appctypes.MustACIdentifier(k8sRktRestartCountAnno), strconv.Itoa(restartCount))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for _, c := range pod.Spec.Containers {
 | 
						for _, c := range pod.Spec.Containers {
 | 
				
			||||||
@@ -587,6 +599,34 @@ func makeHostNetworkMount(opts *kubecontainer.RunContainerOptions) (*kubecontain
 | 
				
			|||||||
	return &hostsMount, &resolvMount
 | 
						return &hostsMount, &resolvMount
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// podFinishedMarkerPath returns the path to a file which should be used to
 | 
				
			||||||
 | 
					// indicate the pod exiting, and the time thereof.
 | 
				
			||||||
 | 
					// If the file at the path does not exist, the pod should not be exited. If it
 | 
				
			||||||
 | 
					// does exist, then the ctime of the file should indicate the time the pod
 | 
				
			||||||
 | 
					// exited.
 | 
				
			||||||
 | 
					func podFinishedMarkerPath(podDir string, rktUID string) string {
 | 
				
			||||||
 | 
						return filepath.Join(podDir, "finished-"+rktUID)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func podFinishedMarkCommand(touchPath, podDir, rktUID string) string {
 | 
				
			||||||
 | 
						// TODO, if the path has a `'` character in it, this breaks.
 | 
				
			||||||
 | 
						return touchPath + " " + podFinishedMarkerPath(podDir, rktUID)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// podFinishedAt returns the time that a pod exited, or a zero time if it has
 | 
				
			||||||
 | 
					// not.
 | 
				
			||||||
 | 
					func (r *Runtime) podFinishedAt(podUID types.UID, rktUID string) time.Time {
 | 
				
			||||||
 | 
						markerFile := podFinishedMarkerPath(r.runtimeHelper.GetPodDir(podUID), rktUID)
 | 
				
			||||||
 | 
						stat, err := r.os.Stat(markerFile)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							if !os.IsNotExist(err) {
 | 
				
			||||||
 | 
								glog.Warningf("rkt: unexpected fs error checking pod finished marker: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return time.Time{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return stat.ModTime()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func makeContainerLogMount(opts *kubecontainer.RunContainerOptions, container *api.Container) (*kubecontainer.Mount, error) {
 | 
					func makeContainerLogMount(opts *kubecontainer.RunContainerOptions, container *api.Container) (*kubecontainer.Mount, error) {
 | 
				
			||||||
	if opts.PodContainerDir == "" || container.TerminationMessagePath == "" {
 | 
						if opts.PodContainerDir == "" || container.TerminationMessagePath == "" {
 | 
				
			||||||
		return nil, nil
 | 
							return nil, nil
 | 
				
			||||||
@@ -884,8 +924,11 @@ func (r *Runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret) (string, *k
 | 
				
			|||||||
	// TODO handle pod.Spec.HostPID
 | 
						// TODO handle pod.Spec.HostPID
 | 
				
			||||||
	// TODO handle pod.Spec.HostIPC
 | 
						// TODO handle pod.Spec.HostIPC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO per container finishedAt, not just per pod
 | 
				
			||||||
 | 
						markPodFinished := podFinishedMarkCommand(r.touchPath, r.runtimeHelper.GetPodDir(pod.UID), uuid)
 | 
				
			||||||
	units := []*unit.UnitOption{
 | 
						units := []*unit.UnitOption{
 | 
				
			||||||
		newUnitOption("Service", "ExecStart", runPrepared),
 | 
							newUnitOption("Service", "ExecStart", runPrepared),
 | 
				
			||||||
 | 
							newUnitOption("Service", "ExecStopPost", markPodFinished),
 | 
				
			||||||
		// This enables graceful stop.
 | 
							// This enables graceful stop.
 | 
				
			||||||
		newUnitOption("Service", "KillMode", "mixed"),
 | 
							newUnitOption("Service", "KillMode", "mixed"),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -1045,14 +1088,6 @@ func (r *Runtime) convertRktPod(rktpod *rktapi.Pod) (*kubecontainer.Pod, error)
 | 
				
			|||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return nil, fmt.Errorf("pod is missing annotation %s", k8sRktNamespaceAnno)
 | 
							return nil, fmt.Errorf("pod is missing annotation %s", k8sRktNamespaceAnno)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	podCreatedString, ok := manifest.Annotations.Get(k8sRktCreationTimeAnno)
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("pod is missing annotation %s", k8sRktCreationTimeAnno)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	podCreated, err := strconv.ParseInt(podCreatedString, 10, 64)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, fmt.Errorf("couldn't parse pod creation timestamp: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kubepod := &kubecontainer.Pod{
 | 
						kubepod := &kubecontainer.Pod{
 | 
				
			||||||
		ID:        types.UID(podUID),
 | 
							ID:        types.UID(podUID),
 | 
				
			||||||
@@ -1078,8 +1113,8 @@ func (r *Runtime) convertRktPod(rktpod *rktapi.Pod) (*kubecontainer.Pod, error)
 | 
				
			|||||||
			// By default, the version returned by rkt API service will be "latest" if not specified.
 | 
								// By default, the version returned by rkt API service will be "latest" if not specified.
 | 
				
			||||||
			Image:   fmt.Sprintf("%s:%s", app.Image.Name, app.Image.Version),
 | 
								Image:   fmt.Sprintf("%s:%s", app.Image.Name, app.Image.Version),
 | 
				
			||||||
			Hash:    containerHash,
 | 
								Hash:    containerHash,
 | 
				
			||||||
			Created: podCreated,
 | 
					 | 
				
			||||||
			State:   appStateToContainerState(app.State),
 | 
								State:   appStateToContainerState(app.State),
 | 
				
			||||||
 | 
								Created: time.Unix(0, rktpod.CreatedAt).Unix(), // convert ns to s
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1526,7 +1561,7 @@ func appStateToContainerState(state rktapi.AppState) kubecontainer.ContainerStat
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// getPodInfo returns the pod manifest, creation time and restart count of the pod.
 | 
					// getPodInfo returns the pod manifest, creation time and restart count of the pod.
 | 
				
			||||||
func getPodInfo(pod *rktapi.Pod) (podManifest *appcschema.PodManifest, creationTime time.Time, restartCount int, err error) {
 | 
					func getPodInfo(pod *rktapi.Pod) (podManifest *appcschema.PodManifest, restartCount int, err error) {
 | 
				
			||||||
	// TODO(yifan): The manifest is only used for getting the annotations.
 | 
						// TODO(yifan): The manifest is only used for getting the annotations.
 | 
				
			||||||
	// Consider to let the server to unmarshal the annotations.
 | 
						// Consider to let the server to unmarshal the annotations.
 | 
				
			||||||
	var manifest appcschema.PodManifest
 | 
						var manifest appcschema.PodManifest
 | 
				
			||||||
@@ -1534,16 +1569,6 @@ func getPodInfo(pod *rktapi.Pod) (podManifest *appcschema.PodManifest, creationT
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	creationTimeStr, ok := manifest.Annotations.Get(k8sRktCreationTimeAnno)
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		err = fmt.Errorf("no creation timestamp in pod manifest")
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	unixSec, err := strconv.ParseInt(creationTimeStr, 10, 64)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if countString, ok := manifest.Annotations.Get(k8sRktRestartCountAnno); ok {
 | 
						if countString, ok := manifest.Annotations.Get(k8sRktRestartCountAnno); ok {
 | 
				
			||||||
		restartCount, err = strconv.Atoi(countString)
 | 
							restartCount, err = strconv.Atoi(countString)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@@ -1551,11 +1576,11 @@ func getPodInfo(pod *rktapi.Pod) (podManifest *appcschema.PodManifest, creationT
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &manifest, time.Unix(unixSec, 0), restartCount, nil
 | 
						return &manifest, restartCount, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// populateContainerStatus fills the container status according to the app's information.
 | 
					// populateContainerStatus fills the container status according to the app's information.
 | 
				
			||||||
func populateContainerStatus(pod rktapi.Pod, app rktapi.App, runtimeApp appcschema.RuntimeApp, restartCount int, creationTime time.Time) (*kubecontainer.ContainerStatus, error) {
 | 
					func populateContainerStatus(pod rktapi.Pod, app rktapi.App, runtimeApp appcschema.RuntimeApp, restartCount int, finishedTime time.Time) (*kubecontainer.ContainerStatus, error) {
 | 
				
			||||||
	hashStr, ok := runtimeApp.Annotations.Get(k8sRktContainerHashAnno)
 | 
						hashStr, ok := runtimeApp.Annotations.Get(k8sRktContainerHashAnno)
 | 
				
			||||||
	if !ok {
 | 
						if !ok {
 | 
				
			||||||
		return nil, fmt.Errorf("No container hash in pod manifest")
 | 
							return nil, fmt.Errorf("No container hash in pod manifest")
 | 
				
			||||||
@@ -1584,14 +1609,17 @@ func populateContainerStatus(pod rktapi.Pod, app rktapi.App, runtimeApp appcsche
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						createdTime := time.Unix(0, pod.CreatedAt)
 | 
				
			||||||
 | 
						startedTime := time.Unix(0, pod.StartedAt)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &kubecontainer.ContainerStatus{
 | 
						return &kubecontainer.ContainerStatus{
 | 
				
			||||||
		ID:    buildContainerID(&containerID{uuid: pod.Id, appName: app.Name}),
 | 
							ID:         buildContainerID(&containerID{uuid: pod.Id, appName: app.Name}),
 | 
				
			||||||
		Name:  app.Name,
 | 
							Name:       app.Name,
 | 
				
			||||||
		State: appStateToContainerState(app.State),
 | 
							State:      appStateToContainerState(app.State),
 | 
				
			||||||
		// TODO(yifan): Use the creation/start/finished timestamp when it's implemented.
 | 
							CreatedAt:  createdTime,
 | 
				
			||||||
		CreatedAt: creationTime,
 | 
							StartedAt:  startedTime,
 | 
				
			||||||
		StartedAt: creationTime,
 | 
							FinishedAt: finishedTime,
 | 
				
			||||||
		ExitCode:  int(app.ExitCode),
 | 
							ExitCode:   int(app.ExitCode),
 | 
				
			||||||
		// By default, the version returned by rkt API service will be "latest" if not specified.
 | 
							// By default, the version returned by rkt API service will be "latest" if not specified.
 | 
				
			||||||
		Image:   fmt.Sprintf("%s:%s", app.Image.Name, app.Image.Version),
 | 
							Image:   fmt.Sprintf("%s:%s", app.Image.Name, app.Image.Version),
 | 
				
			||||||
		ImageID: "rkt://" + app.Image.Id, // TODO(yifan): Add the prefix only in api.PodStatus.
 | 
							ImageID: "rkt://" + app.Image.Id, // TODO(yifan): Add the prefix only in api.PodStatus.
 | 
				
			||||||
@@ -1605,6 +1633,13 @@ func populateContainerStatus(pod rktapi.Pod, app rktapi.App, runtimeApp appcsche
 | 
				
			|||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GetPodStatus returns the status for a pod specified by a given UID, name,
 | 
				
			||||||
 | 
					// and namespace.  It will attempt to find pod's information via a request to
 | 
				
			||||||
 | 
					// the rkt api server.
 | 
				
			||||||
 | 
					// An error will be returned if the api server returns an error. If the api
 | 
				
			||||||
 | 
					// server doesn't error, but doesn't provide meaningful information about the
 | 
				
			||||||
 | 
					// pod, a status with no information (other than the passed in arguments) is
 | 
				
			||||||
 | 
					// returned anyways.
 | 
				
			||||||
func (r *Runtime) GetPodStatus(uid types.UID, name, namespace string) (*kubecontainer.PodStatus, error) {
 | 
					func (r *Runtime) GetPodStatus(uid types.UID, name, namespace string) (*kubecontainer.PodStatus, error) {
 | 
				
			||||||
	podStatus := &kubecontainer.PodStatus{
 | 
						podStatus := &kubecontainer.PodStatus{
 | 
				
			||||||
		ID:        uid,
 | 
							ID:        uid,
 | 
				
			||||||
@@ -1626,7 +1661,7 @@ func (r *Runtime) GetPodStatus(uid types.UID, name, namespace string) (*kubecont
 | 
				
			|||||||
	// In this loop, we group all containers from all pods together,
 | 
						// In this loop, we group all containers from all pods together,
 | 
				
			||||||
	// also we try to find the latest pod, so we can fill other info of the pod below.
 | 
						// also we try to find the latest pod, so we can fill other info of the pod below.
 | 
				
			||||||
	for _, pod := range listResp.Pods {
 | 
						for _, pod := range listResp.Pods {
 | 
				
			||||||
		manifest, creationTime, restartCount, err := getPodInfo(pod)
 | 
							manifest, restartCount, err := getPodInfo(pod)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			glog.Warningf("rkt: Couldn't get necessary info from the rkt pod, (uuid %q): %v", pod.Id, err)
 | 
								glog.Warningf("rkt: Couldn't get necessary info from the rkt pod, (uuid %q): %v", pod.Id, err)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
@@ -1637,11 +1672,10 @@ func (r *Runtime) GetPodStatus(uid types.UID, name, namespace string) (*kubecont
 | 
				
			|||||||
			latestRestartCount = restartCount
 | 
								latestRestartCount = restartCount
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							finishedTime := r.podFinishedAt(uid, pod.Id)
 | 
				
			||||||
		for i, app := range pod.Apps {
 | 
							for i, app := range pod.Apps {
 | 
				
			||||||
			// The order of the apps is determined by the rkt pod manifest.
 | 
								// The order of the apps is determined by the rkt pod manifest.
 | 
				
			||||||
			// TODO(yifan): Save creationTime, restartCount in each app's annotation,
 | 
								cs, err := populateContainerStatus(*pod, *app, manifest.Apps[i], restartCount, finishedTime)
 | 
				
			||||||
			// so we don't need to pass them.
 | 
					 | 
				
			||||||
			cs, err := populateContainerStatus(*pod, *app, manifest.Apps[i], restartCount, creationTime)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				glog.Warningf("rkt: Failed to populate container status(uuid %q, app %q): %v", pod.Id, app.Name, err)
 | 
									glog.Warningf("rkt: Failed to populate container status(uuid %q, app %q): %v", pod.Id, app.Name, err)
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,11 +27,14 @@ import (
 | 
				
			|||||||
	appcschema "github.com/appc/spec/schema"
 | 
						appcschema "github.com/appc/spec/schema"
 | 
				
			||||||
	appctypes "github.com/appc/spec/schema/types"
 | 
						appctypes "github.com/appc/spec/schema/types"
 | 
				
			||||||
	rktapi "github.com/coreos/rkt/api/v1alpha"
 | 
						rktapi "github.com/coreos/rkt/api/v1alpha"
 | 
				
			||||||
 | 
						"github.com/golang/mock/gomock"
 | 
				
			||||||
	"github.com/stretchr/testify/assert"
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api"
 | 
						"k8s.io/kubernetes/pkg/api"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/api/resource"
 | 
						"k8s.io/kubernetes/pkg/api/resource"
 | 
				
			||||||
	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
 | 
						kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
 | 
				
			||||||
 | 
						containertesting "k8s.io/kubernetes/pkg/kubelet/container/testing"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/kubelet/lifecycle"
 | 
						"k8s.io/kubernetes/pkg/kubelet/lifecycle"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/kubelet/rkt/mock_os"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/util/errors"
 | 
						"k8s.io/kubernetes/pkg/util/errors"
 | 
				
			||||||
	utiltesting "k8s.io/kubernetes/pkg/util/testing"
 | 
						utiltesting "k8s.io/kubernetes/pkg/util/testing"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -62,9 +65,10 @@ func mustRktHash(hash string) *appctypes.Hash {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func makeRktPod(rktPodState rktapi.PodState,
 | 
					func makeRktPod(rktPodState rktapi.PodState,
 | 
				
			||||||
	rktPodID, podUID, podName, podNamespace,
 | 
						rktPodID, podUID, podName, podNamespace,
 | 
				
			||||||
	podIP, podCreationTs, podRestartCount string,
 | 
						podIP string, podCreatedAt, podStartedAt int64,
 | 
				
			||||||
	appNames, imgIDs, imgNames, containerHashes []string,
 | 
						podRestartCount string, appNames, imgIDs, imgNames,
 | 
				
			||||||
	appStates []rktapi.AppState, exitcodes []int32) *rktapi.Pod {
 | 
						containerHashes []string, appStates []rktapi.AppState,
 | 
				
			||||||
 | 
						exitcodes []int32) *rktapi.Pod {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	podManifest := &appcschema.PodManifest{
 | 
						podManifest := &appcschema.PodManifest{
 | 
				
			||||||
		ACKind:    appcschema.PodManifestKind,
 | 
							ACKind:    appcschema.PodManifestKind,
 | 
				
			||||||
@@ -86,10 +90,6 @@ func makeRktPod(rktPodState rktapi.PodState,
 | 
				
			|||||||
				Name:  *appctypes.MustACIdentifier(k8sRktNamespaceAnno),
 | 
									Name:  *appctypes.MustACIdentifier(k8sRktNamespaceAnno),
 | 
				
			||||||
				Value: podNamespace,
 | 
									Value: podNamespace,
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			appctypes.Annotation{
 | 
					 | 
				
			||||||
				Name:  *appctypes.MustACIdentifier(k8sRktCreationTimeAnno),
 | 
					 | 
				
			||||||
				Value: podCreationTs,
 | 
					 | 
				
			||||||
			},
 | 
					 | 
				
			||||||
			appctypes.Annotation{
 | 
								appctypes.Annotation{
 | 
				
			||||||
				Name:  *appctypes.MustACIdentifier(k8sRktRestartCountAnno),
 | 
									Name:  *appctypes.MustACIdentifier(k8sRktRestartCountAnno),
 | 
				
			||||||
				Value: podRestartCount,
 | 
									Value: podRestartCount,
 | 
				
			||||||
@@ -143,11 +143,13 @@ func makeRktPod(rktPodState rktapi.PodState,
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &rktapi.Pod{
 | 
						return &rktapi.Pod{
 | 
				
			||||||
		Id:       rktPodID,
 | 
							Id:        rktPodID,
 | 
				
			||||||
		State:    rktPodState,
 | 
							State:     rktPodState,
 | 
				
			||||||
		Networks: []*rktapi.Network{{Name: defaultNetworkName, Ipv4: podIP}},
 | 
							Networks:  []*rktapi.Network{{Name: defaultNetworkName, Ipv4: podIP}},
 | 
				
			||||||
		Apps:     apps,
 | 
							Apps:      apps,
 | 
				
			||||||
		Manifest: mustMarshalPodManifest(podManifest),
 | 
							Manifest:  mustMarshalPodManifest(podManifest),
 | 
				
			||||||
 | 
							StartedAt: podStartedAt,
 | 
				
			||||||
 | 
							CreatedAt: podCreatedAt,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -346,6 +348,10 @@ func TestGetPods(t *testing.T) {
 | 
				
			|||||||
	fs := newFakeSystemd()
 | 
						fs := newFakeSystemd()
 | 
				
			||||||
	r := &Runtime{apisvc: fr, systemd: fs}
 | 
						r := &Runtime{apisvc: fr, systemd: fs}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ns := func(seconds int64) int64 {
 | 
				
			||||||
 | 
							return seconds * 1e9
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tests := []struct {
 | 
						tests := []struct {
 | 
				
			||||||
		pods   []*rktapi.Pod
 | 
							pods   []*rktapi.Pod
 | 
				
			||||||
		result []*kubecontainer.Pod
 | 
							result []*kubecontainer.Pod
 | 
				
			||||||
@@ -357,7 +363,7 @@ func TestGetPods(t *testing.T) {
 | 
				
			|||||||
			[]*rktapi.Pod{
 | 
								[]*rktapi.Pod{
 | 
				
			||||||
				makeRktPod(rktapi.PodState_POD_STATE_RUNNING,
 | 
									makeRktPod(rktapi.PodState_POD_STATE_RUNNING,
 | 
				
			||||||
					"uuid-4002", "42", "guestbook", "default",
 | 
										"uuid-4002", "42", "guestbook", "default",
 | 
				
			||||||
					"10.10.10.42", "100000", "7",
 | 
										"10.10.10.42", ns(10), ns(10), "7",
 | 
				
			||||||
					[]string{"app-1", "app-2"},
 | 
										[]string{"app-1", "app-2"},
 | 
				
			||||||
					[]string{"img-id-1", "img-id-2"},
 | 
										[]string{"img-id-1", "img-id-2"},
 | 
				
			||||||
					[]string{"img-name-1", "img-name-2"},
 | 
										[]string{"img-name-1", "img-name-2"},
 | 
				
			||||||
@@ -377,7 +383,7 @@ func TestGetPods(t *testing.T) {
 | 
				
			|||||||
							Name:    "app-1",
 | 
												Name:    "app-1",
 | 
				
			||||||
							Image:   "img-name-1:latest",
 | 
												Image:   "img-name-1:latest",
 | 
				
			||||||
							Hash:    1001,
 | 
												Hash:    1001,
 | 
				
			||||||
							Created: 100000,
 | 
												Created: 10,
 | 
				
			||||||
							State:   "running",
 | 
												State:   "running",
 | 
				
			||||||
						},
 | 
											},
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
@@ -385,7 +391,7 @@ func TestGetPods(t *testing.T) {
 | 
				
			|||||||
							Name:    "app-2",
 | 
												Name:    "app-2",
 | 
				
			||||||
							Image:   "img-name-2:latest",
 | 
												Image:   "img-name-2:latest",
 | 
				
			||||||
							Hash:    1002,
 | 
												Hash:    1002,
 | 
				
			||||||
							Created: 100000,
 | 
												Created: 10,
 | 
				
			||||||
							State:   "exited",
 | 
												State:   "exited",
 | 
				
			||||||
						},
 | 
											},
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
@@ -397,7 +403,7 @@ func TestGetPods(t *testing.T) {
 | 
				
			|||||||
			[]*rktapi.Pod{
 | 
								[]*rktapi.Pod{
 | 
				
			||||||
				makeRktPod(rktapi.PodState_POD_STATE_RUNNING,
 | 
									makeRktPod(rktapi.PodState_POD_STATE_RUNNING,
 | 
				
			||||||
					"uuid-4002", "42", "guestbook", "default",
 | 
										"uuid-4002", "42", "guestbook", "default",
 | 
				
			||||||
					"10.10.10.42", "100000", "7",
 | 
										"10.10.10.42", ns(10), ns(20), "7",
 | 
				
			||||||
					[]string{"app-1", "app-2"},
 | 
										[]string{"app-1", "app-2"},
 | 
				
			||||||
					[]string{"img-id-1", "img-id-2"},
 | 
										[]string{"img-id-1", "img-id-2"},
 | 
				
			||||||
					[]string{"img-name-1", "img-name-2"},
 | 
										[]string{"img-name-1", "img-name-2"},
 | 
				
			||||||
@@ -407,7 +413,7 @@ func TestGetPods(t *testing.T) {
 | 
				
			|||||||
				),
 | 
									),
 | 
				
			||||||
				makeRktPod(rktapi.PodState_POD_STATE_EXITED,
 | 
									makeRktPod(rktapi.PodState_POD_STATE_EXITED,
 | 
				
			||||||
					"uuid-4003", "43", "guestbook", "default",
 | 
										"uuid-4003", "43", "guestbook", "default",
 | 
				
			||||||
					"10.10.10.43", "90000", "7",
 | 
										"10.10.10.43", ns(30), ns(40), "7",
 | 
				
			||||||
					[]string{"app-11", "app-22"},
 | 
										[]string{"app-11", "app-22"},
 | 
				
			||||||
					[]string{"img-id-11", "img-id-22"},
 | 
										[]string{"img-id-11", "img-id-22"},
 | 
				
			||||||
					[]string{"img-name-11", "img-name-22"},
 | 
										[]string{"img-name-11", "img-name-22"},
 | 
				
			||||||
@@ -417,7 +423,7 @@ func TestGetPods(t *testing.T) {
 | 
				
			|||||||
				),
 | 
									),
 | 
				
			||||||
				makeRktPod(rktapi.PodState_POD_STATE_EXITED,
 | 
									makeRktPod(rktapi.PodState_POD_STATE_EXITED,
 | 
				
			||||||
					"uuid-4004", "43", "guestbook", "default",
 | 
										"uuid-4004", "43", "guestbook", "default",
 | 
				
			||||||
					"10.10.10.44", "100000", "8",
 | 
										"10.10.10.44", ns(50), ns(60), "8",
 | 
				
			||||||
					[]string{"app-11", "app-22"},
 | 
										[]string{"app-11", "app-22"},
 | 
				
			||||||
					[]string{"img-id-11", "img-id-22"},
 | 
										[]string{"img-id-11", "img-id-22"},
 | 
				
			||||||
					[]string{"img-name-11", "img-name-22"},
 | 
										[]string{"img-name-11", "img-name-22"},
 | 
				
			||||||
@@ -437,7 +443,7 @@ func TestGetPods(t *testing.T) {
 | 
				
			|||||||
							Name:    "app-1",
 | 
												Name:    "app-1",
 | 
				
			||||||
							Image:   "img-name-1:latest",
 | 
												Image:   "img-name-1:latest",
 | 
				
			||||||
							Hash:    1001,
 | 
												Hash:    1001,
 | 
				
			||||||
							Created: 100000,
 | 
												Created: 10,
 | 
				
			||||||
							State:   "running",
 | 
												State:   "running",
 | 
				
			||||||
						},
 | 
											},
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
@@ -445,7 +451,7 @@ func TestGetPods(t *testing.T) {
 | 
				
			|||||||
							Name:    "app-2",
 | 
												Name:    "app-2",
 | 
				
			||||||
							Image:   "img-name-2:latest",
 | 
												Image:   "img-name-2:latest",
 | 
				
			||||||
							Hash:    1002,
 | 
												Hash:    1002,
 | 
				
			||||||
							Created: 100000,
 | 
												Created: 10,
 | 
				
			||||||
							State:   "exited",
 | 
												State:   "exited",
 | 
				
			||||||
						},
 | 
											},
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
@@ -460,7 +466,7 @@ func TestGetPods(t *testing.T) {
 | 
				
			|||||||
							Name:    "app-11",
 | 
												Name:    "app-11",
 | 
				
			||||||
							Image:   "img-name-11:latest",
 | 
												Image:   "img-name-11:latest",
 | 
				
			||||||
							Hash:    10011,
 | 
												Hash:    10011,
 | 
				
			||||||
							Created: 90000,
 | 
												Created: 30,
 | 
				
			||||||
							State:   "exited",
 | 
												State:   "exited",
 | 
				
			||||||
						},
 | 
											},
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
@@ -468,7 +474,7 @@ func TestGetPods(t *testing.T) {
 | 
				
			|||||||
							Name:    "app-22",
 | 
												Name:    "app-22",
 | 
				
			||||||
							Image:   "img-name-22:latest",
 | 
												Image:   "img-name-22:latest",
 | 
				
			||||||
							Hash:    10022,
 | 
												Hash:    10022,
 | 
				
			||||||
							Created: 90000,
 | 
												Created: 30,
 | 
				
			||||||
							State:   "exited",
 | 
												State:   "exited",
 | 
				
			||||||
						},
 | 
											},
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
@@ -476,7 +482,7 @@ func TestGetPods(t *testing.T) {
 | 
				
			|||||||
							Name:    "app-11",
 | 
												Name:    "app-11",
 | 
				
			||||||
							Image:   "img-name-11:latest",
 | 
												Image:   "img-name-11:latest",
 | 
				
			||||||
							Hash:    10011,
 | 
												Hash:    10011,
 | 
				
			||||||
							Created: 100000,
 | 
												Created: 50,
 | 
				
			||||||
							State:   "running",
 | 
												State:   "running",
 | 
				
			||||||
						},
 | 
											},
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
@@ -484,7 +490,7 @@ func TestGetPods(t *testing.T) {
 | 
				
			|||||||
							Name:    "app-22",
 | 
												Name:    "app-22",
 | 
				
			||||||
							Image:   "img-name-22:latest",
 | 
												Image:   "img-name-22:latest",
 | 
				
			||||||
							Hash:    10022,
 | 
												Hash:    10022,
 | 
				
			||||||
							Created: 100000,
 | 
												Created: 50,
 | 
				
			||||||
							State:   "running",
 | 
												State:   "running",
 | 
				
			||||||
						},
 | 
											},
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
@@ -557,7 +563,18 @@ func TestGetPodsFilters(t *testing.T) {
 | 
				
			|||||||
func TestGetPodStatus(t *testing.T) {
 | 
					func TestGetPodStatus(t *testing.T) {
 | 
				
			||||||
	fr := newFakeRktInterface()
 | 
						fr := newFakeRktInterface()
 | 
				
			||||||
	fs := newFakeSystemd()
 | 
						fs := newFakeSystemd()
 | 
				
			||||||
	r := &Runtime{apisvc: fr, systemd: fs}
 | 
						fos := &containertesting.FakeOS{}
 | 
				
			||||||
 | 
						frh := &fakeRuntimeHelper{}
 | 
				
			||||||
 | 
						r := &Runtime{
 | 
				
			||||||
 | 
							apisvc:        fr,
 | 
				
			||||||
 | 
							systemd:       fs,
 | 
				
			||||||
 | 
							runtimeHelper: frh,
 | 
				
			||||||
 | 
							os:            fos,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ns := func(seconds int64) int64 {
 | 
				
			||||||
 | 
							return seconds * 1e9
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tests := []struct {
 | 
						tests := []struct {
 | 
				
			||||||
		pods   []*rktapi.Pod
 | 
							pods   []*rktapi.Pod
 | 
				
			||||||
@@ -573,7 +590,7 @@ func TestGetPodStatus(t *testing.T) {
 | 
				
			|||||||
			[]*rktapi.Pod{
 | 
								[]*rktapi.Pod{
 | 
				
			||||||
				makeRktPod(rktapi.PodState_POD_STATE_RUNNING,
 | 
									makeRktPod(rktapi.PodState_POD_STATE_RUNNING,
 | 
				
			||||||
					"uuid-4002", "42", "guestbook", "default",
 | 
										"uuid-4002", "42", "guestbook", "default",
 | 
				
			||||||
					"10.10.10.42", "100000", "7",
 | 
										"10.10.10.42", ns(10), ns(20), "7",
 | 
				
			||||||
					[]string{"app-1", "app-2"},
 | 
										[]string{"app-1", "app-2"},
 | 
				
			||||||
					[]string{"img-id-1", "img-id-2"},
 | 
										[]string{"img-id-1", "img-id-2"},
 | 
				
			||||||
					[]string{"img-name-1", "img-name-2"},
 | 
										[]string{"img-name-1", "img-name-2"},
 | 
				
			||||||
@@ -592,8 +609,9 @@ func TestGetPodStatus(t *testing.T) {
 | 
				
			|||||||
						ID:           kubecontainer.BuildContainerID("rkt", "uuid-4002:app-1"),
 | 
											ID:           kubecontainer.BuildContainerID("rkt", "uuid-4002:app-1"),
 | 
				
			||||||
						Name:         "app-1",
 | 
											Name:         "app-1",
 | 
				
			||||||
						State:        kubecontainer.ContainerStateRunning,
 | 
											State:        kubecontainer.ContainerStateRunning,
 | 
				
			||||||
						CreatedAt:    time.Unix(100000, 0),
 | 
											CreatedAt:    time.Unix(10, 0),
 | 
				
			||||||
						StartedAt:    time.Unix(100000, 0),
 | 
											StartedAt:    time.Unix(20, 0),
 | 
				
			||||||
 | 
											FinishedAt:   time.Unix(0, 30),
 | 
				
			||||||
						Image:        "img-name-1:latest",
 | 
											Image:        "img-name-1:latest",
 | 
				
			||||||
						ImageID:      "rkt://img-id-1",
 | 
											ImageID:      "rkt://img-id-1",
 | 
				
			||||||
						Hash:         1001,
 | 
											Hash:         1001,
 | 
				
			||||||
@@ -603,8 +621,9 @@ func TestGetPodStatus(t *testing.T) {
 | 
				
			|||||||
						ID:           kubecontainer.BuildContainerID("rkt", "uuid-4002:app-2"),
 | 
											ID:           kubecontainer.BuildContainerID("rkt", "uuid-4002:app-2"),
 | 
				
			||||||
						Name:         "app-2",
 | 
											Name:         "app-2",
 | 
				
			||||||
						State:        kubecontainer.ContainerStateExited,
 | 
											State:        kubecontainer.ContainerStateExited,
 | 
				
			||||||
						CreatedAt:    time.Unix(100000, 0),
 | 
											CreatedAt:    time.Unix(10, 0),
 | 
				
			||||||
						StartedAt:    time.Unix(100000, 0),
 | 
											StartedAt:    time.Unix(20, 0),
 | 
				
			||||||
 | 
											FinishedAt:   time.Unix(0, 30),
 | 
				
			||||||
						Image:        "img-name-2:latest",
 | 
											Image:        "img-name-2:latest",
 | 
				
			||||||
						ImageID:      "rkt://img-id-2",
 | 
											ImageID:      "rkt://img-id-2",
 | 
				
			||||||
						Hash:         1002,
 | 
											Hash:         1002,
 | 
				
			||||||
@@ -619,7 +638,7 @@ func TestGetPodStatus(t *testing.T) {
 | 
				
			|||||||
			[]*rktapi.Pod{
 | 
								[]*rktapi.Pod{
 | 
				
			||||||
				makeRktPod(rktapi.PodState_POD_STATE_EXITED,
 | 
									makeRktPod(rktapi.PodState_POD_STATE_EXITED,
 | 
				
			||||||
					"uuid-4002", "42", "guestbook", "default",
 | 
										"uuid-4002", "42", "guestbook", "default",
 | 
				
			||||||
					"10.10.10.42", "90000", "7",
 | 
										"10.10.10.42", ns(10), ns(20), "7",
 | 
				
			||||||
					[]string{"app-1", "app-2"},
 | 
										[]string{"app-1", "app-2"},
 | 
				
			||||||
					[]string{"img-id-1", "img-id-2"},
 | 
										[]string{"img-id-1", "img-id-2"},
 | 
				
			||||||
					[]string{"img-name-1", "img-name-2"},
 | 
										[]string{"img-name-1", "img-name-2"},
 | 
				
			||||||
@@ -629,7 +648,7 @@ func TestGetPodStatus(t *testing.T) {
 | 
				
			|||||||
				),
 | 
									),
 | 
				
			||||||
				makeRktPod(rktapi.PodState_POD_STATE_RUNNING, // The latest pod is running.
 | 
									makeRktPod(rktapi.PodState_POD_STATE_RUNNING, // The latest pod is running.
 | 
				
			||||||
					"uuid-4003", "42", "guestbook", "default",
 | 
										"uuid-4003", "42", "guestbook", "default",
 | 
				
			||||||
					"10.10.10.42", "100000", "10",
 | 
										"10.10.10.42", ns(10), ns(20), "10",
 | 
				
			||||||
					[]string{"app-1", "app-2"},
 | 
										[]string{"app-1", "app-2"},
 | 
				
			||||||
					[]string{"img-id-1", "img-id-2"},
 | 
										[]string{"img-id-1", "img-id-2"},
 | 
				
			||||||
					[]string{"img-name-1", "img-name-2"},
 | 
										[]string{"img-name-1", "img-name-2"},
 | 
				
			||||||
@@ -649,8 +668,9 @@ func TestGetPodStatus(t *testing.T) {
 | 
				
			|||||||
						ID:           kubecontainer.BuildContainerID("rkt", "uuid-4002:app-1"),
 | 
											ID:           kubecontainer.BuildContainerID("rkt", "uuid-4002:app-1"),
 | 
				
			||||||
						Name:         "app-1",
 | 
											Name:         "app-1",
 | 
				
			||||||
						State:        kubecontainer.ContainerStateRunning,
 | 
											State:        kubecontainer.ContainerStateRunning,
 | 
				
			||||||
						CreatedAt:    time.Unix(90000, 0),
 | 
											CreatedAt:    time.Unix(10, 0),
 | 
				
			||||||
						StartedAt:    time.Unix(90000, 0),
 | 
											StartedAt:    time.Unix(20, 0),
 | 
				
			||||||
 | 
											FinishedAt:   time.Unix(0, 30),
 | 
				
			||||||
						Image:        "img-name-1:latest",
 | 
											Image:        "img-name-1:latest",
 | 
				
			||||||
						ImageID:      "rkt://img-id-1",
 | 
											ImageID:      "rkt://img-id-1",
 | 
				
			||||||
						Hash:         1001,
 | 
											Hash:         1001,
 | 
				
			||||||
@@ -660,8 +680,9 @@ func TestGetPodStatus(t *testing.T) {
 | 
				
			|||||||
						ID:           kubecontainer.BuildContainerID("rkt", "uuid-4002:app-2"),
 | 
											ID:           kubecontainer.BuildContainerID("rkt", "uuid-4002:app-2"),
 | 
				
			||||||
						Name:         "app-2",
 | 
											Name:         "app-2",
 | 
				
			||||||
						State:        kubecontainer.ContainerStateExited,
 | 
											State:        kubecontainer.ContainerStateExited,
 | 
				
			||||||
						CreatedAt:    time.Unix(90000, 0),
 | 
											CreatedAt:    time.Unix(10, 0),
 | 
				
			||||||
						StartedAt:    time.Unix(90000, 0),
 | 
											StartedAt:    time.Unix(20, 0),
 | 
				
			||||||
 | 
											FinishedAt:   time.Unix(0, 30),
 | 
				
			||||||
						Image:        "img-name-2:latest",
 | 
											Image:        "img-name-2:latest",
 | 
				
			||||||
						ImageID:      "rkt://img-id-2",
 | 
											ImageID:      "rkt://img-id-2",
 | 
				
			||||||
						Hash:         1002,
 | 
											Hash:         1002,
 | 
				
			||||||
@@ -672,8 +693,9 @@ func TestGetPodStatus(t *testing.T) {
 | 
				
			|||||||
						ID:           kubecontainer.BuildContainerID("rkt", "uuid-4003:app-1"),
 | 
											ID:           kubecontainer.BuildContainerID("rkt", "uuid-4003:app-1"),
 | 
				
			||||||
						Name:         "app-1",
 | 
											Name:         "app-1",
 | 
				
			||||||
						State:        kubecontainer.ContainerStateRunning,
 | 
											State:        kubecontainer.ContainerStateRunning,
 | 
				
			||||||
						CreatedAt:    time.Unix(100000, 0),
 | 
											CreatedAt:    time.Unix(10, 0),
 | 
				
			||||||
						StartedAt:    time.Unix(100000, 0),
 | 
											StartedAt:    time.Unix(20, 0),
 | 
				
			||||||
 | 
											FinishedAt:   time.Unix(0, 30),
 | 
				
			||||||
						Image:        "img-name-1:latest",
 | 
											Image:        "img-name-1:latest",
 | 
				
			||||||
						ImageID:      "rkt://img-id-1",
 | 
											ImageID:      "rkt://img-id-1",
 | 
				
			||||||
						Hash:         1001,
 | 
											Hash:         1001,
 | 
				
			||||||
@@ -683,8 +705,9 @@ func TestGetPodStatus(t *testing.T) {
 | 
				
			|||||||
						ID:           kubecontainer.BuildContainerID("rkt", "uuid-4003:app-2"),
 | 
											ID:           kubecontainer.BuildContainerID("rkt", "uuid-4003:app-2"),
 | 
				
			||||||
						Name:         "app-2",
 | 
											Name:         "app-2",
 | 
				
			||||||
						State:        kubecontainer.ContainerStateExited,
 | 
											State:        kubecontainer.ContainerStateExited,
 | 
				
			||||||
						CreatedAt:    time.Unix(100000, 0),
 | 
											CreatedAt:    time.Unix(10, 0),
 | 
				
			||||||
						StartedAt:    time.Unix(100000, 0),
 | 
											StartedAt:    time.Unix(20, 0),
 | 
				
			||||||
 | 
											FinishedAt:   time.Unix(0, 30),
 | 
				
			||||||
						Image:        "img-name-2:latest",
 | 
											Image:        "img-name-2:latest",
 | 
				
			||||||
						ImageID:      "rkt://img-id-2",
 | 
											ImageID:      "rkt://img-id-2",
 | 
				
			||||||
						Hash:         1002,
 | 
											Hash:         1002,
 | 
				
			||||||
@@ -697,10 +720,28 @@ func TestGetPodStatus(t *testing.T) {
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ctrl := gomock.NewController(t)
 | 
				
			||||||
 | 
						defer ctrl.Finish()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for i, tt := range tests {
 | 
						for i, tt := range tests {
 | 
				
			||||||
		testCaseHint := fmt.Sprintf("test case #%d", i)
 | 
							testCaseHint := fmt.Sprintf("test case #%d", i)
 | 
				
			||||||
		fr.pods = tt.pods
 | 
							fr.pods = tt.pods
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							podTimes := map[string]time.Time{}
 | 
				
			||||||
 | 
							for _, pod := range tt.pods {
 | 
				
			||||||
 | 
								podTimes[podFinishedMarkerPath(r.runtimeHelper.GetPodDir(tt.result.ID), pod.Id)] = tt.result.ContainerStatuses[0].FinishedAt
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							r.os.(*containertesting.FakeOS).StatFn = func(name string) (os.FileInfo, error) {
 | 
				
			||||||
 | 
								podTime, ok := podTimes[name]
 | 
				
			||||||
 | 
								if !ok {
 | 
				
			||||||
 | 
									t.Errorf("osStat called with %v, but only knew about %#v", name, podTimes)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								mockFI := mock_os.NewMockFileInfo(ctrl)
 | 
				
			||||||
 | 
								mockFI.EXPECT().ModTime().Return(podTime)
 | 
				
			||||||
 | 
								return mockFI, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		status, err := r.GetPodStatus("42", "guestbook", "default")
 | 
							status, err := r.GetPodStatus("42", "guestbook", "default")
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			t.Errorf("test case #%d: unexpected error: %v", i, err)
 | 
								t.Errorf("test case #%d: unexpected error: %v", i, err)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user