summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 18:50:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-16 18:50:48 +0000
commit692eeae1b1cbb8abf0fe81c9bdad936755bd07c5 (patch)
tree3bccb791a4f778db2e6439165a24c384e489ca2b
parentAdding upstream version 1.2.5+ds1. (diff)
downloadgolang-github-openshift-imagebuilder-debian.tar.xz
golang-github-openshift-imagebuilder-debian.zip
Adding debian version 1.2.5+ds1-3.debian/1.2.5+ds1-3debian
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r--debian/changelog101
-rw-r--r--debian/control77
-rw-r--r--debian/copyright31
-rw-r--r--debian/gbp.conf2
-rw-r--r--debian/gitlab-ci.yml6
-rw-r--r--debian/golang-github-openshift-imagebuilder-dev.docs3
-rw-r--r--debian/golang-github-openshift-imagebuilder-dev.install1
-rw-r--r--debian/golang-github-openshift-imagebuilder-dev.lintian-override2
-rw-r--r--debian/license-reconcile.yml6
-rw-r--r--debian/openshift-imagebuilder.docs3
-rw-r--r--debian/openshift-imagebuilder.install1
-rw-r--r--debian/patches/ftbfs-arm.patch18
-rw-r--r--debian/patches/ignore-arch-tests.patch12
-rw-r--r--debian/patches/klog.patch1672
-rw-r--r--debian/patches/series3
-rwxr-xr-xdebian/rules13
-rw-r--r--debian/source/format1
-rw-r--r--debian/source/lintian-overrides2
-rw-r--r--debian/upstream/metadata5
-rw-r--r--debian/watch10
20 files changed, 1969 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..858f42e
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,101 @@
+golang-github-openshift-imagebuilder (1.2.5+ds1-3) unstable; urgency=medium
+
+ * Upload to unstable
+
+ -- Reinhard Tartler <siretart@tauware.de> Sat, 09 Sep 2023 11:15:34 -0400
+
+golang-github-openshift-imagebuilder (1.2.5+ds1-2) experimental; urgency=medium
+
+ * fix FTBFS on ARM archs, disable broken test
+
+ -- Reinhard Tartler <siretart@tauware.de> Sat, 02 Sep 2023 21:07:09 -0400
+
+golang-github-openshift-imagebuilder (1.2.5+ds1-1) experimental; urgency=medium
+
+ * New upstream version
+ * Add lintian overrides for funny test data
+ * Bump standards version
+ * Tighten dependency on containers/storage
+
+ -- Reinhard Tartler <siretart@tauware.de> Sat, 02 Sep 2023 08:38:00 -0400
+
+golang-github-openshift-imagebuilder (1.2.3+ds1-2) unstable; urgency=medium
+
+ * Bug fix: "golang-github-openshift-imagebuilder FTBFS due to unlisted
+ dependency", thanks to William Wilson (Closes: #1014183).
+
+ -- Reinhard Tartler <siretart@tauware.de> Sun, 10 Jul 2022 07:11:52 -0400
+
+golang-github-openshift-imagebuilder (1.2.3+ds1-1) unstable; urgency=medium
+
+ * New upstream release
+
+ -- Reinhard Tartler <siretart@tauware.de> Wed, 18 May 2022 22:04:00 -0400
+
+golang-github-openshift-imagebuilder (1.2.1+ds1-3) unstable; urgency=medium
+
+ * Upload to unstable
+ * Bug fix: "Typo in package description", thanks to George B. (Closes:
+ #947240).
+
+ -- Reinhard Tartler <siretart@tauware.de> Sun, 29 Aug 2021 11:02:07 +0200
+
+golang-github-openshift-imagebuilder (1.2.1+ds1-2) experimental; urgency=medium
+
+ * Depend explicitly on golang-github-opencontainers-image-spec-dev
+
+ -- Reinhard Tartler <siretart@tauware.de> Sat, 12 Jun 2021 07:15:07 -0400
+
+golang-github-openshift-imagebuilder (1.2.1+ds1-1) experimental; urgency=medium
+
+ * New upstream release
+ * Backport upstream patch: Add mounts to dispatch run
+
+ -- Reinhard Tartler <siretart@tauware.de> Mon, 07 Jun 2021 17:50:25 -0400
+
+golang-github-openshift-imagebuilder (1.2.0+ds1-1) experimental; urgency=medium
+
+ * New upstream release
+ * Bump debhelper from old 11 to 12.
+ * Set debhelper-compat version in Build-Depends.
+ * Set upstream metadata fields: Bug-Database, Bug-Submit, Repository,
+ Repository-Browse.
+
+ -- Reinhard Tartler <siretart@tauware.de> Fri, 02 Apr 2021 21:14:04 -0400
+
+golang-github-openshift-imagebuilder (1.1.6-2) unstable; urgency=medium
+
+ * debian/control: depend on golang-github-containerd-containerd-dev
+
+ -- Reinhard Tartler <siretart@tauware.de> Fri, 24 Jul 2020 07:20:05 -0400
+
+golang-github-openshift-imagebuilder (1.1.6-1) unstable; urgency=medium
+
+ * New upstream version 1.1.6
+
+ -- Reinhard Tartler <siretart@tauware.de> Sat, 11 Jul 2020 11:57:26 -0400
+
+golang-github-openshift-imagebuilder (1.1.4-2) unstable; urgency=medium
+
+ * Fix FTBFS on arm platforms (Closes: #959538)
+
+ -- Reinhard Tartler <siretart@tauware.de> Tue, 19 May 2020 06:51:27 -0400
+
+golang-github-openshift-imagebuilder (1.1.4-1) unstable; urgency=medium
+
+ * New upstream version 1.1.4
+ * vendor k8s.io/klog
+
+ -- Reinhard Tartler <siretart@tauware.de> Sun, 26 Apr 2020 13:52:45 -0400
+
+golang-github-openshift-imagebuilder (1.1.0-2) unstable; urgency=medium
+
+ * Upload to unstable
+
+ -- Reinhard Tartler <siretart@tauware.de> Sat, 19 Oct 2019 11:17:37 -0400
+
+golang-github-openshift-imagebuilder (1.1.0-1) experimental; urgency=medium
+
+ * Initial release (Closes: #923300)
+
+ -- Reinhard Tartler <siretart@tauware.de> Wed, 10 Apr 2019 21:27:11 -0400
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..b37f57f
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,77 @@
+Source: golang-github-openshift-imagebuilder
+Section: devel
+Priority: optional
+Maintainer: Debian Go Packaging Team <team+pkg-go@tracker.debian.org>
+Uploaders: Reinhard Tartler <siretart@tauware.de>
+Build-Depends: debhelper-compat (= 12),
+ dh-golang,
+ golang-any,
+ golang-github-containerd-containerd-dev,
+ golang-github-containers-storage-dev (>= 1.46),
+ golang-github-docker-distribution-dev,
+ golang-github-docker-docker-dev (>= 18.09.3+dfsg1),
+ golang-github-fsouza-go-dockerclient-dev,
+ golang-github-opencontainers-image-spec-dev,
+ golang-github-ulikunitz-xz-dev,
+ golang-glog-dev,
+ golang-google-genproto-dev,
+ golang-google-grpc-dev,
+Standards-Version: 4.6.2
+Homepage: https://github.com/openshift/imagebuilder
+Vcs-Browser: https://salsa.debian.org/go-team/packages/golang-github-openshift-imagebuilder
+Vcs-Git: https://salsa.debian.org/go-team/packages/golang-github-openshift-imagebuilder.git
+XS-Go-Import-Path: github.com/openshift/imagebuilder
+Testsuite: autopkgtest-pkg-go
+
+Package: openshift-imagebuilder
+Architecture: any
+Built-Using: ${misc:Built-Using}
+Depends: ${misc:Depends},
+ ${shlibs:Depends}
+Description: Builds container images using Dockerfile as input
+ This package supports using the Dockerfile syntax to build OCI & Docker
+ compatible images, without invoking a container build command such
+ as buildah bud or docker build. It is intended to give clients more
+ control over how they build container images, including:
+ - Instead of building one layer per line, run all instructions in the
+ same container
+ - Set HostConfig settings like network and memory controls that are
+ not available when running container builds
+ - Mount external files into the build that are not persisted as part
+ of the final image (i.e. "secrets")
+ - If there are no RUN commands in the Dockerfile, the container is
+ created and committed, but never started. The final image should be
+ 99.9% compatible with regular container builds, but bugs are always
+ possible.
+ .
+ This package provides the imagebuilder command-line utility.
+
+Package: golang-github-openshift-imagebuilder-dev
+Architecture: all
+Depends: ${misc:Depends},
+ golang-github-containerd-containerd-dev,
+ golang-github-containers-storage-dev (>> 1.46),
+ golang-github-docker-distribution-dev,
+ golang-github-docker-docker-dev (>> 18.09.3+dfsg1),
+ golang-github-fsouza-go-dockerclient-dev,
+ golang-github-opencontainers-image-spec-dev,
+ golang-github-ulikunitz-xz-dev,
+ golang-glog-dev
+Description: Builds container images using Dockerfile as input
+ This library supports using the Dockerfile syntax to build OCI & Docker
+ compatible images, without invoking a container build command such
+ as buildah bud or docker build. It is intended to give clients more
+ control over how they build container images, including:
+ - Instead of building one layer per line, run all instructions in the
+ same container
+ - Set HostConfig settings like network and memory controls that are
+ not available when running container builds
+ - Mount external files into the build that are not persisted as part
+ of the final image (i.e. "secrets")
+ - If there are no RUN commands in the Dockerfile, the container is
+ created and committed, but never started. The final image should be
+ 99.9% compatible with regular container builds, but bugs are always
+ possible.
+ .
+ This package provides sources that other package may require for
+ building.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..c53bebf
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,31 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: imagebuilder
+Source: https://github.com/openshift/imagebuilder
+Files-Excluded:
+ vendor
+
+Files: *
+Copyright: 2016-2019 OpenShift
+ 2017-2019 RedHat
+License: Apache-2.0
+
+Files: debian/*
+Copyright: 2019 Reinhard Tartler <siretart@tauware.de>
+License: Apache-2.0
+Comment: Debian packaging is licensed under the same terms as upstream
+
+License: Apache-2.0
+ 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.
+ .
+ On Debian systems, the complete text of the Apache version 2.0 license
+ can be found in "/usr/share/common-licenses/Apache-2.0".
diff --git a/debian/gbp.conf b/debian/gbp.conf
new file mode 100644
index 0000000..cec628c
--- /dev/null
+++ b/debian/gbp.conf
@@ -0,0 +1,2 @@
+[DEFAULT]
+pristine-tar = True
diff --git a/debian/gitlab-ci.yml b/debian/gitlab-ci.yml
new file mode 100644
index 0000000..594e14e
--- /dev/null
+++ b/debian/gitlab-ci.yml
@@ -0,0 +1,6 @@
+# auto-generated, DO NOT MODIFY.
+# The authoritative copy of this file lives at:
+# https://salsa.debian.org/go-team/infra/pkg-go-tools/blob/master/config/gitlabciyml.go
+---
+include:
+ - https://salsa.debian.org/go-team/infra/pkg-go-tools/-/raw/master/pipeline/test-archive.yml
diff --git a/debian/golang-github-openshift-imagebuilder-dev.docs b/debian/golang-github-openshift-imagebuilder-dev.docs
new file mode 100644
index 0000000..9db21b7
--- /dev/null
+++ b/debian/golang-github-openshift-imagebuilder-dev.docs
@@ -0,0 +1,3 @@
+LICENSE
+README.md
+dockerfile/NOTICE
diff --git a/debian/golang-github-openshift-imagebuilder-dev.install b/debian/golang-github-openshift-imagebuilder-dev.install
new file mode 100644
index 0000000..dd222db
--- /dev/null
+++ b/debian/golang-github-openshift-imagebuilder-dev.install
@@ -0,0 +1 @@
+usr/share
diff --git a/debian/golang-github-openshift-imagebuilder-dev.lintian-override b/debian/golang-github-openshift-imagebuilder-dev.lintian-override
new file mode 100644
index 0000000..8a9f7d6
--- /dev/null
+++ b/debian/golang-github-openshift-imagebuilder-dev.lintian-override
@@ -0,0 +1,2 @@
+# contains testdata that is not really an .a archive
+golang-github-openshift-imagebuilder-dev: unpack-message-for-deb-data
diff --git a/debian/license-reconcile.yml b/debian/license-reconcile.yml
new file mode 100644
index 0000000..f86288e
--- /dev/null
+++ b/debian/license-reconcile.yml
@@ -0,0 +1,6 @@
+Rules:
+ rules:
+ -
+ Glob: debian/*
+ License: Apache-2.0
+ Copyright: Reinhard Tartler <siretart@tauware.de>
diff --git a/debian/openshift-imagebuilder.docs b/debian/openshift-imagebuilder.docs
new file mode 100644
index 0000000..9db21b7
--- /dev/null
+++ b/debian/openshift-imagebuilder.docs
@@ -0,0 +1,3 @@
+LICENSE
+README.md
+dockerfile/NOTICE
diff --git a/debian/openshift-imagebuilder.install b/debian/openshift-imagebuilder.install
new file mode 100644
index 0000000..e772481
--- /dev/null
+++ b/debian/openshift-imagebuilder.install
@@ -0,0 +1 @@
+usr/bin
diff --git a/debian/patches/ftbfs-arm.patch b/debian/patches/ftbfs-arm.patch
new file mode 100644
index 0000000..7808d4f
--- /dev/null
+++ b/debian/patches/ftbfs-arm.patch
@@ -0,0 +1,18 @@
+From: Reinhard Tartler <siretart@tauware.de>
+Description: Fix FTBFS on arm platforms
+Forwarded: https://github.com/openshift/imagebuilder/issues/160
+Bug-Debian: http://bugs.debian.org/959538
+
+diff --git a/dispatchers_test.go b/dispatchers_test.go
+index dc46c96..718a9a4 100644
+--- a/dispatchers_test.go
++++ b/dispatchers_test.go
+@@ -23,7 +23,7 @@ func TestDispatchArgDefaultBuiltins(t *testing.T) {
+ localspec := platforms.DefaultSpec()
+ expectedArgs := []string{
+ "BUILDARCH=" + localspec.Architecture,
+- "TARGETPLATFORM=" + localspec.OS + "/" + localspec.Architecture,
++ "TARGETPLATFORM=" + platforms.DefaultString(),
+ }
+ got := mybuilder.Arguments()
+ sort.Strings(got)
diff --git a/debian/patches/ignore-arch-tests.patch b/debian/patches/ignore-arch-tests.patch
new file mode 100644
index 0000000..69b7cce
--- /dev/null
+++ b/debian/patches/ignore-arch-tests.patch
@@ -0,0 +1,12 @@
+Index: golang-github-openshift-imagebuilder/dispatchers_test.go
+===================================================================
+--- golang-github-openshift-imagebuilder.orig/dispatchers_test.go
++++ golang-github-openshift-imagebuilder/dispatchers_test.go
+@@ -777,6 +777,7 @@ func TestDispatchFromFlags(t *testing.T)
+ }
+
+ func TestDispatchFromFlagsAndUseBuiltInArgs(t *testing.T) {
++ t.Skip("DM-skipped, cf. https://github.com/openshift/imagebuilder/pull/224#issuecomment-1703977008")
+ expectedPlatform := localspec.OS + "/" + localspec.Architecture
+ mybuilder := Builder{
+ RunConfig: docker.Config{
diff --git a/debian/patches/klog.patch b/debian/patches/klog.patch
new file mode 100644
index 0000000..cb825b7
--- /dev/null
+++ b/debian/patches/klog.patch
@@ -0,0 +1,1672 @@
+diff --git a/vendor/k8s.io/klog/LICENSE b/vendor/k8s.io/klog/LICENSE
+new file mode 100644
+index 0000000..37ec93a
+--- /dev/null
++++ b/vendor/k8s.io/klog/LICENSE
+@@ -0,0 +1,191 @@
++Apache License
++Version 2.0, January 2004
++http://www.apache.org/licenses/
++
++TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
++
++1. Definitions.
++
++"License" shall mean the terms and conditions for use, reproduction, and
++distribution as defined by Sections 1 through 9 of this document.
++
++"Licensor" shall mean the copyright owner or entity authorized by the copyright
++owner that is granting the License.
++
++"Legal Entity" shall mean the union of the acting entity and all other entities
++that control, are controlled by, or are under common control with that entity.
++For the purposes of this definition, "control" means (i) the power, direct or
++indirect, to cause the direction or management of such entity, whether by
++contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
++outstanding shares, or (iii) beneficial ownership of such entity.
++
++"You" (or "Your") shall mean an individual or Legal Entity exercising
++permissions granted by this License.
++
++"Source" form shall mean the preferred form for making modifications, including
++but not limited to software source code, documentation source, and configuration
++files.
++
++"Object" form shall mean any form resulting from mechanical transformation or
++translation of a Source form, including but not limited to compiled object code,
++generated documentation, and conversions to other media types.
++
++"Work" shall mean the work of authorship, whether in Source or Object form, made
++available under the License, as indicated by a copyright notice that is included
++in or attached to the work (an example is provided in the Appendix below).
++
++"Derivative Works" shall mean any work, whether in Source or Object form, that
++is based on (or derived from) the Work and for which the editorial revisions,
++annotations, elaborations, or other modifications represent, as a whole, an
++original work of authorship. For the purposes of this License, Derivative Works
++shall not include works that remain separable from, or merely link (or bind by
++name) to the interfaces of, the Work and Derivative Works thereof.
++
++"Contribution" shall mean any work of authorship, including the original version
++of the Work and any modifications or additions to that Work or Derivative Works
++thereof, that is intentionally submitted to Licensor for inclusion in the Work
++by the copyright owner or by an individual or Legal Entity authorized to submit
++on behalf of the copyright owner. For the purposes of this definition,
++"submitted" means any form of electronic, verbal, or written communication sent
++to the Licensor or its representatives, including but not limited to
++communication on electronic mailing lists, source code control systems, and
++issue tracking systems that are managed by, or on behalf of, the Licensor for
++the purpose of discussing and improving the Work, but excluding communication
++that is conspicuously marked or otherwise designated in writing by the copyright
++owner as "Not a Contribution."
++
++"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
++of whom a Contribution has been received by Licensor and subsequently
++incorporated within the Work.
++
++2. Grant of Copyright License.
++
++Subject to the terms and conditions of this License, each Contributor hereby
++grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
++irrevocable copyright license to reproduce, prepare Derivative Works of,
++publicly display, publicly perform, sublicense, and distribute the Work and such
++Derivative Works in Source or Object form.
++
++3. Grant of Patent License.
++
++Subject to the terms and conditions of this License, each Contributor hereby
++grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
++irrevocable (except as stated in this section) patent license to make, have
++made, use, offer to sell, sell, import, and otherwise transfer the Work, where
++such license applies only to those patent claims licensable by such Contributor
++that are necessarily infringed by their Contribution(s) alone or by combination
++of their Contribution(s) with the Work to which such Contribution(s) was
++submitted. If You institute patent litigation against any entity (including a
++cross-claim or counterclaim in a lawsuit) alleging that the Work or a
++Contribution incorporated within the Work constitutes direct or contributory
++patent infringement, then any patent licenses granted to You under this License
++for that Work shall terminate as of the date such litigation is filed.
++
++4. Redistribution.
++
++You may reproduce and distribute copies of the Work or Derivative Works thereof
++in any medium, with or without modifications, and in Source or Object form,
++provided that You meet the following conditions:
++
++You must give any other recipients of the Work or Derivative Works a copy of
++this License; and
++You must cause any modified files to carry prominent notices stating that You
++changed the files; and
++You must retain, in the Source form of any Derivative Works that You distribute,
++all copyright, patent, trademark, and attribution notices from the Source form
++of the Work, excluding those notices that do not pertain to any part of the
++Derivative Works; and
++If the Work includes a "NOTICE" text file as part of its distribution, then any
++Derivative Works that You distribute must include a readable copy of the
++attribution notices contained within such NOTICE file, excluding those notices
++that do not pertain to any part of the Derivative Works, in at least one of the
++following places: within a NOTICE text file distributed as part of the
++Derivative Works; within the Source form or documentation, if provided along
++with the Derivative Works; or, within a display generated by the Derivative
++Works, if and wherever such third-party notices normally appear. The contents of
++the NOTICE file are for informational purposes only and do not modify the
++License. You may add Your own attribution notices within Derivative Works that
++You distribute, alongside or as an addendum to the NOTICE text from the Work,
++provided that such additional attribution notices cannot be construed as
++modifying the License.
++You may add Your own copyright statement to Your modifications and may provide
++additional or different license terms and conditions for use, reproduction, or
++distribution of Your modifications, or for any such Derivative Works as a whole,
++provided Your use, reproduction, and distribution of the Work otherwise complies
++with the conditions stated in this License.
++
++5. Submission of Contributions.
++
++Unless You explicitly state otherwise, any Contribution intentionally submitted
++for inclusion in the Work by You to the Licensor shall be under the terms and
++conditions of this License, without any additional terms or conditions.
++Notwithstanding the above, nothing herein shall supersede or modify the terms of
++any separate license agreement you may have executed with Licensor regarding
++such Contributions.
++
++6. Trademarks.
++
++This License does not grant permission to use the trade names, trademarks,
++service marks, or product names of the Licensor, except as required for
++reasonable and customary use in describing the origin of the Work and
++reproducing the content of the NOTICE file.
++
++7. Disclaimer of Warranty.
++
++Unless required by applicable law or agreed to in writing, Licensor provides the
++Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
++WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
++including, without limitation, any warranties or conditions of TITLE,
++NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
++solely responsible for determining the appropriateness of using or
++redistributing the Work and assume any risks associated with Your exercise of
++permissions under this License.
++
++8. Limitation of Liability.
++
++In no event and under no legal theory, whether in tort (including negligence),
++contract, or otherwise, unless required by applicable law (such as deliberate
++and grossly negligent acts) or agreed to in writing, shall any Contributor be
++liable to You for damages, including any direct, indirect, special, incidental,
++or consequential damages of any character arising as a result of this License or
++out of the use or inability to use the Work (including but not limited to
++damages for loss of goodwill, work stoppage, computer failure or malfunction, or
++any and all other commercial damages or losses), even if such Contributor has
++been advised of the possibility of such damages.
++
++9. Accepting Warranty or Additional Liability.
++
++While redistributing the Work or Derivative Works thereof, You may choose to
++offer, and charge a fee for, acceptance of support, warranty, indemnity, or
++other liability obligations and/or rights consistent with this License. However,
++in accepting such obligations, You may act only on Your own behalf and on Your
++sole responsibility, not on behalf of any other Contributor, and only if You
++agree to indemnify, defend, and hold each Contributor harmless for any liability
++incurred by, or claims asserted against, such Contributor by reason of your
++accepting any such warranty or additional liability.
++
++END OF TERMS AND CONDITIONS
++
++APPENDIX: How to apply the Apache License to your work
++
++To apply the Apache License to your work, attach the following boilerplate
++notice, with the fields enclosed by brackets "[]" replaced with your own
++identifying information. (Don't include the brackets!) The text should be
++enclosed in the appropriate comment syntax for the file format. We also
++recommend that a file or class name and description of purpose be included on
++the same "printed page" as the copyright notice for easier identification within
++third-party archives.
++
++ Copyright [yyyy] [name of copyright owner]
++
++ Licensed under the Apache License, Version 2.0 (the "License");
++ you may not use this file except in compliance with the License.
++ You may obtain a copy of the License at
++
++ http://www.apache.org/licenses/LICENSE-2.0
++
++ Unless required by applicable law or agreed to in writing, software
++ distributed under the License is distributed on an "AS IS" BASIS,
++ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ See the License for the specific language governing permissions and
++ limitations under the License.
+diff --git a/vendor/k8s.io/klog/README.md b/vendor/k8s.io/klog/README.md
+new file mode 100644
+index 0000000..6cb6d16
+--- /dev/null
++++ b/vendor/k8s.io/klog/README.md
+@@ -0,0 +1,77 @@
++klog
++====
++
++klog is a permanant fork of https://github.com/golang/glog. original README from glog is below
++
++----
++
++How to use klog
++===============
++- Replace imports for `github.com/golang/glog` with `k8s.io/klog`
++- Use `klog.InitFlags(nil)` explicitly for initializing global flags as we no longer use `init()` method to register the flags
++- You can now use `log-file` instead of `log-dir` for logging to a single file (See `examples/log_file/usage_log_file.go`)
++- If you want to redirect everything logged using klog somewhere else (say syslog!), you can use `klog.SetOutput()` method and supply a `io.Writer`. (See `examples/set_output/usage_set_output.go`)
++- For more logging conventions (See [Logging Conventions](https://github.com/kubernetes/community/blob/master/contributors/devel/logging.md))
++
++### Coexisting with glog
++This package can be used side by side with glog. [This example](examples/coexist_glog/coexist_glog.go) shows how to initialize and syncronize flags from the global `flag.CommandLine` FlagSet. In addition, the example makes use of stderr as combined output by setting `alsologtostderr` (or `logtostderr`) to `true`.
++
++## Community, discussion, contribution, and support
++
++Learn how to engage with the Kubernetes community on the [community page](http://kubernetes.io/community/).
++
++You can reach the maintainers of this project at:
++
++- [Slack](https://kubernetes.slack.com/messages/sig-architecture)
++- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-architecture)
++
++### Code of conduct
++
++Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md).
++
++----
++
++glog
++====
++
++Leveled execution logs for Go.
++
++This is an efficient pure Go implementation of leveled logs in the
++manner of the open source C++ package
++ https://github.com/google/glog
++
++By binding methods to booleans it is possible to use the log package
++without paying the expense of evaluating the arguments to the log.
++Through the -vmodule flag, the package also provides fine-grained
++control over logging at the file level.
++
++The comment from glog.go introduces the ideas:
++
++ Package glog implements logging analogous to the Google-internal
++ C++ INFO/ERROR/V setup. It provides functions Info, Warning,
++ Error, Fatal, plus formatting variants such as Infof. It
++ also provides V-style logging controlled by the -v and
++ -vmodule=file=2 flags.
++
++ Basic examples:
++
++ glog.Info("Prepare to repel boarders")
++
++ glog.Fatalf("Initialization failed: %s", err)
++
++ See the documentation for the V function for an explanation
++ of these examples:
++
++ if glog.V(2) {
++ glog.Info("Starting transaction...")
++ }
++
++ glog.V(2).Infoln("Processed", nItems, "elements")
++
++
++The repository contains an open source version of the log package
++used inside Google. The master copy of the source lives inside
++Google, not here. The code in this repo is for export only and is not itself
++under development. Feature requests will be ignored.
++
++Send bug reports to golang-nuts@googlegroups.com.
+diff --git a/vendor/k8s.io/klog/klog.go b/vendor/k8s.io/klog/klog.go
+new file mode 100644
+index 0000000..398cd1c
+--- /dev/null
++++ b/vendor/k8s.io/klog/klog.go
+@@ -0,0 +1,1241 @@
++// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
++//
++// Copyright 2013 Google Inc. 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.
++
++// Package klog implements logging analogous to the Google-internal C++ INFO/ERROR/V setup.
++// It provides functions Info, Warning, Error, Fatal, plus formatting variants such as
++// Infof. It also provides V-style logging controlled by the -v and -vmodule=file=2 flags.
++//
++// Basic examples:
++//
++// glog.Info("Prepare to repel boarders")
++//
++// glog.Fatalf("Initialization failed: %s", err)
++//
++// See the documentation for the V function for an explanation of these examples:
++//
++// if glog.V(2) {
++// glog.Info("Starting transaction...")
++// }
++//
++// glog.V(2).Infoln("Processed", nItems, "elements")
++//
++// Log output is buffered and written periodically using Flush. Programs
++// should call Flush before exiting to guarantee all log output is written.
++//
++// By default, all log statements write to files in a temporary directory.
++// This package provides several flags that modify this behavior.
++// As a result, flag.Parse must be called before any logging is done.
++//
++// -logtostderr=false
++// Logs are written to standard error instead of to files.
++// -alsologtostderr=false
++// Logs are written to standard error as well as to files.
++// -stderrthreshold=ERROR
++// Log events at or above this severity are logged to standard
++// error as well as to files.
++// -log_dir=""
++// Log files will be written to this directory instead of the
++// default temporary directory.
++//
++// Other flags provide aids to debugging.
++//
++// -log_backtrace_at=""
++// When set to a file and line number holding a logging statement,
++// such as
++// -log_backtrace_at=gopherflakes.go:234
++// a stack trace will be written to the Info log whenever execution
++// hits that statement. (Unlike with -vmodule, the ".go" must be
++// present.)
++// -v=0
++// Enable V-leveled logging at the specified level.
++// -vmodule=""
++// The syntax of the argument is a comma-separated list of pattern=N,
++// where pattern is a literal file name (minus the ".go" suffix) or
++// "glob" pattern and N is a V level. For instance,
++// -vmodule=gopher*=3
++// sets the V level to 3 in all Go files whose names begin "gopher".
++//
++package klog
++
++import (
++ "bufio"
++ "bytes"
++ "errors"
++ "flag"
++ "fmt"
++ "io"
++ stdLog "log"
++ "os"
++ "path/filepath"
++ "runtime"
++ "strconv"
++ "strings"
++ "sync"
++ "sync/atomic"
++ "time"
++)
++
++// severity identifies the sort of log: info, warning etc. It also implements
++// the flag.Value interface. The -stderrthreshold flag is of type severity and
++// should be modified only through the flag.Value interface. The values match
++// the corresponding constants in C++.
++type severity int32 // sync/atomic int32
++
++// These constants identify the log levels in order of increasing severity.
++// A message written to a high-severity log file is also written to each
++// lower-severity log file.
++const (
++ infoLog severity = iota
++ warningLog
++ errorLog
++ fatalLog
++ numSeverity = 4
++)
++
++const severityChar = "IWEF"
++
++var severityName = []string{
++ infoLog: "INFO",
++ warningLog: "WARNING",
++ errorLog: "ERROR",
++ fatalLog: "FATAL",
++}
++
++// get returns the value of the severity.
++func (s *severity) get() severity {
++ return severity(atomic.LoadInt32((*int32)(s)))
++}
++
++// set sets the value of the severity.
++func (s *severity) set(val severity) {
++ atomic.StoreInt32((*int32)(s), int32(val))
++}
++
++// String is part of the flag.Value interface.
++func (s *severity) String() string {
++ return strconv.FormatInt(int64(*s), 10)
++}
++
++// Get is part of the flag.Value interface.
++func (s *severity) Get() interface{} {
++ return *s
++}
++
++// Set is part of the flag.Value interface.
++func (s *severity) Set(value string) error {
++ var threshold severity
++ // Is it a known name?
++ if v, ok := severityByName(value); ok {
++ threshold = v
++ } else {
++ v, err := strconv.Atoi(value)
++ if err != nil {
++ return err
++ }
++ threshold = severity(v)
++ }
++ logging.stderrThreshold.set(threshold)
++ return nil
++}
++
++func severityByName(s string) (severity, bool) {
++ s = strings.ToUpper(s)
++ for i, name := range severityName {
++ if name == s {
++ return severity(i), true
++ }
++ }
++ return 0, false
++}
++
++// OutputStats tracks the number of output lines and bytes written.
++type OutputStats struct {
++ lines int64
++ bytes int64
++}
++
++// Lines returns the number of lines written.
++func (s *OutputStats) Lines() int64 {
++ return atomic.LoadInt64(&s.lines)
++}
++
++// Bytes returns the number of bytes written.
++func (s *OutputStats) Bytes() int64 {
++ return atomic.LoadInt64(&s.bytes)
++}
++
++// Stats tracks the number of lines of output and number of bytes
++// per severity level. Values must be read with atomic.LoadInt64.
++var Stats struct {
++ Info, Warning, Error OutputStats
++}
++
++var severityStats = [numSeverity]*OutputStats{
++ infoLog: &Stats.Info,
++ warningLog: &Stats.Warning,
++ errorLog: &Stats.Error,
++}
++
++// Level is exported because it appears in the arguments to V and is
++// the type of the v flag, which can be set programmatically.
++// It's a distinct type because we want to discriminate it from logType.
++// Variables of type level are only changed under logging.mu.
++// The -v flag is read only with atomic ops, so the state of the logging
++// module is consistent.
++
++// Level is treated as a sync/atomic int32.
++
++// Level specifies a level of verbosity for V logs. *Level implements
++// flag.Value; the -v flag is of type Level and should be modified
++// only through the flag.Value interface.
++type Level int32
++
++// get returns the value of the Level.
++func (l *Level) get() Level {
++ return Level(atomic.LoadInt32((*int32)(l)))
++}
++
++// set sets the value of the Level.
++func (l *Level) set(val Level) {
++ atomic.StoreInt32((*int32)(l), int32(val))
++}
++
++// String is part of the flag.Value interface.
++func (l *Level) String() string {
++ return strconv.FormatInt(int64(*l), 10)
++}
++
++// Get is part of the flag.Value interface.
++func (l *Level) Get() interface{} {
++ return *l
++}
++
++// Set is part of the flag.Value interface.
++func (l *Level) Set(value string) error {
++ v, err := strconv.Atoi(value)
++ if err != nil {
++ return err
++ }
++ logging.mu.Lock()
++ defer logging.mu.Unlock()
++ logging.setVState(Level(v), logging.vmodule.filter, false)
++ return nil
++}
++
++// moduleSpec represents the setting of the -vmodule flag.
++type moduleSpec struct {
++ filter []modulePat
++}
++
++// modulePat contains a filter for the -vmodule flag.
++// It holds a verbosity level and a file pattern to match.
++type modulePat struct {
++ pattern string
++ literal bool // The pattern is a literal string
++ level Level
++}
++
++// match reports whether the file matches the pattern. It uses a string
++// comparison if the pattern contains no metacharacters.
++func (m *modulePat) match(file string) bool {
++ if m.literal {
++ return file == m.pattern
++ }
++ match, _ := filepath.Match(m.pattern, file)
++ return match
++}
++
++func (m *moduleSpec) String() string {
++ // Lock because the type is not atomic. TODO: clean this up.
++ logging.mu.Lock()
++ defer logging.mu.Unlock()
++ var b bytes.Buffer
++ for i, f := range m.filter {
++ if i > 0 {
++ b.WriteRune(',')
++ }
++ fmt.Fprintf(&b, "%s=%d", f.pattern, f.level)
++ }
++ return b.String()
++}
++
++// Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the
++// struct is not exported.
++func (m *moduleSpec) Get() interface{} {
++ return nil
++}
++
++var errVmoduleSyntax = errors.New("syntax error: expect comma-separated list of filename=N")
++
++// Syntax: -vmodule=recordio=2,file=1,gfs*=3
++func (m *moduleSpec) Set(value string) error {
++ var filter []modulePat
++ for _, pat := range strings.Split(value, ",") {
++ if len(pat) == 0 {
++ // Empty strings such as from a trailing comma can be ignored.
++ continue
++ }
++ patLev := strings.Split(pat, "=")
++ if len(patLev) != 2 || len(patLev[0]) == 0 || len(patLev[1]) == 0 {
++ return errVmoduleSyntax
++ }
++ pattern := patLev[0]
++ v, err := strconv.Atoi(patLev[1])
++ if err != nil {
++ return errors.New("syntax error: expect comma-separated list of filename=N")
++ }
++ if v < 0 {
++ return errors.New("negative value for vmodule level")
++ }
++ if v == 0 {
++ continue // Ignore. It's harmless but no point in paying the overhead.
++ }
++ // TODO: check syntax of filter?
++ filter = append(filter, modulePat{pattern, isLiteral(pattern), Level(v)})
++ }
++ logging.mu.Lock()
++ defer logging.mu.Unlock()
++ logging.setVState(logging.verbosity, filter, true)
++ return nil
++}
++
++// isLiteral reports whether the pattern is a literal string, that is, has no metacharacters
++// that require filepath.Match to be called to match the pattern.
++func isLiteral(pattern string) bool {
++ return !strings.ContainsAny(pattern, `\*?[]`)
++}
++
++// traceLocation represents the setting of the -log_backtrace_at flag.
++type traceLocation struct {
++ file string
++ line int
++}
++
++// isSet reports whether the trace location has been specified.
++// logging.mu is held.
++func (t *traceLocation) isSet() bool {
++ return t.line > 0
++}
++
++// match reports whether the specified file and line matches the trace location.
++// The argument file name is the full path, not the basename specified in the flag.
++// logging.mu is held.
++func (t *traceLocation) match(file string, line int) bool {
++ if t.line != line {
++ return false
++ }
++ if i := strings.LastIndex(file, "/"); i >= 0 {
++ file = file[i+1:]
++ }
++ return t.file == file
++}
++
++func (t *traceLocation) String() string {
++ // Lock because the type is not atomic. TODO: clean this up.
++ logging.mu.Lock()
++ defer logging.mu.Unlock()
++ return fmt.Sprintf("%s:%d", t.file, t.line)
++}
++
++// Get is part of the (Go 1.2) flag.Getter interface. It always returns nil for this flag type since the
++// struct is not exported
++func (t *traceLocation) Get() interface{} {
++ return nil
++}
++
++var errTraceSyntax = errors.New("syntax error: expect file.go:234")
++
++// Syntax: -log_backtrace_at=gopherflakes.go:234
++// Note that unlike vmodule the file extension is included here.
++func (t *traceLocation) Set(value string) error {
++ if value == "" {
++ // Unset.
++ t.line = 0
++ t.file = ""
++ }
++ fields := strings.Split(value, ":")
++ if len(fields) != 2 {
++ return errTraceSyntax
++ }
++ file, line := fields[0], fields[1]
++ if !strings.Contains(file, ".") {
++ return errTraceSyntax
++ }
++ v, err := strconv.Atoi(line)
++ if err != nil {
++ return errTraceSyntax
++ }
++ if v <= 0 {
++ return errors.New("negative or zero value for level")
++ }
++ logging.mu.Lock()
++ defer logging.mu.Unlock()
++ t.line = v
++ t.file = file
++ return nil
++}
++
++// flushSyncWriter is the interface satisfied by logging destinations.
++type flushSyncWriter interface {
++ Flush() error
++ Sync() error
++ io.Writer
++}
++
++func init() {
++ // Default stderrThreshold is ERROR.
++ logging.stderrThreshold = errorLog
++
++ logging.setVState(0, nil, false)
++ go logging.flushDaemon()
++}
++
++// InitFlags is for explicitly initializing the flags
++func InitFlags(flagset *flag.FlagSet) {
++ if flagset == nil {
++ flagset = flag.CommandLine
++ }
++ flagset.StringVar(&logging.logDir, "log_dir", "", "If non-empty, write log files in this directory")
++ flagset.StringVar(&logging.logFile, "log_file", "", "If non-empty, use this log file")
++ flagset.BoolVar(&logging.toStderr, "logtostderr", true, "log to standard error instead of files")
++ flagset.BoolVar(&logging.alsoToStderr, "alsologtostderr", false, "log to standard error as well as files")
++ flagset.Var(&logging.verbosity, "v", "number for the log level verbosity")
++ flagset.BoolVar(&logging.skipHeaders, "skip_headers", false, "If true, avoid header prefixes in the log messages")
++ flagset.Var(&logging.stderrThreshold, "stderrthreshold", "logs at or above this threshold go to stderr")
++ flagset.Var(&logging.vmodule, "vmodule", "comma-separated list of pattern=N settings for file-filtered logging")
++ flagset.Var(&logging.traceLocation, "log_backtrace_at", "when logging hits line file:N, emit a stack trace")
++}
++
++// Flush flushes all pending log I/O.
++func Flush() {
++ logging.lockAndFlushAll()
++}
++
++// loggingT collects all the global state of the logging setup.
++type loggingT struct {
++ // Boolean flags. Not handled atomically because the flag.Value interface
++ // does not let us avoid the =true, and that shorthand is necessary for
++ // compatibility. TODO: does this matter enough to fix? Seems unlikely.
++ toStderr bool // The -logtostderr flag.
++ alsoToStderr bool // The -alsologtostderr flag.
++
++ // Level flag. Handled atomically.
++ stderrThreshold severity // The -stderrthreshold flag.
++
++ // freeList is a list of byte buffers, maintained under freeListMu.
++ freeList *buffer
++ // freeListMu maintains the free list. It is separate from the main mutex
++ // so buffers can be grabbed and printed to without holding the main lock,
++ // for better parallelization.
++ freeListMu sync.Mutex
++
++ // mu protects the remaining elements of this structure and is
++ // used to synchronize logging.
++ mu sync.Mutex
++ // file holds writer for each of the log types.
++ file [numSeverity]flushSyncWriter
++ // pcs is used in V to avoid an allocation when computing the caller's PC.
++ pcs [1]uintptr
++ // vmap is a cache of the V Level for each V() call site, identified by PC.
++ // It is wiped whenever the vmodule flag changes state.
++ vmap map[uintptr]Level
++ // filterLength stores the length of the vmodule filter chain. If greater
++ // than zero, it means vmodule is enabled. It may be read safely
++ // using sync.LoadInt32, but is only modified under mu.
++ filterLength int32
++ // traceLocation is the state of the -log_backtrace_at flag.
++ traceLocation traceLocation
++ // These flags are modified only under lock, although verbosity may be fetched
++ // safely using atomic.LoadInt32.
++ vmodule moduleSpec // The state of the -vmodule flag.
++ verbosity Level // V logging level, the value of the -v flag/
++
++ // If non-empty, overrides the choice of directory in which to write logs.
++ // See createLogDirs for the full list of possible destinations.
++ logDir string
++
++ // If non-empty, specifies the path of the file to write logs. mutually exclusive
++ // with the log-dir option.
++ logFile string
++
++ // If true, do not add the prefix headers, useful when used with SetOutput
++ skipHeaders bool
++}
++
++// buffer holds a byte Buffer for reuse. The zero value is ready for use.
++type buffer struct {
++ bytes.Buffer
++ tmp [64]byte // temporary byte array for creating headers.
++ next *buffer
++}
++
++var logging loggingT
++
++// setVState sets a consistent state for V logging.
++// l.mu is held.
++func (l *loggingT) setVState(verbosity Level, filter []modulePat, setFilter bool) {
++ // Turn verbosity off so V will not fire while we are in transition.
++ logging.verbosity.set(0)
++ // Ditto for filter length.
++ atomic.StoreInt32(&logging.filterLength, 0)
++
++ // Set the new filters and wipe the pc->Level map if the filter has changed.
++ if setFilter {
++ logging.vmodule.filter = filter
++ logging.vmap = make(map[uintptr]Level)
++ }
++
++ // Things are consistent now, so enable filtering and verbosity.
++ // They are enabled in order opposite to that in V.
++ atomic.StoreInt32(&logging.filterLength, int32(len(filter)))
++ logging.verbosity.set(verbosity)
++}
++
++// getBuffer returns a new, ready-to-use buffer.
++func (l *loggingT) getBuffer() *buffer {
++ l.freeListMu.Lock()
++ b := l.freeList
++ if b != nil {
++ l.freeList = b.next
++ }
++ l.freeListMu.Unlock()
++ if b == nil {
++ b = new(buffer)
++ } else {
++ b.next = nil
++ b.Reset()
++ }
++ return b
++}
++
++// putBuffer returns a buffer to the free list.
++func (l *loggingT) putBuffer(b *buffer) {
++ if b.Len() >= 256 {
++ // Let big buffers die a natural death.
++ return
++ }
++ l.freeListMu.Lock()
++ b.next = l.freeList
++ l.freeList = b
++ l.freeListMu.Unlock()
++}
++
++var timeNow = time.Now // Stubbed out for testing.
++
++/*
++header formats a log header as defined by the C++ implementation.
++It returns a buffer containing the formatted header and the user's file and line number.
++The depth specifies how many stack frames above lives the source line to be identified in the log message.
++
++Log lines have this form:
++ Lmmdd hh:mm:ss.uuuuuu threadid file:line] msg...
++where the fields are defined as follows:
++ L A single character, representing the log level (eg 'I' for INFO)
++ mm The month (zero padded; ie May is '05')
++ dd The day (zero padded)
++ hh:mm:ss.uuuuuu Time in hours, minutes and fractional seconds
++ threadid The space-padded thread ID as returned by GetTID()
++ file The file name
++ line The line number
++ msg The user-supplied message
++*/
++func (l *loggingT) header(s severity, depth int) (*buffer, string, int) {
++ _, file, line, ok := runtime.Caller(3 + depth)
++ if !ok {
++ file = "???"
++ line = 1
++ } else {
++ slash := strings.LastIndex(file, "/")
++ if slash >= 0 {
++ file = file[slash+1:]
++ }
++ }
++ return l.formatHeader(s, file, line), file, line
++}
++
++// formatHeader formats a log header using the provided file name and line number.
++func (l *loggingT) formatHeader(s severity, file string, line int) *buffer {
++ now := timeNow()
++ if line < 0 {
++ line = 0 // not a real line number, but acceptable to someDigits
++ }
++ if s > fatalLog {
++ s = infoLog // for safety.
++ }
++ buf := l.getBuffer()
++ if l.skipHeaders {
++ return buf
++ }
++
++ // Avoid Fprintf, for speed. The format is so simple that we can do it quickly by hand.
++ // It's worth about 3X. Fprintf is hard.
++ _, month, day := now.Date()
++ hour, minute, second := now.Clock()
++ // Lmmdd hh:mm:ss.uuuuuu threadid file:line]
++ buf.tmp[0] = severityChar[s]
++ buf.twoDigits(1, int(month))
++ buf.twoDigits(3, day)
++ buf.tmp[5] = ' '
++ buf.twoDigits(6, hour)
++ buf.tmp[8] = ':'
++ buf.twoDigits(9, minute)
++ buf.tmp[11] = ':'
++ buf.twoDigits(12, second)
++ buf.tmp[14] = '.'
++ buf.nDigits(6, 15, now.Nanosecond()/1000, '0')
++ buf.tmp[21] = ' '
++ buf.nDigits(7, 22, pid, ' ') // TODO: should be TID
++ buf.tmp[29] = ' '
++ buf.Write(buf.tmp[:30])
++ buf.WriteString(file)
++ buf.tmp[0] = ':'
++ n := buf.someDigits(1, line)
++ buf.tmp[n+1] = ']'
++ buf.tmp[n+2] = ' '
++ buf.Write(buf.tmp[:n+3])
++ return buf
++}
++
++// Some custom tiny helper functions to print the log header efficiently.
++
++const digits = "0123456789"
++
++// twoDigits formats a zero-prefixed two-digit integer at buf.tmp[i].
++func (buf *buffer) twoDigits(i, d int) {
++ buf.tmp[i+1] = digits[d%10]
++ d /= 10
++ buf.tmp[i] = digits[d%10]
++}
++
++// nDigits formats an n-digit integer at buf.tmp[i],
++// padding with pad on the left.
++// It assumes d >= 0.
++func (buf *buffer) nDigits(n, i, d int, pad byte) {
++ j := n - 1
++ for ; j >= 0 && d > 0; j-- {
++ buf.tmp[i+j] = digits[d%10]
++ d /= 10
++ }
++ for ; j >= 0; j-- {
++ buf.tmp[i+j] = pad
++ }
++}
++
++// someDigits formats a zero-prefixed variable-width integer at buf.tmp[i].
++func (buf *buffer) someDigits(i, d int) int {
++ // Print into the top, then copy down. We know there's space for at least
++ // a 10-digit number.
++ j := len(buf.tmp)
++ for {
++ j--
++ buf.tmp[j] = digits[d%10]
++ d /= 10
++ if d == 0 {
++ break
++ }
++ }
++ return copy(buf.tmp[i:], buf.tmp[j:])
++}
++
++func (l *loggingT) println(s severity, args ...interface{}) {
++ buf, file, line := l.header(s, 0)
++ fmt.Fprintln(buf, args...)
++ l.output(s, buf, file, line, false)
++}
++
++func (l *loggingT) print(s severity, args ...interface{}) {
++ l.printDepth(s, 1, args...)
++}
++
++func (l *loggingT) printDepth(s severity, depth int, args ...interface{}) {
++ buf, file, line := l.header(s, depth)
++ fmt.Fprint(buf, args...)
++ if buf.Bytes()[buf.Len()-1] != '\n' {
++ buf.WriteByte('\n')
++ }
++ l.output(s, buf, file, line, false)
++}
++
++func (l *loggingT) printf(s severity, format string, args ...interface{}) {
++ buf, file, line := l.header(s, 0)
++ fmt.Fprintf(buf, format, args...)
++ if buf.Bytes()[buf.Len()-1] != '\n' {
++ buf.WriteByte('\n')
++ }
++ l.output(s, buf, file, line, false)
++}
++
++// printWithFileLine behaves like print but uses the provided file and line number. If
++// alsoLogToStderr is true, the log message always appears on standard error; it
++// will also appear in the log file unless --logtostderr is set.
++func (l *loggingT) printWithFileLine(s severity, file string, line int, alsoToStderr bool, args ...interface{}) {
++ buf := l.formatHeader(s, file, line)
++ fmt.Fprint(buf, args...)
++ if buf.Bytes()[buf.Len()-1] != '\n' {
++ buf.WriteByte('\n')
++ }
++ l.output(s, buf, file, line, alsoToStderr)
++}
++
++// redirectBuffer is used to set an alternate destination for the logs
++type redirectBuffer struct {
++ w io.Writer
++}
++
++func (rb *redirectBuffer) Sync() error {
++ return nil
++}
++
++func (rb *redirectBuffer) Flush() error {
++ return nil
++}
++
++func (rb *redirectBuffer) Write(bytes []byte) (n int, err error) {
++ return rb.w.Write(bytes)
++}
++
++// SetOutput sets the output destination for all severities
++func SetOutput(w io.Writer) {
++ for s := fatalLog; s >= infoLog; s-- {
++ rb := &redirectBuffer{
++ w: w,
++ }
++ logging.file[s] = rb
++ }
++}
++
++// SetOutputBySeverity sets the output destination for specific severity
++func SetOutputBySeverity(name string, w io.Writer) {
++ sev, ok := severityByName(name)
++ if !ok {
++ panic(fmt.Sprintf("SetOutputBySeverity(%q): unrecognized severity name", name))
++ }
++ rb := &redirectBuffer{
++ w: w,
++ }
++ logging.file[sev] = rb
++}
++
++// output writes the data to the log files and releases the buffer.
++func (l *loggingT) output(s severity, buf *buffer, file string, line int, alsoToStderr bool) {
++ l.mu.Lock()
++ if l.traceLocation.isSet() {
++ if l.traceLocation.match(file, line) {
++ buf.Write(stacks(false))
++ }
++ }
++ data := buf.Bytes()
++ if l.toStderr {
++ os.Stderr.Write(data)
++ } else {
++ if alsoToStderr || l.alsoToStderr || s >= l.stderrThreshold.get() {
++ os.Stderr.Write(data)
++ }
++ if l.file[s] == nil {
++ if err := l.createFiles(s); err != nil {
++ os.Stderr.Write(data) // Make sure the message appears somewhere.
++ l.exit(err)
++ }
++ }
++ switch s {
++ case fatalLog:
++ l.file[fatalLog].Write(data)
++ fallthrough
++ case errorLog:
++ l.file[errorLog].Write(data)
++ fallthrough
++ case warningLog:
++ l.file[warningLog].Write(data)
++ fallthrough
++ case infoLog:
++ l.file[infoLog].Write(data)
++ }
++ }
++ if s == fatalLog {
++ // If we got here via Exit rather than Fatal, print no stacks.
++ if atomic.LoadUint32(&fatalNoStacks) > 0 {
++ l.mu.Unlock()
++ timeoutFlush(10 * time.Second)
++ os.Exit(1)
++ }
++ // Dump all goroutine stacks before exiting.
++ // First, make sure we see the trace for the current goroutine on standard error.
++ // If -logtostderr has been specified, the loop below will do that anyway
++ // as the first stack in the full dump.
++ if !l.toStderr {
++ os.Stderr.Write(stacks(false))
++ }
++ // Write the stack trace for all goroutines to the files.
++ trace := stacks(true)
++ logExitFunc = func(error) {} // If we get a write error, we'll still exit below.
++ for log := fatalLog; log >= infoLog; log-- {
++ if f := l.file[log]; f != nil { // Can be nil if -logtostderr is set.
++ f.Write(trace)
++ }
++ }
++ l.mu.Unlock()
++ timeoutFlush(10 * time.Second)
++ os.Exit(255) // C++ uses -1, which is silly because it's anded with 255 anyway.
++ }
++ l.putBuffer(buf)
++ l.mu.Unlock()
++ if stats := severityStats[s]; stats != nil {
++ atomic.AddInt64(&stats.lines, 1)
++ atomic.AddInt64(&stats.bytes, int64(len(data)))
++ }
++}
++
++// timeoutFlush calls Flush and returns when it completes or after timeout
++// elapses, whichever happens first. This is needed because the hooks invoked
++// by Flush may deadlock when glog.Fatal is called from a hook that holds
++// a lock.
++func timeoutFlush(timeout time.Duration) {
++ done := make(chan bool, 1)
++ go func() {
++ Flush() // calls logging.lockAndFlushAll()
++ done <- true
++ }()
++ select {
++ case <-done:
++ case <-time.After(timeout):
++ fmt.Fprintln(os.Stderr, "glog: Flush took longer than", timeout)
++ }
++}
++
++// stacks is a wrapper for runtime.Stack that attempts to recover the data for all goroutines.
++func stacks(all bool) []byte {
++ // We don't know how big the traces are, so grow a few times if they don't fit. Start large, though.
++ n := 10000
++ if all {
++ n = 100000
++ }
++ var trace []byte
++ for i := 0; i < 5; i++ {
++ trace = make([]byte, n)
++ nbytes := runtime.Stack(trace, all)
++ if nbytes < len(trace) {
++ return trace[:nbytes]
++ }
++ n *= 2
++ }
++ return trace
++}
++
++// logExitFunc provides a simple mechanism to override the default behavior
++// of exiting on error. Used in testing and to guarantee we reach a required exit
++// for fatal logs. Instead, exit could be a function rather than a method but that
++// would make its use clumsier.
++var logExitFunc func(error)
++
++// exit is called if there is trouble creating or writing log files.
++// It flushes the logs and exits the program; there's no point in hanging around.
++// l.mu is held.
++func (l *loggingT) exit(err error) {
++ fmt.Fprintf(os.Stderr, "log: exiting because of error: %s\n", err)
++ // If logExitFunc is set, we do that instead of exiting.
++ if logExitFunc != nil {
++ logExitFunc(err)
++ return
++ }
++ l.flushAll()
++ os.Exit(2)
++}
++
++// syncBuffer joins a bufio.Writer to its underlying file, providing access to the
++// file's Sync method and providing a wrapper for the Write method that provides log
++// file rotation. There are conflicting methods, so the file cannot be embedded.
++// l.mu is held for all its methods.
++type syncBuffer struct {
++ logger *loggingT
++ *bufio.Writer
++ file *os.File
++ sev severity
++ nbytes uint64 // The number of bytes written to this file
++}
++
++func (sb *syncBuffer) Sync() error {
++ return sb.file.Sync()
++}
++
++func (sb *syncBuffer) Write(p []byte) (n int, err error) {
++ if sb.nbytes+uint64(len(p)) >= MaxSize {
++ if err := sb.rotateFile(time.Now(), false); err != nil {
++ sb.logger.exit(err)
++ }
++ }
++ n, err = sb.Writer.Write(p)
++ sb.nbytes += uint64(n)
++ if err != nil {
++ sb.logger.exit(err)
++ }
++ return
++}
++
++// rotateFile closes the syncBuffer's file and starts a new one.
++// The startup argument indicates whether this is the initial startup of klog.
++// If startup is true, existing files are opened for apending instead of truncated.
++func (sb *syncBuffer) rotateFile(now time.Time, startup bool) error {
++ if sb.file != nil {
++ sb.Flush()
++ sb.file.Close()
++ }
++ var err error
++ sb.file, _, err = create(severityName[sb.sev], now, startup)
++ sb.nbytes = 0
++ if err != nil {
++ return err
++ }
++
++ sb.Writer = bufio.NewWriterSize(sb.file, bufferSize)
++
++ // Write header.
++ var buf bytes.Buffer
++ fmt.Fprintf(&buf, "Log file created at: %s\n", now.Format("2006/01/02 15:04:05"))
++ fmt.Fprintf(&buf, "Running on machine: %s\n", host)
++ fmt.Fprintf(&buf, "Binary: Built with %s %s for %s/%s\n", runtime.Compiler, runtime.Version(), runtime.GOOS, runtime.GOARCH)
++ fmt.Fprintf(&buf, "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg\n")
++ n, err := sb.file.Write(buf.Bytes())
++ sb.nbytes += uint64(n)
++ return err
++}
++
++// bufferSize sizes the buffer associated with each log file. It's large
++// so that log records can accumulate without the logging thread blocking
++// on disk I/O. The flushDaemon will block instead.
++const bufferSize = 256 * 1024
++
++// createFiles creates all the log files for severity from sev down to infoLog.
++// l.mu is held.
++func (l *loggingT) createFiles(sev severity) error {
++ now := time.Now()
++ // Files are created in decreasing severity order, so as soon as we find one
++ // has already been created, we can stop.
++ for s := sev; s >= infoLog && l.file[s] == nil; s-- {
++ sb := &syncBuffer{
++ logger: l,
++ sev: s,
++ }
++ if err := sb.rotateFile(now, true); err != nil {
++ return err
++ }
++ l.file[s] = sb
++ }
++ return nil
++}
++
++const flushInterval = 5 * time.Second
++
++// flushDaemon periodically flushes the log file buffers.
++func (l *loggingT) flushDaemon() {
++ for range time.NewTicker(flushInterval).C {
++ l.lockAndFlushAll()
++ }
++}
++
++// lockAndFlushAll is like flushAll but locks l.mu first.
++func (l *loggingT) lockAndFlushAll() {
++ l.mu.Lock()
++ l.flushAll()
++ l.mu.Unlock()
++}
++
++// flushAll flushes all the logs and attempts to "sync" their data to disk.
++// l.mu is held.
++func (l *loggingT) flushAll() {
++ // Flush from fatal down, in case there's trouble flushing.
++ for s := fatalLog; s >= infoLog; s-- {
++ file := l.file[s]
++ if file != nil {
++ file.Flush() // ignore error
++ file.Sync() // ignore error
++ }
++ }
++}
++
++// CopyStandardLogTo arranges for messages written to the Go "log" package's
++// default logs to also appear in the Google logs for the named and lower
++// severities. Subsequent changes to the standard log's default output location
++// or format may break this behavior.
++//
++// Valid names are "INFO", "WARNING", "ERROR", and "FATAL". If the name is not
++// recognized, CopyStandardLogTo panics.
++func CopyStandardLogTo(name string) {
++ sev, ok := severityByName(name)
++ if !ok {
++ panic(fmt.Sprintf("log.CopyStandardLogTo(%q): unrecognized severity name", name))
++ }
++ // Set a log format that captures the user's file and line:
++ // d.go:23: message
++ stdLog.SetFlags(stdLog.Lshortfile)
++ stdLog.SetOutput(logBridge(sev))
++}
++
++// logBridge provides the Write method that enables CopyStandardLogTo to connect
++// Go's standard logs to the logs provided by this package.
++type logBridge severity
++
++// Write parses the standard logging line and passes its components to the
++// logger for severity(lb).
++func (lb logBridge) Write(b []byte) (n int, err error) {
++ var (
++ file = "???"
++ line = 1
++ text string
++ )
++ // Split "d.go:23: message" into "d.go", "23", and "message".
++ if parts := bytes.SplitN(b, []byte{':'}, 3); len(parts) != 3 || len(parts[0]) < 1 || len(parts[2]) < 1 {
++ text = fmt.Sprintf("bad log format: %s", b)
++ } else {
++ file = string(parts[0])
++ text = string(parts[2][1:]) // skip leading space
++ line, err = strconv.Atoi(string(parts[1]))
++ if err != nil {
++ text = fmt.Sprintf("bad line number: %s", b)
++ line = 1
++ }
++ }
++ // printWithFileLine with alsoToStderr=true, so standard log messages
++ // always appear on standard error.
++ logging.printWithFileLine(severity(lb), file, line, true, text)
++ return len(b), nil
++}
++
++// setV computes and remembers the V level for a given PC
++// when vmodule is enabled.
++// File pattern matching takes the basename of the file, stripped
++// of its .go suffix, and uses filepath.Match, which is a little more
++// general than the *? matching used in C++.
++// l.mu is held.
++func (l *loggingT) setV(pc uintptr) Level {
++ fn := runtime.FuncForPC(pc)
++ file, _ := fn.FileLine(pc)
++ // The file is something like /a/b/c/d.go. We want just the d.
++ if strings.HasSuffix(file, ".go") {
++ file = file[:len(file)-3]
++ }
++ if slash := strings.LastIndex(file, "/"); slash >= 0 {
++ file = file[slash+1:]
++ }
++ for _, filter := range l.vmodule.filter {
++ if filter.match(file) {
++ l.vmap[pc] = filter.level
++ return filter.level
++ }
++ }
++ l.vmap[pc] = 0
++ return 0
++}
++
++// Verbose is a boolean type that implements Infof (like Printf) etc.
++// See the documentation of V for more information.
++type Verbose bool
++
++// V reports whether verbosity at the call site is at least the requested level.
++// The returned value is a boolean of type Verbose, which implements Info, Infoln
++// and Infof. These methods will write to the Info log if called.
++// Thus, one may write either
++// if glog.V(2) { glog.Info("log this") }
++// or
++// glog.V(2).Info("log this")
++// The second form is shorter but the first is cheaper if logging is off because it does
++// not evaluate its arguments.
++//
++// Whether an individual call to V generates a log record depends on the setting of
++// the -v and --vmodule flags; both are off by default. If the level in the call to
++// V is at least the value of -v, or of -vmodule for the source file containing the
++// call, the V call will log.
++func V(level Level) Verbose {
++ // This function tries hard to be cheap unless there's work to do.
++ // The fast path is two atomic loads and compares.
++
++ // Here is a cheap but safe test to see if V logging is enabled globally.
++ if logging.verbosity.get() >= level {
++ return Verbose(true)
++ }
++
++ // It's off globally but it vmodule may still be set.
++ // Here is another cheap but safe test to see if vmodule is enabled.
++ if atomic.LoadInt32(&logging.filterLength) > 0 {
++ // Now we need a proper lock to use the logging structure. The pcs field
++ // is shared so we must lock before accessing it. This is fairly expensive,
++ // but if V logging is enabled we're slow anyway.
++ logging.mu.Lock()
++ defer logging.mu.Unlock()
++ if runtime.Callers(2, logging.pcs[:]) == 0 {
++ return Verbose(false)
++ }
++ v, ok := logging.vmap[logging.pcs[0]]
++ if !ok {
++ v = logging.setV(logging.pcs[0])
++ }
++ return Verbose(v >= level)
++ }
++ return Verbose(false)
++}
++
++// Info is equivalent to the global Info function, guarded by the value of v.
++// See the documentation of V for usage.
++func (v Verbose) Info(args ...interface{}) {
++ if v {
++ logging.print(infoLog, args...)
++ }
++}
++
++// Infoln is equivalent to the global Infoln function, guarded by the value of v.
++// See the documentation of V for usage.
++func (v Verbose) Infoln(args ...interface{}) {
++ if v {
++ logging.println(infoLog, args...)
++ }
++}
++
++// Infof is equivalent to the global Infof function, guarded by the value of v.
++// See the documentation of V for usage.
++func (v Verbose) Infof(format string, args ...interface{}) {
++ if v {
++ logging.printf(infoLog, format, args...)
++ }
++}
++
++// Info logs to the INFO log.
++// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
++func Info(args ...interface{}) {
++ logging.print(infoLog, args...)
++}
++
++// InfoDepth acts as Info but uses depth to determine which call frame to log.
++// InfoDepth(0, "msg") is the same as Info("msg").
++func InfoDepth(depth int, args ...interface{}) {
++ logging.printDepth(infoLog, depth, args...)
++}
++
++// Infoln logs to the INFO log.
++// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
++func Infoln(args ...interface{}) {
++ logging.println(infoLog, args...)
++}
++
++// Infof logs to the INFO log.
++// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
++func Infof(format string, args ...interface{}) {
++ logging.printf(infoLog, format, args...)
++}
++
++// Warning logs to the WARNING and INFO logs.
++// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
++func Warning(args ...interface{}) {
++ logging.print(warningLog, args...)
++}
++
++// WarningDepth acts as Warning but uses depth to determine which call frame to log.
++// WarningDepth(0, "msg") is the same as Warning("msg").
++func WarningDepth(depth int, args ...interface{}) {
++ logging.printDepth(warningLog, depth, args...)
++}
++
++// Warningln logs to the WARNING and INFO logs.
++// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
++func Warningln(args ...interface{}) {
++ logging.println(warningLog, args...)
++}
++
++// Warningf logs to the WARNING and INFO logs.
++// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
++func Warningf(format string, args ...interface{}) {
++ logging.printf(warningLog, format, args...)
++}
++
++// Error logs to the ERROR, WARNING, and INFO logs.
++// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
++func Error(args ...interface{}) {
++ logging.print(errorLog, args...)
++}
++
++// ErrorDepth acts as Error but uses depth to determine which call frame to log.
++// ErrorDepth(0, "msg") is the same as Error("msg").
++func ErrorDepth(depth int, args ...interface{}) {
++ logging.printDepth(errorLog, depth, args...)
++}
++
++// Errorln logs to the ERROR, WARNING, and INFO logs.
++// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
++func Errorln(args ...interface{}) {
++ logging.println(errorLog, args...)
++}
++
++// Errorf logs to the ERROR, WARNING, and INFO logs.
++// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
++func Errorf(format string, args ...interface{}) {
++ logging.printf(errorLog, format, args...)
++}
++
++// Fatal logs to the FATAL, ERROR, WARNING, and INFO logs,
++// including a stack trace of all running goroutines, then calls os.Exit(255).
++// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
++func Fatal(args ...interface{}) {
++ logging.print(fatalLog, args...)
++}
++
++// FatalDepth acts as Fatal but uses depth to determine which call frame to log.
++// FatalDepth(0, "msg") is the same as Fatal("msg").
++func FatalDepth(depth int, args ...interface{}) {
++ logging.printDepth(fatalLog, depth, args...)
++}
++
++// Fatalln logs to the FATAL, ERROR, WARNING, and INFO logs,
++// including a stack trace of all running goroutines, then calls os.Exit(255).
++// Arguments are handled in the manner of fmt.Println; a newline is appended if missing.
++func Fatalln(args ...interface{}) {
++ logging.println(fatalLog, args...)
++}
++
++// Fatalf logs to the FATAL, ERROR, WARNING, and INFO logs,
++// including a stack trace of all running goroutines, then calls os.Exit(255).
++// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
++func Fatalf(format string, args ...interface{}) {
++ logging.printf(fatalLog, format, args...)
++}
++
++// fatalNoStacks is non-zero if we are to exit without dumping goroutine stacks.
++// It allows Exit and relatives to use the Fatal logs.
++var fatalNoStacks uint32
++
++// Exit logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
++// Arguments are handled in the manner of fmt.Print; a newline is appended if missing.
++func Exit(args ...interface{}) {
++ atomic.StoreUint32(&fatalNoStacks, 1)
++ logging.print(fatalLog, args...)
++}
++
++// ExitDepth acts as Exit but uses depth to determine which call frame to log.
++// ExitDepth(0, "msg") is the same as Exit("msg").
++func ExitDepth(depth int, args ...interface{}) {
++ atomic.StoreUint32(&fatalNoStacks, 1)
++ logging.printDepth(fatalLog, depth, args...)
++}
++
++// Exitln logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
++func Exitln(args ...interface{}) {
++ atomic.StoreUint32(&fatalNoStacks, 1)
++ logging.println(fatalLog, args...)
++}
++
++// Exitf logs to the FATAL, ERROR, WARNING, and INFO logs, then calls os.Exit(1).
++// Arguments are handled in the manner of fmt.Printf; a newline is appended if missing.
++func Exitf(format string, args ...interface{}) {
++ atomic.StoreUint32(&fatalNoStacks, 1)
++ logging.printf(fatalLog, format, args...)
++}
+diff --git a/vendor/k8s.io/klog/klog_file.go b/vendor/k8s.io/klog/klog_file.go
+new file mode 100644
+index 0000000..1c4897f
+--- /dev/null
++++ b/vendor/k8s.io/klog/klog_file.go
+@@ -0,0 +1,139 @@
++// Go support for leveled logs, analogous to https://code.google.com/p/google-glog/
++//
++// Copyright 2013 Google Inc. 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.
++
++// File I/O for logs.
++
++package klog
++
++import (
++ "errors"
++ "fmt"
++ "os"
++ "os/user"
++ "path/filepath"
++ "strings"
++ "sync"
++ "time"
++)
++
++// MaxSize is the maximum size of a log file in bytes.
++var MaxSize uint64 = 1024 * 1024 * 1800
++
++// logDirs lists the candidate directories for new log files.
++var logDirs []string
++
++func createLogDirs() {
++ if logging.logDir != "" {
++ logDirs = append(logDirs, logging.logDir)
++ }
++ logDirs = append(logDirs, os.TempDir())
++}
++
++var (
++ pid = os.Getpid()
++ program = filepath.Base(os.Args[0])
++ host = "unknownhost"
++ userName = "unknownuser"
++)
++
++func init() {
++ h, err := os.Hostname()
++ if err == nil {
++ host = shortHostname(h)
++ }
++
++ current, err := user.Current()
++ if err == nil {
++ userName = current.Username
++ }
++
++ // Sanitize userName since it may contain filepath separators on Windows.
++ userName = strings.Replace(userName, `\`, "_", -1)
++}
++
++// shortHostname returns its argument, truncating at the first period.
++// For instance, given "www.google.com" it returns "www".
++func shortHostname(hostname string) string {
++ if i := strings.Index(hostname, "."); i >= 0 {
++ return hostname[:i]
++ }
++ return hostname
++}
++
++// logName returns a new log file name containing tag, with start time t, and
++// the name for the symlink for tag.
++func logName(tag string, t time.Time) (name, link string) {
++ name = fmt.Sprintf("%s.%s.%s.log.%s.%04d%02d%02d-%02d%02d%02d.%d",
++ program,
++ host,
++ userName,
++ tag,
++ t.Year(),
++ t.Month(),
++ t.Day(),
++ t.Hour(),
++ t.Minute(),
++ t.Second(),
++ pid)
++ return name, program + "." + tag
++}
++
++var onceLogDirs sync.Once
++
++// create creates a new log file and returns the file and its filename, which
++// contains tag ("INFO", "FATAL", etc.) and t. If the file is created
++// successfully, create also attempts to update the symlink for that tag, ignoring
++// errors.
++// The startup argument indicates whether this is the initial startup of klog.
++// If startup is true, existing files are opened for apending instead of truncated.
++func create(tag string, t time.Time, startup bool) (f *os.File, filename string, err error) {
++ if logging.logFile != "" {
++ f, err := openOrCreate(logging.logFile, startup)
++ if err == nil {
++ return f, logging.logFile, nil
++ }
++ return nil, "", fmt.Errorf("log: unable to create log: %v", err)
++ }
++ onceLogDirs.Do(createLogDirs)
++ if len(logDirs) == 0 {
++ return nil, "", errors.New("log: no log dirs")
++ }
++ name, link := logName(tag, t)
++ var lastErr error
++ for _, dir := range logDirs {
++ fname := filepath.Join(dir, name)
++ f, err := openOrCreate(fname, startup)
++ if err == nil {
++ symlink := filepath.Join(dir, link)
++ os.Remove(symlink) // ignore err
++ os.Symlink(name, symlink) // ignore err
++ return f, fname, nil
++ }
++ lastErr = err
++ }
++ return nil, "", fmt.Errorf("log: cannot create log: %v", lastErr)
++}
++
++// The startup argument indicates whether this is the initial startup of klog.
++// If startup is true, existing files are opened for appending instead of truncated.
++func openOrCreate(name string, startup bool) (*os.File, error) {
++ if startup {
++ f, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
++ return f, err
++ }
++ f, err := os.Create(name)
++ return f, err
++}
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..231ad34
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,3 @@
+ftbfs-arm.patch
+klog.patch
+ignore-arch-tests.patch
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..9385ef3
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,13 @@
+#!/usr/bin/make -f
+
+# install all files for dockerfile/parser to pickup the various testfiles
+# Ideally, upstream would move all test files out to 'testdata/', which seems
+# to be a common best-practice in many other golang projects, and
+# detected automatically by the golang debhelper
+export DH_GOLANG_INSTALL_EXTRA := dockerfile/parser
+
+# avoid installing test utility
+export DH_GOLANG_EXCLUDES := dumper
+
+%:
+ dh $@ --buildsystem=golang --with=golang
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debian/source/lintian-overrides b/debian/source/lintian-overrides
new file mode 100644
index 0000000..53a1f62
--- /dev/null
+++ b/debian/source/lintian-overrides
@@ -0,0 +1,2 @@
+# contains testdata that is not really an .a archive
+golang-github-openshift-imagebuilder source: unpack-message-for-orig
diff --git a/debian/upstream/metadata b/debian/upstream/metadata
new file mode 100644
index 0000000..f69b88a
--- /dev/null
+++ b/debian/upstream/metadata
@@ -0,0 +1,5 @@
+---
+Bug-Database: https://github.com/openshift/imagebuilder/issues
+Bug-Submit: https://github.com/openshift/imagebuilder/issues/new
+Repository: https://github.com/openshift/imagebuilder.git
+Repository-Browse: https://github.com/openshift/imagebuilder
diff --git a/debian/watch b/debian/watch
new file mode 100644
index 0000000..ecb9d10
--- /dev/null
+++ b/debian/watch
@@ -0,0 +1,10 @@
+version=4
+opts="\
+pgpmode=none,\
+repacksuffix=+ds1,\
+repack,compression=xz,\
+dirversionmangle=s/-rc/~rc/,\
+uversionmangle=s/-rc/~rc/,\
+dversionmangle=s{[+~]ds\d*}{},\
+" https://github.com/openshift/imagebuilder/tags \
+ .*/v?@ANY_VERSION@@ARCHIVE_EXT@