mirror of
https://github.com/NVIDIA/nvidia-container-toolkit
synced 2025-06-26 18:18:24 +00:00
Run go mod vendor and tidy
Signed-off-by: Evan Lezar <elezar@nvidia.com>
This commit is contained in:
4
go.mod
4
go.mod
@@ -4,6 +4,10 @@ go 1.14
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/NVIDIA/go-nvml v0.11.1-0
|
||||
github.com/opencontainers/runtime-spec v1.0.2
|
||||
github.com/pelletier/go-toml v1.9.3
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
golang.org/x/mod v0.3.0
|
||||
)
|
||||
|
||||
8
go.sum
8
go.sum
@@ -1,8 +1,15 @@
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/NVIDIA/go-nvml v0.11.1-0/go.mod h1:hy7HYeQy335x6nEss0Ne3PYqleRa6Ct+VKD9RQ4nyFs=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
|
||||
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
@@ -13,6 +20,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
202
vendor/github.com/NVIDIA/go-nvml/LICENSE
generated
vendored
Normal file
202
vendor/github.com/NVIDIA/go-nvml/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.
|
||||
75
vendor/github.com/NVIDIA/go-nvml/pkg/dl/dl.go
generated
vendored
Normal file
75
vendor/github.com/NVIDIA/go-nvml/pkg/dl/dl.go
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright (c) 2020, NVIDIA CORPORATION. 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 dl
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// #cgo LDFLAGS: -ldl
|
||||
// #include <dlfcn.h>
|
||||
import "C"
|
||||
|
||||
const (
|
||||
RTLD_LAZY = C.RTLD_LAZY
|
||||
RTLD_NOW = C.RTLD_NOW
|
||||
RTLD_GLOBAL = C.RTLD_GLOBAL
|
||||
RTLD_LOCAL = C.RTLD_LOCAL
|
||||
RTLD_NODELETE = C.RTLD_NODELETE
|
||||
RTLD_NOLOAD = C.RTLD_NOLOAD
|
||||
RTLD_DEEPBIND = C.RTLD_DEEPBIND
|
||||
)
|
||||
|
||||
type DynamicLibrary struct{
|
||||
Name string
|
||||
Flags int
|
||||
handle unsafe.Pointer
|
||||
}
|
||||
|
||||
func New(name string, flags int) *DynamicLibrary {
|
||||
return &DynamicLibrary{
|
||||
Name: name,
|
||||
Flags: flags,
|
||||
handle: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func (dl *DynamicLibrary) Open() error {
|
||||
handle := C.dlopen(C.CString(dl.Name), C.int(dl.Flags))
|
||||
if handle == C.NULL {
|
||||
return fmt.Errorf("%s", C.GoString(C.dlerror()))
|
||||
}
|
||||
dl.handle = handle
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dl *DynamicLibrary) Close() error {
|
||||
err := C.dlclose(dl.handle)
|
||||
if err != 0 {
|
||||
return fmt.Errorf("%s", C.GoString(C.dlerror()))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dl *DynamicLibrary) Lookup(symbol string) error {
|
||||
C.dlerror() // Clear out any previous errors
|
||||
C.dlsym(dl.handle, C.CString(symbol))
|
||||
err := C.dlerror()
|
||||
if unsafe.Pointer(err) == C.NULL {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("%s", C.GoString(err))
|
||||
}
|
||||
64
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/cgo_helpers.go
generated
vendored
Normal file
64
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/cgo_helpers.go
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
// Copyright (c) 2020, NVIDIA CORPORATION. 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 nvml
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
import "C"
|
||||
|
||||
var cgoAllocsUnknown = new(struct{})
|
||||
|
||||
type stringHeader struct {
|
||||
Data unsafe.Pointer
|
||||
Len int
|
||||
}
|
||||
|
||||
func clen(n []byte) int {
|
||||
for i := 0; i < len(n); i++ {
|
||||
if n[i] == 0 {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return len(n)
|
||||
}
|
||||
|
||||
func uint32SliceToIntSlice(s []uint32) []int {
|
||||
ret := make([]int, len(s))
|
||||
for i := range s {
|
||||
ret[i] = int(s[i])
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// packPCharString creates a Go string backed by *C.char and avoids copying.
|
||||
func packPCharString(p *C.char) (raw string) {
|
||||
if p != nil && *p != 0 {
|
||||
h := (*stringHeader)(unsafe.Pointer(&raw))
|
||||
h.Data = unsafe.Pointer(p)
|
||||
for *p != 0 {
|
||||
p = (*C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + 1)) // p++
|
||||
}
|
||||
h.Len = int(uintptr(unsafe.Pointer(p)) - uintptr(h.Data))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// unpackPCharString represents the data from Go string as *C.char and avoids copying.
|
||||
func unpackPCharString(str string) (*C.char, *struct{}) {
|
||||
h := (*stringHeader)(unsafe.Pointer(&str))
|
||||
return (*C.char)(h.Data), cgoAllocsUnknown
|
||||
}
|
||||
23
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/cgo_helpers.h
generated
vendored
Normal file
23
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/cgo_helpers.h
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2020, NVIDIA CORPORATION. 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.
|
||||
|
||||
// WARNING: This file has automatically been generated on Wed, 03 Feb 2021 13:08:24 UTC.
|
||||
// Code generated by https://git.io/c-for-go. DO NOT EDIT.
|
||||
|
||||
#include "nvml.h"
|
||||
#include <stdlib.h>
|
||||
#pragma once
|
||||
|
||||
#define __CGOGEN 1
|
||||
|
||||
1010
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/const.go
generated
vendored
Normal file
1010
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/const.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1962
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/device.go
generated
vendored
Normal file
1962
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/device.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
21
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/doc.go
generated
vendored
Normal file
21
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/doc.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright (c) 2020, NVIDIA CORPORATION. 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.
|
||||
|
||||
// WARNING: This file has automatically been generated on Wed, 03 Feb 2021 13:08:24 UTC.
|
||||
// Code generated by https://git.io/c-for-go. DO NOT EDIT.
|
||||
|
||||
/*
|
||||
Package NVML bindings
|
||||
*/
|
||||
package nvml
|
||||
42
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/event_set.go
generated
vendored
Normal file
42
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/event_set.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) 2020, NVIDIA CORPORATION. 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 nvml
|
||||
|
||||
// nvml.EventSetCreate()
|
||||
func EventSetCreate() (EventSet, Return) {
|
||||
var Set EventSet
|
||||
ret := nvmlEventSetCreate(&Set)
|
||||
return Set, ret
|
||||
}
|
||||
|
||||
// nvml.EventSetWait()
|
||||
func EventSetWait(Set EventSet, Timeoutms uint32) (EventData, Return) {
|
||||
var Data EventData
|
||||
ret := nvmlEventSetWait(Set, &Data, Timeoutms)
|
||||
return Data, ret
|
||||
}
|
||||
|
||||
func (Set EventSet) Wait(Timeoutms uint32) (EventData, Return) {
|
||||
return EventSetWait(Set, Timeoutms)
|
||||
}
|
||||
|
||||
// nvml.EventSetFree()
|
||||
func EventSetFree(Set EventSet) Return {
|
||||
return nvmlEventSetFree(Set)
|
||||
}
|
||||
|
||||
func (Set EventSet) Free() Return {
|
||||
return EventSetFree(Set)
|
||||
}
|
||||
157
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/init.go
generated
vendored
Normal file
157
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/init.go
generated
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
// Copyright (c) 2020, NVIDIA CORPORATION. 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 nvml
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/NVIDIA/go-nvml/pkg/dl"
|
||||
)
|
||||
|
||||
import "C"
|
||||
|
||||
const (
|
||||
nvmlLibraryName = "libnvidia-ml.so.1"
|
||||
nvmlLibraryLoadFlags = dl.RTLD_LAZY | dl.RTLD_GLOBAL
|
||||
)
|
||||
|
||||
var nvml *dl.DynamicLibrary
|
||||
|
||||
// nvml.Init()
|
||||
func Init() Return {
|
||||
lib := dl.New(nvmlLibraryName, nvmlLibraryLoadFlags)
|
||||
if lib == nil {
|
||||
panic(fmt.Sprintf("error instantiating DynamicLibrary for %s", nvmlLibraryName))
|
||||
}
|
||||
|
||||
err := lib.Open()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error opening %s: %v", nvmlLibraryName, err))
|
||||
}
|
||||
|
||||
nvml = lib
|
||||
updateVersionedSymbols()
|
||||
|
||||
return nvmlInit()
|
||||
}
|
||||
|
||||
// nvml.InitWithFlags()
|
||||
func InitWithFlags(Flags uint32) Return {
|
||||
lib := dl.New(nvmlLibraryName, nvmlLibraryLoadFlags)
|
||||
if lib == nil {
|
||||
panic(fmt.Sprintf("error instantiating DynamicLibrary for %s", nvmlLibraryName))
|
||||
}
|
||||
|
||||
err := lib.Open()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error opening %s: %v", nvmlLibraryName, err))
|
||||
}
|
||||
|
||||
nvml = lib
|
||||
|
||||
return nvmlInitWithFlags(Flags)
|
||||
}
|
||||
|
||||
// nvml.Shutdown()
|
||||
func Shutdown() Return {
|
||||
ret := nvmlShutdown()
|
||||
if ret != SUCCESS {
|
||||
return ret
|
||||
}
|
||||
|
||||
err := nvml.Close()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("error closing %s: %v", nvmlLibraryName, err))
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// Default all versioned APIs to v1 (to infer the types)
|
||||
var nvmlInit = nvmlInit_v1
|
||||
var nvmlDeviceGetPciInfo = nvmlDeviceGetPciInfo_v1
|
||||
var nvmlDeviceGetCount = nvmlDeviceGetCount_v1
|
||||
var nvmlDeviceGetHandleByIndex = nvmlDeviceGetHandleByIndex_v1
|
||||
var nvmlDeviceGetHandleByPciBusId = nvmlDeviceGetHandleByPciBusId_v1
|
||||
var nvmlDeviceGetNvLinkRemotePciInfo = nvmlDeviceGetNvLinkRemotePciInfo_v1
|
||||
var nvmlDeviceRemoveGpu = nvmlDeviceRemoveGpu_v1
|
||||
var nvmlDeviceGetGridLicensableFeatures = nvmlDeviceGetGridLicensableFeatures_v1
|
||||
var nvmlEventSetWait = nvmlEventSetWait_v1
|
||||
var nvmlDeviceGetAttributes = nvmlDeviceGetAttributes_v1
|
||||
var nvmlDeviceGetComputeRunningProcesses = nvmlDeviceGetComputeRunningProcesses_v1
|
||||
var nvmlDeviceGetGraphicsRunningProcesses = nvmlDeviceGetGraphicsRunningProcesses_v1
|
||||
|
||||
// updateVersionedSymbols()
|
||||
func updateVersionedSymbols() {
|
||||
err := nvml.Lookup("nvmlInit_v2")
|
||||
if err == nil {
|
||||
nvmlInit = nvmlInit_v2
|
||||
}
|
||||
err = nvml.Lookup("nvmlDeviceGetPciInfo_v2")
|
||||
if err == nil {
|
||||
nvmlDeviceGetPciInfo = nvmlDeviceGetPciInfo_v2
|
||||
}
|
||||
err = nvml.Lookup("nvmlDeviceGetPciInfo_v3")
|
||||
if err == nil {
|
||||
nvmlDeviceGetPciInfo = nvmlDeviceGetPciInfo_v3
|
||||
}
|
||||
err = nvml.Lookup("nvmlDeviceGetCount_v2")
|
||||
if err == nil {
|
||||
nvmlDeviceGetCount = nvmlDeviceGetCount_v2
|
||||
}
|
||||
err = nvml.Lookup("nvmlDeviceGetHandleByIndex_v2")
|
||||
if err == nil {
|
||||
nvmlDeviceGetHandleByIndex = nvmlDeviceGetHandleByIndex_v2
|
||||
}
|
||||
err = nvml.Lookup("nvmlDeviceGetHandleByPciBusId_v2")
|
||||
if err == nil {
|
||||
nvmlDeviceGetHandleByPciBusId = nvmlDeviceGetHandleByPciBusId_v2
|
||||
}
|
||||
err = nvml.Lookup("nvmlDeviceGetNvLinkRemotePciInfo_v2")
|
||||
if err == nil {
|
||||
nvmlDeviceGetNvLinkRemotePciInfo = nvmlDeviceGetNvLinkRemotePciInfo_v2
|
||||
}
|
||||
// Unable to overwrite nvmlDeviceRemoveGpu() because the v2 function takes
|
||||
// a different set of parameters than the v1 function.
|
||||
//err = nvml.Lookup("nvmlDeviceRemoveGpu_v2")
|
||||
//if err == nil {
|
||||
// nvmlDeviceRemoveGpu = nvmlDeviceRemoveGpu_v2
|
||||
//}
|
||||
err = nvml.Lookup("nvmlDeviceGetGridLicensableFeatures_v2")
|
||||
if err == nil {
|
||||
nvmlDeviceGetGridLicensableFeatures = nvmlDeviceGetGridLicensableFeatures_v2
|
||||
}
|
||||
err = nvml.Lookup("nvmlDeviceGetGridLicensableFeatures_v3")
|
||||
if err == nil {
|
||||
nvmlDeviceGetGridLicensableFeatures = nvmlDeviceGetGridLicensableFeatures_v3
|
||||
}
|
||||
err = nvml.Lookup("nvmlEventSetWait_v2")
|
||||
if err == nil {
|
||||
nvmlEventSetWait = nvmlEventSetWait_v2
|
||||
}
|
||||
err = nvml.Lookup("nvmlDeviceGetAttributes_v2")
|
||||
if err == nil {
|
||||
nvmlDeviceGetAttributes = nvmlDeviceGetAttributes_v2
|
||||
}
|
||||
err = nvml.Lookup("nvmlDeviceGetComputeRunningProcesses_v2")
|
||||
if err == nil {
|
||||
nvmlDeviceGetComputeRunningProcesses = nvmlDeviceGetComputeRunningProcesses_v2
|
||||
}
|
||||
err = nvml.Lookup("nvmlDeviceGetGraphicsRunningProcesses_v2")
|
||||
if err == nil {
|
||||
nvmlDeviceGetGraphicsRunningProcesses = nvmlDeviceGetGraphicsRunningProcesses_v2
|
||||
}
|
||||
|
||||
}
|
||||
2307
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/nvml.go
generated
vendored
Normal file
2307
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/nvml.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
7664
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/nvml.h
generated
vendored
Normal file
7664
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/nvml.h
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
20
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/return.go
generated
vendored
Normal file
20
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/return.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright (c) 2020, NVIDIA CORPORATION. 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 nvml
|
||||
|
||||
// nvml.ErrorString()
|
||||
func ErrorString(Result Return) string {
|
||||
return nvmlErrorString(Result)
|
||||
}
|
||||
84
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/system.go
generated
vendored
Normal file
84
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/system.go
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
// Copyright (c) 2020, NVIDIA CORPORATION. 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 nvml
|
||||
|
||||
// #include <sys/prctl.h>
|
||||
import "C"
|
||||
|
||||
// nvml.SystemGetDriverVersion()
|
||||
func SystemGetDriverVersion() (string, Return) {
|
||||
Version := make([]byte, SYSTEM_DRIVER_VERSION_BUFFER_SIZE)
|
||||
ret := nvmlSystemGetDriverVersion(&Version[0], SYSTEM_DRIVER_VERSION_BUFFER_SIZE)
|
||||
return string(Version[:clen(Version)]), ret
|
||||
}
|
||||
|
||||
// nvml.SystemGetNVMLVersion()
|
||||
func SystemGetNVMLVersion() (string, Return) {
|
||||
Version := make([]byte, SYSTEM_NVML_VERSION_BUFFER_SIZE)
|
||||
ret := nvmlSystemGetNVMLVersion(&Version[0], SYSTEM_NVML_VERSION_BUFFER_SIZE)
|
||||
return string(Version[:clen(Version)]), ret
|
||||
}
|
||||
|
||||
// nvml.SystemGetCudaDriverVersion()
|
||||
func SystemGetCudaDriverVersion() (int, Return) {
|
||||
var CudaDriverVersion int32
|
||||
ret := nvmlSystemGetCudaDriverVersion(&CudaDriverVersion)
|
||||
return int(CudaDriverVersion), ret
|
||||
}
|
||||
|
||||
// nvml.SystemGetCudaDriverVersion_v2()
|
||||
func SystemGetCudaDriverVersion_v2() (int, Return) {
|
||||
var CudaDriverVersion int32
|
||||
ret := nvmlSystemGetCudaDriverVersion_v2(&CudaDriverVersion)
|
||||
return int(CudaDriverVersion), ret
|
||||
}
|
||||
|
||||
// nvml.SystemGetProcessName()
|
||||
func SystemGetProcessName(Pid int) (string, Return) {
|
||||
Name := make([]byte, C.PR_SET_NAME)
|
||||
ret := nvmlSystemGetProcessName(uint32(Pid), &Name[0], C.PR_SET_NAME)
|
||||
return string(Name[:clen(Name)]), ret
|
||||
}
|
||||
|
||||
// nvml.SystemGetHicVersion()
|
||||
func SystemGetHicVersion() ([]HwbcEntry, Return) {
|
||||
var HwbcCount uint32 = 1 // Will be reduced upon returning
|
||||
for {
|
||||
HwbcEntries := make([]HwbcEntry, HwbcCount)
|
||||
ret := nvmlSystemGetHicVersion(&HwbcCount, &HwbcEntries[0])
|
||||
if ret == SUCCESS {
|
||||
return HwbcEntries[:HwbcCount], ret
|
||||
}
|
||||
if ret != ERROR_INSUFFICIENT_SIZE {
|
||||
return nil, ret
|
||||
}
|
||||
HwbcCount *= 2
|
||||
}
|
||||
}
|
||||
|
||||
// nvml.SystemGetTopologyGpuSet()
|
||||
func SystemGetTopologyGpuSet(CpuNumber int) ([]Device, Return) {
|
||||
var Count uint32
|
||||
ret := nvmlSystemGetTopologyGpuSet(uint32(CpuNumber), &Count, nil)
|
||||
if ret != SUCCESS {
|
||||
return nil, ret
|
||||
}
|
||||
if Count == 0 {
|
||||
return []Device{}, ret
|
||||
}
|
||||
DeviceArray := make([]Device, Count)
|
||||
ret = nvmlSystemGetTopologyGpuSet(uint32(CpuNumber), &Count, &DeviceArray[0])
|
||||
return DeviceArray, ret
|
||||
}
|
||||
345
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/types_gen.go
generated
vendored
Normal file
345
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/types_gen.go
generated
vendored
Normal file
@@ -0,0 +1,345 @@
|
||||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs types.go
|
||||
|
||||
package nvml
|
||||
|
||||
import "unsafe"
|
||||
|
||||
type Device struct {
|
||||
Handle *_Ctype_struct_nvmlDevice_st
|
||||
}
|
||||
|
||||
type PciInfo struct {
|
||||
BusIdLegacy [16]int8
|
||||
Domain uint32
|
||||
Bus uint32
|
||||
Device uint32
|
||||
PciDeviceId uint32
|
||||
PciSubSystemId uint32
|
||||
BusId [32]int8
|
||||
}
|
||||
|
||||
type EccErrorCounts struct {
|
||||
L1Cache uint64
|
||||
L2Cache uint64
|
||||
DeviceMemory uint64
|
||||
RegisterFile uint64
|
||||
}
|
||||
|
||||
type Utilization struct {
|
||||
Gpu uint32
|
||||
Memory uint32
|
||||
}
|
||||
|
||||
type Memory struct {
|
||||
Total uint64
|
||||
Free uint64
|
||||
Used uint64
|
||||
}
|
||||
|
||||
type BAR1Memory struct {
|
||||
Bar1Total uint64
|
||||
Bar1Free uint64
|
||||
Bar1Used uint64
|
||||
}
|
||||
|
||||
type ProcessInfo struct {
|
||||
Pid uint32
|
||||
UsedGpuMemory uint64
|
||||
GpuInstanceId uint32
|
||||
ComputeInstanceId uint32
|
||||
}
|
||||
|
||||
type DeviceAttributes struct {
|
||||
MultiprocessorCount uint32
|
||||
SharedCopyEngineCount uint32
|
||||
SharedDecoderCount uint32
|
||||
SharedEncoderCount uint32
|
||||
SharedJpegCount uint32
|
||||
SharedOfaCount uint32
|
||||
GpuInstanceSliceCount uint32
|
||||
ComputeInstanceSliceCount uint32
|
||||
MemorySizeMB uint64
|
||||
}
|
||||
|
||||
type RowRemapperHistogramValues struct {
|
||||
Max uint32
|
||||
High uint32
|
||||
Partial uint32
|
||||
Low uint32
|
||||
None uint32
|
||||
}
|
||||
|
||||
type NvLinkUtilizationControl struct {
|
||||
Units uint32
|
||||
Pktfilter uint32
|
||||
}
|
||||
|
||||
type BridgeChipInfo struct {
|
||||
Type uint32
|
||||
FwVersion uint32
|
||||
}
|
||||
|
||||
type BridgeChipHierarchy struct {
|
||||
BridgeCount uint8
|
||||
BridgeChipInfo [128]BridgeChipInfo
|
||||
}
|
||||
|
||||
const sizeofValue = unsafe.Sizeof([8]byte{})
|
||||
|
||||
type Value [sizeofValue]byte
|
||||
|
||||
type Sample struct {
|
||||
TimeStamp uint64
|
||||
SampleValue [8]byte
|
||||
}
|
||||
|
||||
type ViolationTime struct {
|
||||
ReferenceTime uint64
|
||||
ViolationTime uint64
|
||||
}
|
||||
|
||||
type VgpuTypeId uint32
|
||||
|
||||
type VgpuInstance uint32
|
||||
|
||||
type VgpuInstanceUtilizationSample struct {
|
||||
VgpuInstance uint32
|
||||
TimeStamp uint64
|
||||
SmUtil [8]byte
|
||||
MemUtil [8]byte
|
||||
EncUtil [8]byte
|
||||
DecUtil [8]byte
|
||||
}
|
||||
|
||||
type VgpuProcessUtilizationSample struct {
|
||||
VgpuInstance uint32
|
||||
Pid uint32
|
||||
ProcessName [64]int8
|
||||
TimeStamp uint64
|
||||
SmUtil uint32
|
||||
MemUtil uint32
|
||||
EncUtil uint32
|
||||
DecUtil uint32
|
||||
}
|
||||
|
||||
type ProcessUtilizationSample struct {
|
||||
Pid uint32
|
||||
TimeStamp uint64
|
||||
SmUtil uint32
|
||||
MemUtil uint32
|
||||
EncUtil uint32
|
||||
DecUtil uint32
|
||||
}
|
||||
|
||||
type GridLicensableFeature struct {
|
||||
FeatureCode uint32
|
||||
FeatureState uint32
|
||||
LicenseInfo [128]int8
|
||||
ProductName [128]int8
|
||||
FeatureEnabled uint32
|
||||
}
|
||||
|
||||
type GridLicensableFeatures struct {
|
||||
IsGridLicenseSupported int32
|
||||
LicensableFeaturesCount uint32
|
||||
GridLicensableFeatures [3]GridLicensableFeature
|
||||
}
|
||||
|
||||
type DeviceArchitecture uint32
|
||||
|
||||
type FieldValue struct {
|
||||
FieldId uint32
|
||||
ScopeId uint32
|
||||
Timestamp int64
|
||||
LatencyUsec int64
|
||||
ValueType uint32
|
||||
NvmlReturn uint32
|
||||
Value [8]byte
|
||||
}
|
||||
|
||||
type Unit struct {
|
||||
Handle *_Ctype_struct_nvmlUnit_st
|
||||
}
|
||||
|
||||
type HwbcEntry struct {
|
||||
HwbcId uint32
|
||||
FirmwareVersion [32]int8
|
||||
}
|
||||
|
||||
type LedState struct {
|
||||
Cause [256]int8
|
||||
Color uint32
|
||||
}
|
||||
|
||||
type UnitInfo struct {
|
||||
Name [96]int8
|
||||
Id [96]int8
|
||||
Serial [96]int8
|
||||
FirmwareVersion [96]int8
|
||||
}
|
||||
|
||||
type PSUInfo struct {
|
||||
State [256]int8
|
||||
Current uint32
|
||||
Voltage uint32
|
||||
Power uint32
|
||||
}
|
||||
|
||||
type UnitFanInfo struct {
|
||||
Speed uint32
|
||||
State uint32
|
||||
}
|
||||
|
||||
type UnitFanSpeeds struct {
|
||||
Fans [24]UnitFanInfo
|
||||
Count uint32
|
||||
}
|
||||
|
||||
type EventSet struct {
|
||||
Handle *_Ctype_struct_nvmlEventSet_st
|
||||
}
|
||||
|
||||
type EventData struct {
|
||||
Device Device
|
||||
EventType uint64
|
||||
EventData uint64
|
||||
GpuInstanceId uint32
|
||||
ComputeInstanceId uint32
|
||||
}
|
||||
|
||||
type AccountingStats struct {
|
||||
GpuUtilization uint32
|
||||
MemoryUtilization uint32
|
||||
MaxMemoryUsage uint64
|
||||
Time uint64
|
||||
StartTime uint64
|
||||
IsRunning uint32
|
||||
Reserved [5]uint32
|
||||
}
|
||||
|
||||
type EncoderSessionInfo struct {
|
||||
SessionId uint32
|
||||
Pid uint32
|
||||
VgpuInstance uint32
|
||||
CodecType uint32
|
||||
HResolution uint32
|
||||
VResolution uint32
|
||||
AverageFps uint32
|
||||
AverageLatency uint32
|
||||
}
|
||||
|
||||
type FBCStats struct {
|
||||
SessionsCount uint32
|
||||
AverageFPS uint32
|
||||
AverageLatency uint32
|
||||
}
|
||||
|
||||
type FBCSessionInfo struct {
|
||||
SessionId uint32
|
||||
Pid uint32
|
||||
VgpuInstance uint32
|
||||
DisplayOrdinal uint32
|
||||
SessionType uint32
|
||||
SessionFlags uint32
|
||||
HMaxResolution uint32
|
||||
VMaxResolution uint32
|
||||
HResolution uint32
|
||||
VResolution uint32
|
||||
AverageFPS uint32
|
||||
AverageLatency uint32
|
||||
}
|
||||
|
||||
type AffinityScope uint32
|
||||
|
||||
type VgpuVersion struct {
|
||||
MinVersion uint32
|
||||
MaxVersion uint32
|
||||
}
|
||||
|
||||
type nvmlVgpuMetadata struct {
|
||||
Version uint32
|
||||
Revision uint32
|
||||
GuestInfoState uint32
|
||||
GuestDriverVersion [80]int8
|
||||
HostDriverVersion [80]int8
|
||||
Reserved [6]uint32
|
||||
VgpuVirtualizationCaps uint32
|
||||
GuestVgpuVersion uint32
|
||||
OpaqueDataSize uint32
|
||||
OpaqueData [4]int8
|
||||
}
|
||||
|
||||
type nvmlVgpuPgpuMetadata struct {
|
||||
Version uint32
|
||||
Revision uint32
|
||||
HostDriverVersion [80]int8
|
||||
PgpuVirtualizationCaps uint32
|
||||
Reserved [5]uint32
|
||||
HostSupportedVgpuRange VgpuVersion
|
||||
OpaqueDataSize uint32
|
||||
OpaqueData [4]int8
|
||||
}
|
||||
|
||||
type VgpuPgpuCompatibility struct {
|
||||
VgpuVmCompatibility uint32
|
||||
CompatibilityLimitCode uint32
|
||||
}
|
||||
|
||||
type BlacklistDeviceInfo struct {
|
||||
PciInfo PciInfo
|
||||
Uuid [80]int8
|
||||
}
|
||||
|
||||
type GpuInstancePlacement struct {
|
||||
Start uint32
|
||||
Size uint32
|
||||
}
|
||||
|
||||
type GpuInstanceProfileInfo struct {
|
||||
Id uint32
|
||||
IsP2pSupported uint32
|
||||
SliceCount uint32
|
||||
InstanceCount uint32
|
||||
MultiprocessorCount uint32
|
||||
CopyEngineCount uint32
|
||||
DecoderCount uint32
|
||||
EncoderCount uint32
|
||||
JpegCount uint32
|
||||
OfaCount uint32
|
||||
MemorySizeMB uint64
|
||||
}
|
||||
|
||||
type GpuInstanceInfo struct {
|
||||
Device Device
|
||||
Id uint32
|
||||
ProfileId uint32
|
||||
Placement GpuInstancePlacement
|
||||
}
|
||||
|
||||
type GpuInstance struct {
|
||||
Handle *_Ctype_struct_nvmlGpuInstance_st
|
||||
}
|
||||
|
||||
type ComputeInstanceProfileInfo struct {
|
||||
Id uint32
|
||||
SliceCount uint32
|
||||
InstanceCount uint32
|
||||
MultiprocessorCount uint32
|
||||
SharedCopyEngineCount uint32
|
||||
SharedDecoderCount uint32
|
||||
SharedEncoderCount uint32
|
||||
SharedJpegCount uint32
|
||||
SharedOfaCount uint32
|
||||
}
|
||||
|
||||
type ComputeInstanceInfo struct {
|
||||
Device Device
|
||||
GpuInstance GpuInstance
|
||||
Id uint32
|
||||
ProfileId uint32
|
||||
}
|
||||
|
||||
type ComputeInstance struct {
|
||||
Handle *_Ctype_struct_nvmlComputeInstance_st
|
||||
}
|
||||
113
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/unit.go
generated
vendored
Normal file
113
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/unit.go
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright (c) 2020, NVIDIA CORPORATION. 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 nvml
|
||||
|
||||
// nvml.UnitGetCount()
|
||||
func UnitGetCount() (int, Return) {
|
||||
var UnitCount uint32
|
||||
ret := nvmlUnitGetCount(&UnitCount)
|
||||
return int(UnitCount), ret
|
||||
}
|
||||
|
||||
// nvml.UnitGetHandleByIndex()
|
||||
func UnitGetHandleByIndex(Index int) (Unit, Return) {
|
||||
var Unit Unit
|
||||
ret := nvmlUnitGetHandleByIndex(uint32(Index), &Unit)
|
||||
return Unit, ret
|
||||
}
|
||||
|
||||
// nvml.UnitGetUnitInfo()
|
||||
func UnitGetUnitInfo(Unit Unit) (UnitInfo, Return) {
|
||||
var Info UnitInfo
|
||||
ret := nvmlUnitGetUnitInfo(Unit, &Info)
|
||||
return Info, ret
|
||||
}
|
||||
|
||||
func (Unit Unit) GetUnitInfo() (UnitInfo, Return) {
|
||||
return UnitGetUnitInfo(Unit)
|
||||
}
|
||||
|
||||
// nvml.UnitGetLedState()
|
||||
func UnitGetLedState(Unit Unit) (LedState, Return) {
|
||||
var State LedState
|
||||
ret := nvmlUnitGetLedState(Unit, &State)
|
||||
return State, ret
|
||||
}
|
||||
|
||||
func (Unit Unit) GetLedState() (LedState, Return) {
|
||||
return UnitGetLedState(Unit)
|
||||
}
|
||||
|
||||
// nvml.UnitGetPsuInfo()
|
||||
func UnitGetPsuInfo(Unit Unit) (PSUInfo, Return) {
|
||||
var Psu PSUInfo
|
||||
ret := nvmlUnitGetPsuInfo(Unit, &Psu)
|
||||
return Psu, ret
|
||||
}
|
||||
|
||||
func (Unit Unit) GetPsuInfo() (PSUInfo, Return) {
|
||||
return UnitGetPsuInfo(Unit)
|
||||
}
|
||||
|
||||
// nvml.UnitGetTemperature()
|
||||
func UnitGetTemperature(Unit Unit, Type int) (uint32, Return) {
|
||||
var Temp uint32
|
||||
ret := nvmlUnitGetTemperature(Unit, uint32(Type), &Temp)
|
||||
return Temp, ret
|
||||
}
|
||||
|
||||
func (Unit Unit) GetTemperature(Type int) (uint32, Return) {
|
||||
return UnitGetTemperature(Unit, Type)
|
||||
}
|
||||
|
||||
// nvml.UnitGetFanSpeedInfo()
|
||||
func UnitGetFanSpeedInfo(Unit Unit) (UnitFanSpeeds, Return) {
|
||||
var FanSpeeds UnitFanSpeeds
|
||||
ret := nvmlUnitGetFanSpeedInfo(Unit, &FanSpeeds)
|
||||
return FanSpeeds, ret
|
||||
}
|
||||
|
||||
func (Unit Unit) GetFanSpeedInfo() (UnitFanSpeeds, Return) {
|
||||
return UnitGetFanSpeedInfo(Unit)
|
||||
}
|
||||
|
||||
// nvml.UnitGetDevices()
|
||||
func UnitGetDevices(Unit Unit) ([]Device, Return) {
|
||||
var DeviceCount uint32 = 1 // Will be reduced upon returning
|
||||
for {
|
||||
Devices := make([]Device, DeviceCount)
|
||||
ret := nvmlUnitGetDevices(Unit, &DeviceCount, &Devices[0])
|
||||
if ret == SUCCESS {
|
||||
return Devices[:DeviceCount], ret
|
||||
}
|
||||
if ret != ERROR_INSUFFICIENT_SIZE {
|
||||
return nil, ret
|
||||
}
|
||||
DeviceCount *= 2
|
||||
}
|
||||
}
|
||||
|
||||
func (Unit Unit) GetDevices() ([]Device, Return) {
|
||||
return UnitGetDevices(Unit)
|
||||
}
|
||||
|
||||
// nvml.UnitSetLedState()
|
||||
func UnitSetLedState(Unit Unit, Color LedColor) Return {
|
||||
return nvmlUnitSetLedState(Unit, Color)
|
||||
}
|
||||
|
||||
func (Unit Unit) SetLedState(Color LedColor) Return {
|
||||
return UnitSetLedState(Unit, Color)
|
||||
}
|
||||
420
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/vgpu.go
generated
vendored
Normal file
420
vendor/github.com/NVIDIA/go-nvml/pkg/nvml/vgpu.go
generated
vendored
Normal file
@@ -0,0 +1,420 @@
|
||||
// Copyright (c) 2020, NVIDIA CORPORATION. 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 nvml
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// nvml.VgpuMetadata
|
||||
type VgpuMetadata struct {
|
||||
nvmlVgpuMetadata
|
||||
OpaqueData []byte
|
||||
}
|
||||
|
||||
// nvml.VgpuPgpuMetadata
|
||||
type VgpuPgpuMetadata struct {
|
||||
nvmlVgpuPgpuMetadata
|
||||
OpaqueData []byte
|
||||
}
|
||||
|
||||
// nvml.VgpuTypeGetClass()
|
||||
func VgpuTypeGetClass(VgpuTypeId VgpuTypeId) (string, Return) {
|
||||
var Size uint32 = DEVICE_NAME_BUFFER_SIZE
|
||||
VgpuTypeClass := make([]byte, DEVICE_NAME_BUFFER_SIZE)
|
||||
ret := nvmlVgpuTypeGetClass(VgpuTypeId, &VgpuTypeClass[0], &Size)
|
||||
return string(VgpuTypeClass[:clen(VgpuTypeClass)]), ret
|
||||
}
|
||||
|
||||
func (VgpuTypeId VgpuTypeId) GetClass() (string, Return) {
|
||||
return VgpuTypeGetClass(VgpuTypeId)
|
||||
}
|
||||
|
||||
// nvml.VgpuTypeGetName()
|
||||
func VgpuTypeGetName(VgpuTypeId VgpuTypeId) (string, Return) {
|
||||
var Size uint32 = DEVICE_NAME_BUFFER_SIZE
|
||||
VgpuTypeName := make([]byte, DEVICE_NAME_BUFFER_SIZE)
|
||||
ret := nvmlVgpuTypeGetName(VgpuTypeId, &VgpuTypeName[0], &Size)
|
||||
return string(VgpuTypeName[:clen(VgpuTypeName)]), ret
|
||||
}
|
||||
|
||||
func (VgpuTypeId VgpuTypeId) GetName() (string, Return) {
|
||||
return VgpuTypeGetName(VgpuTypeId)
|
||||
}
|
||||
|
||||
// nvml.VgpuTypeGetGpuInstanceProfileId()
|
||||
func VgpuTypeGetGpuInstanceProfileId(VgpuTypeId VgpuTypeId) (uint32, Return) {
|
||||
var Size uint32
|
||||
ret := nvmlVgpuTypeGetGpuInstanceProfileId(VgpuTypeId, &Size)
|
||||
return Size, ret
|
||||
}
|
||||
|
||||
func (VgpuTypeId VgpuTypeId) GetGpuInstanceProfileId() (uint32, Return) {
|
||||
return VgpuTypeGetGpuInstanceProfileId(VgpuTypeId)
|
||||
}
|
||||
|
||||
// nvml.VgpuTypeGetDeviceID()
|
||||
func VgpuTypeGetDeviceID(VgpuTypeId VgpuTypeId) (uint64, uint64, Return) {
|
||||
var DeviceID, SubsystemID uint64
|
||||
ret := nvmlVgpuTypeGetDeviceID(VgpuTypeId, &DeviceID, &SubsystemID)
|
||||
return DeviceID, SubsystemID, ret
|
||||
}
|
||||
|
||||
func (VgpuTypeId VgpuTypeId) GetDeviceID() (uint64, uint64, Return) {
|
||||
return VgpuTypeGetDeviceID(VgpuTypeId)
|
||||
}
|
||||
|
||||
// nvml.VgpuTypeGetFramebufferSize()
|
||||
func VgpuTypeGetFramebufferSize(VgpuTypeId VgpuTypeId) (uint64, Return) {
|
||||
var FbSize uint64
|
||||
ret := nvmlVgpuTypeGetFramebufferSize(VgpuTypeId, &FbSize)
|
||||
return FbSize, ret
|
||||
}
|
||||
|
||||
func (VgpuTypeId VgpuTypeId) GetFramebufferSize() (uint64, Return) {
|
||||
return VgpuTypeGetFramebufferSize(VgpuTypeId)
|
||||
}
|
||||
|
||||
// nvml.VgpuTypeGetNumDisplayHeads()
|
||||
func VgpuTypeGetNumDisplayHeads(VgpuTypeId VgpuTypeId) (int, Return) {
|
||||
var NumDisplayHeads uint32
|
||||
ret := nvmlVgpuTypeGetNumDisplayHeads(VgpuTypeId, &NumDisplayHeads)
|
||||
return int(NumDisplayHeads), ret
|
||||
}
|
||||
|
||||
func (VgpuTypeId VgpuTypeId) GetNumDisplayHeads() (int, Return) {
|
||||
return VgpuTypeGetNumDisplayHeads(VgpuTypeId)
|
||||
}
|
||||
|
||||
// nvml.VgpuTypeGetResolution()
|
||||
func VgpuTypeGetResolution(VgpuTypeId VgpuTypeId, DisplayIndex int) (uint32, uint32, Return) {
|
||||
var Xdim, Ydim uint32
|
||||
ret := nvmlVgpuTypeGetResolution(VgpuTypeId, uint32(DisplayIndex), &Xdim, &Ydim)
|
||||
return Xdim, Ydim, ret
|
||||
}
|
||||
|
||||
func (VgpuTypeId VgpuTypeId) GetResolution(DisplayIndex int) (uint32, uint32, Return) {
|
||||
return VgpuTypeGetResolution(VgpuTypeId, DisplayIndex)
|
||||
}
|
||||
|
||||
// nvml.VgpuTypeGetLicense()
|
||||
func VgpuTypeGetLicense(VgpuTypeId VgpuTypeId) (string, Return) {
|
||||
VgpuTypeLicenseString := make([]byte, GRID_LICENSE_BUFFER_SIZE)
|
||||
ret := nvmlVgpuTypeGetLicense(VgpuTypeId, &VgpuTypeLicenseString[0], GRID_LICENSE_BUFFER_SIZE)
|
||||
return string(VgpuTypeLicenseString[:clen(VgpuTypeLicenseString)]), ret
|
||||
}
|
||||
|
||||
func (VgpuTypeId VgpuTypeId) GetLicense() (string, Return) {
|
||||
return VgpuTypeGetLicense(VgpuTypeId)
|
||||
}
|
||||
|
||||
// nvml.VgpuTypeGetFrameRateLimit()
|
||||
func VgpuTypeGetFrameRateLimit(VgpuTypeId VgpuTypeId) (uint32, Return) {
|
||||
var FrameRateLimit uint32
|
||||
ret := nvmlVgpuTypeGetFrameRateLimit(VgpuTypeId, &FrameRateLimit)
|
||||
return FrameRateLimit, ret
|
||||
}
|
||||
|
||||
func (VgpuTypeId VgpuTypeId) GetFrameRateLimit() (uint32, Return) {
|
||||
return VgpuTypeGetFrameRateLimit(VgpuTypeId)
|
||||
}
|
||||
|
||||
// nvml.VgpuTypeGetMaxInstances()
|
||||
func VgpuTypeGetMaxInstances(Device Device, VgpuTypeId VgpuTypeId) (int, Return) {
|
||||
var VgpuInstanceCount uint32
|
||||
ret := nvmlVgpuTypeGetMaxInstances(Device, VgpuTypeId, &VgpuInstanceCount)
|
||||
return int(VgpuInstanceCount), ret
|
||||
}
|
||||
|
||||
func (Device Device) VgpuTypeGetMaxInstances(VgpuTypeId VgpuTypeId) (int, Return) {
|
||||
return VgpuTypeGetMaxInstances(Device, VgpuTypeId)
|
||||
}
|
||||
|
||||
func (VgpuTypeId VgpuTypeId) GetMaxInstances(Device Device) (int, Return) {
|
||||
return VgpuTypeGetMaxInstances(Device, VgpuTypeId)
|
||||
}
|
||||
|
||||
// nvml.VgpuTypeGetMaxInstancesPerVm()
|
||||
func VgpuTypeGetMaxInstancesPerVm(VgpuTypeId VgpuTypeId) (int, Return) {
|
||||
var VgpuInstanceCountPerVm uint32
|
||||
ret := nvmlVgpuTypeGetMaxInstancesPerVm(VgpuTypeId, &VgpuInstanceCountPerVm)
|
||||
return int(VgpuInstanceCountPerVm), ret
|
||||
}
|
||||
|
||||
func (VgpuTypeId VgpuTypeId) GetMaxInstancesPerVm() (int, Return) {
|
||||
return VgpuTypeGetMaxInstancesPerVm(VgpuTypeId)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetVmID()
|
||||
func VgpuInstanceGetVmID(VgpuInstance VgpuInstance) (string, VgpuVmIdType, Return) {
|
||||
var VmIdType VgpuVmIdType
|
||||
VmId := make([]byte, DEVICE_UUID_BUFFER_SIZE)
|
||||
ret := nvmlVgpuInstanceGetVmID(VgpuInstance, &VmId[0], DEVICE_UUID_BUFFER_SIZE, &VmIdType)
|
||||
return string(VmId[:clen(VmId)]), VmIdType, ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetVmID() (string, VgpuVmIdType, Return) {
|
||||
return VgpuInstanceGetVmID(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetUUID()
|
||||
func VgpuInstanceGetUUID(VgpuInstance VgpuInstance) (string, Return) {
|
||||
Uuid := make([]byte, DEVICE_UUID_BUFFER_SIZE)
|
||||
ret := nvmlVgpuInstanceGetUUID(VgpuInstance, &Uuid[0], DEVICE_UUID_BUFFER_SIZE)
|
||||
return string(Uuid[:clen(Uuid)]), ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetUUID() (string, Return) {
|
||||
return VgpuInstanceGetUUID(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetVmDriverVersion()
|
||||
func VgpuInstanceGetVmDriverVersion(VgpuInstance VgpuInstance) (string, Return) {
|
||||
Version := make([]byte, SYSTEM_DRIVER_VERSION_BUFFER_SIZE)
|
||||
ret := nvmlVgpuInstanceGetVmDriverVersion(VgpuInstance, &Version[0], SYSTEM_DRIVER_VERSION_BUFFER_SIZE)
|
||||
return string(Version[:clen(Version)]), ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetVmDriverVersion() (string, Return) {
|
||||
return VgpuInstanceGetVmDriverVersion(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetFbUsage()
|
||||
func VgpuInstanceGetFbUsage(VgpuInstance VgpuInstance) (uint64, Return) {
|
||||
var FbUsage uint64
|
||||
ret := nvmlVgpuInstanceGetFbUsage(VgpuInstance, &FbUsage)
|
||||
return FbUsage, ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetFbUsage() (uint64, Return) {
|
||||
return VgpuInstanceGetFbUsage(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetLicenseStatus()
|
||||
func VgpuInstanceGetLicenseStatus(VgpuInstance VgpuInstance) (int, Return) {
|
||||
var Licensed uint32
|
||||
ret := nvmlVgpuInstanceGetLicenseStatus(VgpuInstance, &Licensed)
|
||||
return int(Licensed), ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetLicenseStatus() (int, Return) {
|
||||
return VgpuInstanceGetLicenseStatus(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetType()
|
||||
func VgpuInstanceGetType(VgpuInstance VgpuInstance) (VgpuTypeId, Return) {
|
||||
var VgpuTypeId VgpuTypeId
|
||||
ret := nvmlVgpuInstanceGetType(VgpuInstance, &VgpuTypeId)
|
||||
return VgpuTypeId, ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetType() (VgpuTypeId, Return) {
|
||||
return VgpuInstanceGetType(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetFrameRateLimit()
|
||||
func VgpuInstanceGetFrameRateLimit(VgpuInstance VgpuInstance) (uint32, Return) {
|
||||
var FrameRateLimit uint32
|
||||
ret := nvmlVgpuInstanceGetFrameRateLimit(VgpuInstance, &FrameRateLimit)
|
||||
return FrameRateLimit, ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetFrameRateLimit() (uint32, Return) {
|
||||
return VgpuInstanceGetFrameRateLimit(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetEccMode()
|
||||
func VgpuInstanceGetEccMode(VgpuInstance VgpuInstance) (EnableState, Return) {
|
||||
var EccMode EnableState
|
||||
ret := nvmlVgpuInstanceGetEccMode(VgpuInstance, &EccMode)
|
||||
return EccMode, ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetEccMode() (EnableState, Return) {
|
||||
return VgpuInstanceGetEccMode(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetEncoderCapacity()
|
||||
func VgpuInstanceGetEncoderCapacity(VgpuInstance VgpuInstance) (int, Return) {
|
||||
var EncoderCapacity uint32
|
||||
ret := nvmlVgpuInstanceGetEncoderCapacity(VgpuInstance, &EncoderCapacity)
|
||||
return int(EncoderCapacity), ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetEncoderCapacity() (int, Return) {
|
||||
return VgpuInstanceGetEncoderCapacity(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceSetEncoderCapacity()
|
||||
func VgpuInstanceSetEncoderCapacity(VgpuInstance VgpuInstance, EncoderCapacity int) Return {
|
||||
return nvmlVgpuInstanceSetEncoderCapacity(VgpuInstance, uint32(EncoderCapacity))
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) SetEncoderCapacity(EncoderCapacity int) Return {
|
||||
return VgpuInstanceSetEncoderCapacity(VgpuInstance, EncoderCapacity)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetEncoderStats()
|
||||
func VgpuInstanceGetEncoderStats(VgpuInstance VgpuInstance) (int, uint32, uint32, Return) {
|
||||
var SessionCount, AverageFps, AverageLatency uint32
|
||||
ret := nvmlVgpuInstanceGetEncoderStats(VgpuInstance, &SessionCount, &AverageFps, &AverageLatency)
|
||||
return int(SessionCount), AverageFps, AverageLatency, ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetEncoderStats() (int, uint32, uint32, Return) {
|
||||
return VgpuInstanceGetEncoderStats(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetEncoderSessions()
|
||||
func VgpuInstanceGetEncoderSessions(VgpuInstance VgpuInstance) (int, EncoderSessionInfo, Return) {
|
||||
var SessionCount uint32
|
||||
var SessionInfo EncoderSessionInfo
|
||||
ret := nvmlVgpuInstanceGetEncoderSessions(VgpuInstance, &SessionCount, &SessionInfo)
|
||||
return int(SessionCount), SessionInfo, ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetEncoderSessions() (int, EncoderSessionInfo, Return) {
|
||||
return VgpuInstanceGetEncoderSessions(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetFBCStats()
|
||||
func VgpuInstanceGetFBCStats(VgpuInstance VgpuInstance) (FBCStats, Return) {
|
||||
var FbcStats FBCStats
|
||||
ret := nvmlVgpuInstanceGetFBCStats(VgpuInstance, &FbcStats)
|
||||
return FbcStats, ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetFBCStats() (FBCStats, Return) {
|
||||
return VgpuInstanceGetFBCStats(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetFBCSessions()
|
||||
func VgpuInstanceGetFBCSessions(VgpuInstance VgpuInstance) (int, FBCSessionInfo, Return) {
|
||||
var SessionCount uint32
|
||||
var SessionInfo FBCSessionInfo
|
||||
ret := nvmlVgpuInstanceGetFBCSessions(VgpuInstance, &SessionCount, &SessionInfo)
|
||||
return int(SessionCount), SessionInfo, ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetFBCSessions() (int, FBCSessionInfo, Return) {
|
||||
return VgpuInstanceGetFBCSessions(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetMetadata()
|
||||
func VgpuInstanceGetMetadata(VgpuInstance VgpuInstance) (VgpuMetadata, Return) {
|
||||
var VgpuMetadata VgpuMetadata
|
||||
OpaqueDataSize := unsafe.Sizeof(VgpuMetadata.nvmlVgpuMetadata.OpaqueData)
|
||||
VgpuMetadataSize := unsafe.Sizeof(VgpuMetadata.nvmlVgpuMetadata) - OpaqueDataSize
|
||||
for {
|
||||
BufferSize := uint32(VgpuMetadataSize + OpaqueDataSize)
|
||||
Buffer := make([]byte, BufferSize)
|
||||
nvmlVgpuMetadataPtr := (*nvmlVgpuMetadata)(unsafe.Pointer(&Buffer[0]))
|
||||
ret := nvmlVgpuInstanceGetMetadata(VgpuInstance, nvmlVgpuMetadataPtr, &BufferSize)
|
||||
if ret == SUCCESS {
|
||||
VgpuMetadata.nvmlVgpuMetadata = *nvmlVgpuMetadataPtr
|
||||
VgpuMetadata.OpaqueData = Buffer[VgpuMetadataSize:BufferSize]
|
||||
return VgpuMetadata, ret
|
||||
}
|
||||
if ret != ERROR_INSUFFICIENT_SIZE {
|
||||
return VgpuMetadata, ret
|
||||
}
|
||||
OpaqueDataSize = 2 * OpaqueDataSize
|
||||
}
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetMetadata() (VgpuMetadata, Return) {
|
||||
return VgpuInstanceGetMetadata(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetAccountingMode()
|
||||
func VgpuInstanceGetAccountingMode(VgpuInstance VgpuInstance) (EnableState, Return) {
|
||||
var Mode EnableState
|
||||
ret := nvmlVgpuInstanceGetAccountingMode(VgpuInstance, &Mode)
|
||||
return Mode, ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetAccountingMode() (EnableState, Return) {
|
||||
return VgpuInstanceGetAccountingMode(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetAccountingPids()
|
||||
func VgpuInstanceGetAccountingPids(VgpuInstance VgpuInstance) ([]int, Return) {
|
||||
var Count uint32 = 1 // Will be reduced upon returning
|
||||
for {
|
||||
Pids := make([]uint32, Count)
|
||||
ret := nvmlVgpuInstanceGetAccountingPids(VgpuInstance, &Count, &Pids[0])
|
||||
if ret == SUCCESS {
|
||||
return uint32SliceToIntSlice(Pids[:Count]), ret
|
||||
}
|
||||
if ret != ERROR_INSUFFICIENT_SIZE {
|
||||
return nil, ret
|
||||
}
|
||||
Count *= 2
|
||||
}
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetAccountingPids() ([]int, Return) {
|
||||
return VgpuInstanceGetAccountingPids(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetAccountingStats()
|
||||
func VgpuInstanceGetAccountingStats(VgpuInstance VgpuInstance, Pid int) (AccountingStats, Return) {
|
||||
var Stats AccountingStats
|
||||
ret := nvmlVgpuInstanceGetAccountingStats(VgpuInstance, uint32(Pid), &Stats)
|
||||
return Stats, ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetAccountingStats(Pid int) (AccountingStats, Return) {
|
||||
return VgpuInstanceGetAccountingStats(VgpuInstance, Pid)
|
||||
}
|
||||
|
||||
// nvml.GetVgpuCompatibility()
|
||||
func GetVgpuCompatibility(nvmlVgpuMetadata *nvmlVgpuMetadata, PgpuMetadata *nvmlVgpuPgpuMetadata) (VgpuPgpuCompatibility, Return) {
|
||||
var CompatibilityInfo VgpuPgpuCompatibility
|
||||
ret := nvmlGetVgpuCompatibility(nvmlVgpuMetadata, PgpuMetadata, &CompatibilityInfo)
|
||||
return CompatibilityInfo, ret
|
||||
}
|
||||
|
||||
// nvml.GetVgpuVersion()
|
||||
func GetVgpuVersion() (VgpuVersion, VgpuVersion, Return) {
|
||||
var Supported, Current VgpuVersion
|
||||
ret := nvmlGetVgpuVersion(&Supported, &Current)
|
||||
return Supported, Current, ret
|
||||
}
|
||||
|
||||
// nvml.SetVgpuVersion()
|
||||
func SetVgpuVersion(VgpuVersion *VgpuVersion) Return {
|
||||
return SetVgpuVersion(VgpuVersion)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceClearAccountingPids()
|
||||
func VgpuInstanceClearAccountingPids(VgpuInstance VgpuInstance) Return {
|
||||
return nvmlVgpuInstanceClearAccountingPids(VgpuInstance)
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) ClearAccountingPids() Return {
|
||||
return VgpuInstanceClearAccountingPids(VgpuInstance)
|
||||
}
|
||||
|
||||
// nvml.VgpuInstanceGetMdevUUID()
|
||||
func VgpuInstanceGetMdevUUID(VgpuInstance VgpuInstance) (string, Return) {
|
||||
MdevUuid := make([]byte, DEVICE_UUID_BUFFER_SIZE)
|
||||
ret := nvmlVgpuInstanceGetMdevUUID(VgpuInstance, &MdevUuid[0], DEVICE_UUID_BUFFER_SIZE)
|
||||
return string(MdevUuid[:clen(MdevUuid)]), ret
|
||||
}
|
||||
|
||||
func (VgpuInstance VgpuInstance) GetMdevUUID() (string, Return) {
|
||||
return VgpuInstanceGetMdevUUID(VgpuInstance)
|
||||
}
|
||||
2
vendor/github.com/davecgh/go-spew/LICENSE
generated
vendored
2
vendor/github.com/davecgh/go-spew/LICENSE
generated
vendored
@@ -2,7 +2,7 @@ ISC License
|
||||
|
||||
Copyright (c) 2012-2016 Dave Collins <dave@davec.name>
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
|
||||
187
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
187
vendor/github.com/davecgh/go-spew/spew/bypass.go
generated
vendored
@@ -16,7 +16,9 @@
|
||||
// when the code is not running on Google App Engine, compiled by GopherJS, and
|
||||
// "-tags safe" is not added to the go build command line. The "disableunsafe"
|
||||
// tag is deprecated and thus should not be used.
|
||||
// +build !js,!appengine,!safe,!disableunsafe
|
||||
// Go versions prior to 1.4 are disabled because they use a different layout
|
||||
// for interfaces which make the implementation of unsafeReflectValue more complex.
|
||||
// +build !js,!appengine,!safe,!disableunsafe,go1.4
|
||||
|
||||
package spew
|
||||
|
||||
@@ -34,80 +36,49 @@ const (
|
||||
ptrSize = unsafe.Sizeof((*byte)(nil))
|
||||
)
|
||||
|
||||
var (
|
||||
// offsetPtr, offsetScalar, and offsetFlag are the offsets for the
|
||||
// internal reflect.Value fields. These values are valid before golang
|
||||
// commit ecccf07e7f9d which changed the format. The are also valid
|
||||
// after commit 82f48826c6c7 which changed the format again to mirror
|
||||
// the original format. Code in the init function updates these offsets
|
||||
// as necessary.
|
||||
offsetPtr = uintptr(ptrSize)
|
||||
offsetScalar = uintptr(0)
|
||||
offsetFlag = uintptr(ptrSize * 2)
|
||||
type flag uintptr
|
||||
|
||||
// flagKindWidth and flagKindShift indicate various bits that the
|
||||
// reflect package uses internally to track kind information.
|
||||
//
|
||||
// flagRO indicates whether or not the value field of a reflect.Value is
|
||||
// read-only.
|
||||
//
|
||||
// flagIndir indicates whether the value field of a reflect.Value is
|
||||
// the actual data or a pointer to the data.
|
||||
//
|
||||
// These values are valid before golang commit 90a7c3c86944 which
|
||||
// changed their positions. Code in the init function updates these
|
||||
// flags as necessary.
|
||||
flagKindWidth = uintptr(5)
|
||||
flagKindShift = uintptr(flagKindWidth - 1)
|
||||
flagRO = uintptr(1 << 0)
|
||||
flagIndir = uintptr(1 << 1)
|
||||
var (
|
||||
// flagRO indicates whether the value field of a reflect.Value
|
||||
// is read-only.
|
||||
flagRO flag
|
||||
|
||||
// flagAddr indicates whether the address of the reflect.Value's
|
||||
// value may be taken.
|
||||
flagAddr flag
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Older versions of reflect.Value stored small integers directly in the
|
||||
// ptr field (which is named val in the older versions). Versions
|
||||
// between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
|
||||
// scalar for this purpose which unfortunately came before the flag
|
||||
// field, so the offset of the flag field is different for those
|
||||
// versions.
|
||||
//
|
||||
// This code constructs a new reflect.Value from a known small integer
|
||||
// and checks if the size of the reflect.Value struct indicates it has
|
||||
// the scalar field. When it does, the offsets are updated accordingly.
|
||||
vv := reflect.ValueOf(0xf00)
|
||||
if unsafe.Sizeof(vv) == (ptrSize * 4) {
|
||||
offsetScalar = ptrSize * 2
|
||||
offsetFlag = ptrSize * 3
|
||||
}
|
||||
// flagKindMask holds the bits that make up the kind
|
||||
// part of the flags field. In all the supported versions,
|
||||
// it is in the lower 5 bits.
|
||||
const flagKindMask = flag(0x1f)
|
||||
|
||||
// Commit 90a7c3c86944 changed the flag positions such that the low
|
||||
// order bits are the kind. This code extracts the kind from the flags
|
||||
// field and ensures it's the correct type. When it's not, the flag
|
||||
// order has been changed to the newer format, so the flags are updated
|
||||
// accordingly.
|
||||
upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
|
||||
upfv := *(*uintptr)(upf)
|
||||
flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
|
||||
if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
|
||||
flagKindShift = 0
|
||||
flagRO = 1 << 5
|
||||
flagIndir = 1 << 6
|
||||
// Different versions of Go have used different
|
||||
// bit layouts for the flags type. This table
|
||||
// records the known combinations.
|
||||
var okFlags = []struct {
|
||||
ro, addr flag
|
||||
}{{
|
||||
// From Go 1.4 to 1.5
|
||||
ro: 1 << 5,
|
||||
addr: 1 << 7,
|
||||
}, {
|
||||
// Up to Go tip.
|
||||
ro: 1<<5 | 1<<6,
|
||||
addr: 1 << 8,
|
||||
}}
|
||||
|
||||
// Commit adf9b30e5594 modified the flags to separate the
|
||||
// flagRO flag into two bits which specifies whether or not the
|
||||
// field is embedded. This causes flagIndir to move over a bit
|
||||
// and means that flagRO is the combination of either of the
|
||||
// original flagRO bit and the new bit.
|
||||
//
|
||||
// This code detects the change by extracting what used to be
|
||||
// the indirect bit to ensure it's set. When it's not, the flag
|
||||
// order has been changed to the newer format, so the flags are
|
||||
// updated accordingly.
|
||||
if upfv&flagIndir == 0 {
|
||||
flagRO = 3 << 5
|
||||
flagIndir = 1 << 7
|
||||
}
|
||||
var flagValOffset = func() uintptr {
|
||||
field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
|
||||
if !ok {
|
||||
panic("reflect.Value has no flag field")
|
||||
}
|
||||
return field.Offset
|
||||
}()
|
||||
|
||||
// flagField returns a pointer to the flag field of a reflect.Value.
|
||||
func flagField(v *reflect.Value) *flag {
|
||||
return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))
|
||||
}
|
||||
|
||||
// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
|
||||
@@ -119,34 +90,56 @@ func init() {
|
||||
// This allows us to check for implementations of the Stringer and error
|
||||
// interfaces to be used for pretty printing ordinarily unaddressable and
|
||||
// inaccessible values such as unexported struct fields.
|
||||
func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
|
||||
indirects := 1
|
||||
vt := v.Type()
|
||||
upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
|
||||
rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
|
||||
if rvf&flagIndir != 0 {
|
||||
vt = reflect.PtrTo(v.Type())
|
||||
indirects++
|
||||
} else if offsetScalar != 0 {
|
||||
// The value is in the scalar field when it's not one of the
|
||||
// reference types.
|
||||
switch vt.Kind() {
|
||||
case reflect.Uintptr:
|
||||
case reflect.Chan:
|
||||
case reflect.Func:
|
||||
case reflect.Map:
|
||||
case reflect.Ptr:
|
||||
case reflect.UnsafePointer:
|
||||
default:
|
||||
upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
|
||||
offsetScalar)
|
||||
func unsafeReflectValue(v reflect.Value) reflect.Value {
|
||||
if !v.IsValid() || (v.CanInterface() && v.CanAddr()) {
|
||||
return v
|
||||
}
|
||||
flagFieldPtr := flagField(&v)
|
||||
*flagFieldPtr &^= flagRO
|
||||
*flagFieldPtr |= flagAddr
|
||||
return v
|
||||
}
|
||||
|
||||
// Sanity checks against future reflect package changes
|
||||
// to the type or semantics of the Value.flag field.
|
||||
func init() {
|
||||
field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
|
||||
if !ok {
|
||||
panic("reflect.Value has no flag field")
|
||||
}
|
||||
if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {
|
||||
panic("reflect.Value flag field has changed kind")
|
||||
}
|
||||
type t0 int
|
||||
var t struct {
|
||||
A t0
|
||||
// t0 will have flagEmbedRO set.
|
||||
t0
|
||||
// a will have flagStickyRO set
|
||||
a t0
|
||||
}
|
||||
vA := reflect.ValueOf(t).FieldByName("A")
|
||||
va := reflect.ValueOf(t).FieldByName("a")
|
||||
vt0 := reflect.ValueOf(t).FieldByName("t0")
|
||||
|
||||
// Infer flagRO from the difference between the flags
|
||||
// for the (otherwise identical) fields in t.
|
||||
flagPublic := *flagField(&vA)
|
||||
flagWithRO := *flagField(&va) | *flagField(&vt0)
|
||||
flagRO = flagPublic ^ flagWithRO
|
||||
|
||||
// Infer flagAddr from the difference between a value
|
||||
// taken from a pointer and not.
|
||||
vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A")
|
||||
flagNoPtr := *flagField(&vA)
|
||||
flagPtr := *flagField(&vPtrA)
|
||||
flagAddr = flagNoPtr ^ flagPtr
|
||||
|
||||
// Check that the inferred flags tally with one of the known versions.
|
||||
for _, f := range okFlags {
|
||||
if flagRO == f.ro && flagAddr == f.addr {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
pv := reflect.NewAt(vt, upv)
|
||||
rv = pv
|
||||
for i := 0; i < indirects; i++ {
|
||||
rv = rv.Elem()
|
||||
}
|
||||
return rv
|
||||
panic("reflect.Value read-only flag has changed semantics")
|
||||
}
|
||||
|
||||
2
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
2
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
generated
vendored
@@ -16,7 +16,7 @@
|
||||
// when the code is running on Google App Engine, compiled by GopherJS, or
|
||||
// "-tags safe" is added to the go build command line. The "disableunsafe"
|
||||
// tag is deprecated and thus should not be used.
|
||||
// +build js appengine safe disableunsafe
|
||||
// +build js appengine safe disableunsafe !go1.4
|
||||
|
||||
package spew
|
||||
|
||||
|
||||
2
vendor/github.com/davecgh/go-spew/spew/common.go
generated
vendored
2
vendor/github.com/davecgh/go-spew/spew/common.go
generated
vendored
@@ -180,7 +180,7 @@ func printComplex(w io.Writer, c complex128, floatPrecision int) {
|
||||
w.Write(closeParenBytes)
|
||||
}
|
||||
|
||||
// printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x'
|
||||
// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x'
|
||||
// prefix to Writer w.
|
||||
func printHexPtr(w io.Writer, p uintptr) {
|
||||
// Null pointer.
|
||||
|
||||
10
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
10
vendor/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
@@ -35,16 +35,16 @@ var (
|
||||
|
||||
// cCharRE is a regular expression that matches a cgo char.
|
||||
// It is used to detect character arrays to hexdump them.
|
||||
cCharRE = regexp.MustCompile("^.*\\._Ctype_char$")
|
||||
cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`)
|
||||
|
||||
// cUnsignedCharRE is a regular expression that matches a cgo unsigned
|
||||
// char. It is used to detect unsigned character arrays to hexdump
|
||||
// them.
|
||||
cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$")
|
||||
cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`)
|
||||
|
||||
// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
|
||||
// It is used to detect uint8_t arrays to hexdump them.
|
||||
cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$")
|
||||
cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`)
|
||||
)
|
||||
|
||||
// dumpState contains information about the state of a dump operation.
|
||||
@@ -143,10 +143,10 @@ func (d *dumpState) dumpPtr(v reflect.Value) {
|
||||
// Display dereferenced value.
|
||||
d.w.Write(openParenBytes)
|
||||
switch {
|
||||
case nilFound == true:
|
||||
case nilFound:
|
||||
d.w.Write(nilAngleBytes)
|
||||
|
||||
case cycleFound == true:
|
||||
case cycleFound:
|
||||
d.w.Write(circularBytes)
|
||||
|
||||
default:
|
||||
|
||||
4
vendor/github.com/davecgh/go-spew/spew/format.go
generated
vendored
4
vendor/github.com/davecgh/go-spew/spew/format.go
generated
vendored
@@ -182,10 +182,10 @@ func (f *formatState) formatPtr(v reflect.Value) {
|
||||
|
||||
// Display dereferenced value.
|
||||
switch {
|
||||
case nilFound == true:
|
||||
case nilFound:
|
||||
f.fs.Write(nilAngleBytes)
|
||||
|
||||
case cycleFound == true:
|
||||
case cycleFound:
|
||||
f.fs.Write(circularShortBytes)
|
||||
|
||||
default:
|
||||
|
||||
191
vendor/github.com/opencontainers/runtime-spec/LICENSE
generated
vendored
Normal file
191
vendor/github.com/opencontainers/runtime-spec/LICENSE
generated
vendored
Normal file
@@ -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:
|
||||
|
||||
(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
|
||||
|
||||
Copyright 2015 The Linux Foundation.
|
||||
|
||||
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.
|
||||
689
vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
generated
vendored
Normal file
689
vendor/github.com/opencontainers/runtime-spec/specs-go/config.go
generated
vendored
Normal file
@@ -0,0 +1,689 @@
|
||||
package specs
|
||||
|
||||
import "os"
|
||||
|
||||
// Spec is the base configuration for the container.
|
||||
type Spec struct {
|
||||
// Version of the Open Container Initiative Runtime Specification with which the bundle complies.
|
||||
Version string `json:"ociVersion"`
|
||||
// Process configures the container process.
|
||||
Process *Process `json:"process,omitempty"`
|
||||
// Root configures the container's root filesystem.
|
||||
Root *Root `json:"root,omitempty"`
|
||||
// Hostname configures the container's hostname.
|
||||
Hostname string `json:"hostname,omitempty"`
|
||||
// Mounts configures additional mounts (on top of Root).
|
||||
Mounts []Mount `json:"mounts,omitempty"`
|
||||
// Hooks configures callbacks for container lifecycle events.
|
||||
Hooks *Hooks `json:"hooks,omitempty" platform:"linux,solaris"`
|
||||
// Annotations contains arbitrary metadata for the container.
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
|
||||
// Linux is platform-specific configuration for Linux based containers.
|
||||
Linux *Linux `json:"linux,omitempty" platform:"linux"`
|
||||
// Solaris is platform-specific configuration for Solaris based containers.
|
||||
Solaris *Solaris `json:"solaris,omitempty" platform:"solaris"`
|
||||
// Windows is platform-specific configuration for Windows based containers.
|
||||
Windows *Windows `json:"windows,omitempty" platform:"windows"`
|
||||
// VM specifies configuration for virtual-machine-based containers.
|
||||
VM *VM `json:"vm,omitempty" platform:"vm"`
|
||||
}
|
||||
|
||||
// Process contains information to start a specific application inside the container.
|
||||
type Process struct {
|
||||
// Terminal creates an interactive terminal for the container.
|
||||
Terminal bool `json:"terminal,omitempty"`
|
||||
// ConsoleSize specifies the size of the console.
|
||||
ConsoleSize *Box `json:"consoleSize,omitempty"`
|
||||
// User specifies user information for the process.
|
||||
User User `json:"user"`
|
||||
// Args specifies the binary and arguments for the application to execute.
|
||||
Args []string `json:"args,omitempty"`
|
||||
// CommandLine specifies the full command line for the application to execute on Windows.
|
||||
CommandLine string `json:"commandLine,omitempty" platform:"windows"`
|
||||
// Env populates the process environment for the process.
|
||||
Env []string `json:"env,omitempty"`
|
||||
// Cwd is the current working directory for the process and must be
|
||||
// relative to the container's root.
|
||||
Cwd string `json:"cwd"`
|
||||
// Capabilities are Linux capabilities that are kept for the process.
|
||||
Capabilities *LinuxCapabilities `json:"capabilities,omitempty" platform:"linux"`
|
||||
// Rlimits specifies rlimit options to apply to the process.
|
||||
Rlimits []POSIXRlimit `json:"rlimits,omitempty" platform:"linux,solaris"`
|
||||
// NoNewPrivileges controls whether additional privileges could be gained by processes in the container.
|
||||
NoNewPrivileges bool `json:"noNewPrivileges,omitempty" platform:"linux"`
|
||||
// ApparmorProfile specifies the apparmor profile for the container.
|
||||
ApparmorProfile string `json:"apparmorProfile,omitempty" platform:"linux"`
|
||||
// Specify an oom_score_adj for the container.
|
||||
OOMScoreAdj *int `json:"oomScoreAdj,omitempty" platform:"linux"`
|
||||
// SelinuxLabel specifies the selinux context that the container process is run as.
|
||||
SelinuxLabel string `json:"selinuxLabel,omitempty" platform:"linux"`
|
||||
}
|
||||
|
||||
// LinuxCapabilities specifies the whitelist of capabilities that are kept for a process.
|
||||
// http://man7.org/linux/man-pages/man7/capabilities.7.html
|
||||
type LinuxCapabilities struct {
|
||||
// Bounding is the set of capabilities checked by the kernel.
|
||||
Bounding []string `json:"bounding,omitempty" platform:"linux"`
|
||||
// Effective is the set of capabilities checked by the kernel.
|
||||
Effective []string `json:"effective,omitempty" platform:"linux"`
|
||||
// Inheritable is the capabilities preserved across execve.
|
||||
Inheritable []string `json:"inheritable,omitempty" platform:"linux"`
|
||||
// Permitted is the limiting superset for effective capabilities.
|
||||
Permitted []string `json:"permitted,omitempty" platform:"linux"`
|
||||
// Ambient is the ambient set of capabilities that are kept.
|
||||
Ambient []string `json:"ambient,omitempty" platform:"linux"`
|
||||
}
|
||||
|
||||
// Box specifies dimensions of a rectangle. Used for specifying the size of a console.
|
||||
type Box struct {
|
||||
// Height is the vertical dimension of a box.
|
||||
Height uint `json:"height"`
|
||||
// Width is the horizontal dimension of a box.
|
||||
Width uint `json:"width"`
|
||||
}
|
||||
|
||||
// User specifies specific user (and group) information for the container process.
|
||||
type User struct {
|
||||
// UID is the user id.
|
||||
UID uint32 `json:"uid" platform:"linux,solaris"`
|
||||
// GID is the group id.
|
||||
GID uint32 `json:"gid" platform:"linux,solaris"`
|
||||
// Umask is the umask for the init process.
|
||||
Umask uint32 `json:"umask,omitempty" platform:"linux,solaris"`
|
||||
// AdditionalGids are additional group ids set for the container's process.
|
||||
AdditionalGids []uint32 `json:"additionalGids,omitempty" platform:"linux,solaris"`
|
||||
// Username is the user name.
|
||||
Username string `json:"username,omitempty" platform:"windows"`
|
||||
}
|
||||
|
||||
// Root contains information about the container's root filesystem on the host.
|
||||
type Root struct {
|
||||
// Path is the absolute path to the container's root filesystem.
|
||||
Path string `json:"path"`
|
||||
// Readonly makes the root filesystem for the container readonly before the process is executed.
|
||||
Readonly bool `json:"readonly,omitempty"`
|
||||
}
|
||||
|
||||
// Mount specifies a mount for a container.
|
||||
type Mount struct {
|
||||
// Destination is the absolute path where the mount will be placed in the container.
|
||||
Destination string `json:"destination"`
|
||||
// Type specifies the mount kind.
|
||||
Type string `json:"type,omitempty" platform:"linux,solaris"`
|
||||
// Source specifies the source path of the mount.
|
||||
Source string `json:"source,omitempty"`
|
||||
// Options are fstab style mount options.
|
||||
Options []string `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
// Hook specifies a command that is run at a particular event in the lifecycle of a container
|
||||
type Hook struct {
|
||||
Path string `json:"path"`
|
||||
Args []string `json:"args,omitempty"`
|
||||
Env []string `json:"env,omitempty"`
|
||||
Timeout *int `json:"timeout,omitempty"`
|
||||
}
|
||||
|
||||
// Hooks specifies a command that is run in the container at a particular event in the lifecycle of a container
|
||||
// Hooks for container setup and teardown
|
||||
type Hooks struct {
|
||||
// Prestart is Deprecated. Prestart is a list of hooks to be run before the container process is executed.
|
||||
// It is called in the Runtime Namespace
|
||||
Prestart []Hook `json:"prestart,omitempty"`
|
||||
// CreateRuntime is a list of hooks to be run after the container has been created but before pivot_root or any equivalent operation has been called
|
||||
// It is called in the Runtime Namespace
|
||||
CreateRuntime []Hook `json:"createRuntime,omitempty"`
|
||||
// CreateContainer is a list of hooks to be run after the container has been created but before pivot_root or any equivalent operation has been called
|
||||
// It is called in the Container Namespace
|
||||
CreateContainer []Hook `json:"createContainer,omitempty"`
|
||||
// StartContainer is a list of hooks to be run after the start operation is called but before the container process is started
|
||||
// It is called in the Container Namespace
|
||||
StartContainer []Hook `json:"startContainer,omitempty"`
|
||||
// Poststart is a list of hooks to be run after the container process is started.
|
||||
// It is called in the Runtime Namespace
|
||||
Poststart []Hook `json:"poststart,omitempty"`
|
||||
// Poststop is a list of hooks to be run after the container process exits.
|
||||
// It is called in the Runtime Namespace
|
||||
Poststop []Hook `json:"poststop,omitempty"`
|
||||
}
|
||||
|
||||
// Linux contains platform-specific configuration for Linux based containers.
|
||||
type Linux struct {
|
||||
// UIDMapping specifies user mappings for supporting user namespaces.
|
||||
UIDMappings []LinuxIDMapping `json:"uidMappings,omitempty"`
|
||||
// GIDMapping specifies group mappings for supporting user namespaces.
|
||||
GIDMappings []LinuxIDMapping `json:"gidMappings,omitempty"`
|
||||
// Sysctl are a set of key value pairs that are set for the container on start
|
||||
Sysctl map[string]string `json:"sysctl,omitempty"`
|
||||
// Resources contain cgroup information for handling resource constraints
|
||||
// for the container
|
||||
Resources *LinuxResources `json:"resources,omitempty"`
|
||||
// CgroupsPath specifies the path to cgroups that are created and/or joined by the container.
|
||||
// The path is expected to be relative to the cgroups mountpoint.
|
||||
// If resources are specified, the cgroups at CgroupsPath will be updated based on resources.
|
||||
CgroupsPath string `json:"cgroupsPath,omitempty"`
|
||||
// Namespaces contains the namespaces that are created and/or joined by the container
|
||||
Namespaces []LinuxNamespace `json:"namespaces,omitempty"`
|
||||
// Devices are a list of device nodes that are created for the container
|
||||
Devices []LinuxDevice `json:"devices,omitempty"`
|
||||
// Seccomp specifies the seccomp security settings for the container.
|
||||
Seccomp *LinuxSeccomp `json:"seccomp,omitempty"`
|
||||
// RootfsPropagation is the rootfs mount propagation mode for the container.
|
||||
RootfsPropagation string `json:"rootfsPropagation,omitempty"`
|
||||
// MaskedPaths masks over the provided paths inside the container.
|
||||
MaskedPaths []string `json:"maskedPaths,omitempty"`
|
||||
// ReadonlyPaths sets the provided paths as RO inside the container.
|
||||
ReadonlyPaths []string `json:"readonlyPaths,omitempty"`
|
||||
// MountLabel specifies the selinux context for the mounts in the container.
|
||||
MountLabel string `json:"mountLabel,omitempty"`
|
||||
// IntelRdt contains Intel Resource Director Technology (RDT) information for
|
||||
// handling resource constraints (e.g., L3 cache, memory bandwidth) for the container
|
||||
IntelRdt *LinuxIntelRdt `json:"intelRdt,omitempty"`
|
||||
// Personality contains configuration for the Linux personality syscall
|
||||
Personality *LinuxPersonality `json:"personality,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxNamespace is the configuration for a Linux namespace
|
||||
type LinuxNamespace struct {
|
||||
// Type is the type of namespace
|
||||
Type LinuxNamespaceType `json:"type"`
|
||||
// Path is a path to an existing namespace persisted on disk that can be joined
|
||||
// and is of the same type
|
||||
Path string `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxNamespaceType is one of the Linux namespaces
|
||||
type LinuxNamespaceType string
|
||||
|
||||
const (
|
||||
// PIDNamespace for isolating process IDs
|
||||
PIDNamespace LinuxNamespaceType = "pid"
|
||||
// NetworkNamespace for isolating network devices, stacks, ports, etc
|
||||
NetworkNamespace LinuxNamespaceType = "network"
|
||||
// MountNamespace for isolating mount points
|
||||
MountNamespace LinuxNamespaceType = "mount"
|
||||
// IPCNamespace for isolating System V IPC, POSIX message queues
|
||||
IPCNamespace LinuxNamespaceType = "ipc"
|
||||
// UTSNamespace for isolating hostname and NIS domain name
|
||||
UTSNamespace LinuxNamespaceType = "uts"
|
||||
// UserNamespace for isolating user and group IDs
|
||||
UserNamespace LinuxNamespaceType = "user"
|
||||
// CgroupNamespace for isolating cgroup hierarchies
|
||||
CgroupNamespace LinuxNamespaceType = "cgroup"
|
||||
)
|
||||
|
||||
// LinuxIDMapping specifies UID/GID mappings
|
||||
type LinuxIDMapping struct {
|
||||
// ContainerID is the starting UID/GID in the container
|
||||
ContainerID uint32 `json:"containerID"`
|
||||
// HostID is the starting UID/GID on the host to be mapped to 'ContainerID'
|
||||
HostID uint32 `json:"hostID"`
|
||||
// Size is the number of IDs to be mapped
|
||||
Size uint32 `json:"size"`
|
||||
}
|
||||
|
||||
// POSIXRlimit type and restrictions
|
||||
type POSIXRlimit struct {
|
||||
// Type of the rlimit to set
|
||||
Type string `json:"type"`
|
||||
// Hard is the hard limit for the specified type
|
||||
Hard uint64 `json:"hard"`
|
||||
// Soft is the soft limit for the specified type
|
||||
Soft uint64 `json:"soft"`
|
||||
}
|
||||
|
||||
// LinuxHugepageLimit structure corresponds to limiting kernel hugepages
|
||||
type LinuxHugepageLimit struct {
|
||||
// Pagesize is the hugepage size
|
||||
// Format: "<size><unit-prefix>B' (e.g. 64KB, 2MB, 1GB, etc.)
|
||||
Pagesize string `json:"pageSize"`
|
||||
// Limit is the limit of "hugepagesize" hugetlb usage
|
||||
Limit uint64 `json:"limit"`
|
||||
}
|
||||
|
||||
// LinuxInterfacePriority for network interfaces
|
||||
type LinuxInterfacePriority struct {
|
||||
// Name is the name of the network interface
|
||||
Name string `json:"name"`
|
||||
// Priority for the interface
|
||||
Priority uint32 `json:"priority"`
|
||||
}
|
||||
|
||||
// linuxBlockIODevice holds major:minor format supported in blkio cgroup
|
||||
type linuxBlockIODevice struct {
|
||||
// Major is the device's major number.
|
||||
Major int64 `json:"major"`
|
||||
// Minor is the device's minor number.
|
||||
Minor int64 `json:"minor"`
|
||||
}
|
||||
|
||||
// LinuxWeightDevice struct holds a `major:minor weight` pair for weightDevice
|
||||
type LinuxWeightDevice struct {
|
||||
linuxBlockIODevice
|
||||
// Weight is the bandwidth rate for the device.
|
||||
Weight *uint16 `json:"weight,omitempty"`
|
||||
// LeafWeight is the bandwidth rate for the device while competing with the cgroup's child cgroups, CFQ scheduler only
|
||||
LeafWeight *uint16 `json:"leafWeight,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxThrottleDevice struct holds a `major:minor rate_per_second` pair
|
||||
type LinuxThrottleDevice struct {
|
||||
linuxBlockIODevice
|
||||
// Rate is the IO rate limit per cgroup per device
|
||||
Rate uint64 `json:"rate"`
|
||||
}
|
||||
|
||||
// LinuxBlockIO for Linux cgroup 'blkio' resource management
|
||||
type LinuxBlockIO struct {
|
||||
// Specifies per cgroup weight
|
||||
Weight *uint16 `json:"weight,omitempty"`
|
||||
// Specifies tasks' weight in the given cgroup while competing with the cgroup's child cgroups, CFQ scheduler only
|
||||
LeafWeight *uint16 `json:"leafWeight,omitempty"`
|
||||
// Weight per cgroup per device, can override BlkioWeight
|
||||
WeightDevice []LinuxWeightDevice `json:"weightDevice,omitempty"`
|
||||
// IO read rate limit per cgroup per device, bytes per second
|
||||
ThrottleReadBpsDevice []LinuxThrottleDevice `json:"throttleReadBpsDevice,omitempty"`
|
||||
// IO write rate limit per cgroup per device, bytes per second
|
||||
ThrottleWriteBpsDevice []LinuxThrottleDevice `json:"throttleWriteBpsDevice,omitempty"`
|
||||
// IO read rate limit per cgroup per device, IO per second
|
||||
ThrottleReadIOPSDevice []LinuxThrottleDevice `json:"throttleReadIOPSDevice,omitempty"`
|
||||
// IO write rate limit per cgroup per device, IO per second
|
||||
ThrottleWriteIOPSDevice []LinuxThrottleDevice `json:"throttleWriteIOPSDevice,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxMemory for Linux cgroup 'memory' resource management
|
||||
type LinuxMemory struct {
|
||||
// Memory limit (in bytes).
|
||||
Limit *int64 `json:"limit,omitempty"`
|
||||
// Memory reservation or soft_limit (in bytes).
|
||||
Reservation *int64 `json:"reservation,omitempty"`
|
||||
// Total memory limit (memory + swap).
|
||||
Swap *int64 `json:"swap,omitempty"`
|
||||
// Kernel memory limit (in bytes).
|
||||
Kernel *int64 `json:"kernel,omitempty"`
|
||||
// Kernel memory limit for tcp (in bytes)
|
||||
KernelTCP *int64 `json:"kernelTCP,omitempty"`
|
||||
// How aggressive the kernel will swap memory pages.
|
||||
Swappiness *uint64 `json:"swappiness,omitempty"`
|
||||
// DisableOOMKiller disables the OOM killer for out of memory conditions
|
||||
DisableOOMKiller *bool `json:"disableOOMKiller,omitempty"`
|
||||
// Enables hierarchical memory accounting
|
||||
UseHierarchy *bool `json:"useHierarchy,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxCPU for Linux cgroup 'cpu' resource management
|
||||
type LinuxCPU struct {
|
||||
// CPU shares (relative weight (ratio) vs. other cgroups with cpu shares).
|
||||
Shares *uint64 `json:"shares,omitempty"`
|
||||
// CPU hardcap limit (in usecs). Allowed cpu time in a given period.
|
||||
Quota *int64 `json:"quota,omitempty"`
|
||||
// CPU period to be used for hardcapping (in usecs).
|
||||
Period *uint64 `json:"period,omitempty"`
|
||||
// How much time realtime scheduling may use (in usecs).
|
||||
RealtimeRuntime *int64 `json:"realtimeRuntime,omitempty"`
|
||||
// CPU period to be used for realtime scheduling (in usecs).
|
||||
RealtimePeriod *uint64 `json:"realtimePeriod,omitempty"`
|
||||
// CPUs to use within the cpuset. Default is to use any CPU available.
|
||||
Cpus string `json:"cpus,omitempty"`
|
||||
// List of memory nodes in the cpuset. Default is to use any available memory node.
|
||||
Mems string `json:"mems,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxPids for Linux cgroup 'pids' resource management (Linux 4.3)
|
||||
type LinuxPids struct {
|
||||
// Maximum number of PIDs. Default is "no limit".
|
||||
Limit int64 `json:"limit"`
|
||||
}
|
||||
|
||||
// LinuxNetwork identification and priority configuration
|
||||
type LinuxNetwork struct {
|
||||
// Set class identifier for container's network packets
|
||||
ClassID *uint32 `json:"classID,omitempty"`
|
||||
// Set priority of network traffic for container
|
||||
Priorities []LinuxInterfacePriority `json:"priorities,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxRdma for Linux cgroup 'rdma' resource management (Linux 4.11)
|
||||
type LinuxRdma struct {
|
||||
// Maximum number of HCA handles that can be opened. Default is "no limit".
|
||||
HcaHandles *uint32 `json:"hcaHandles,omitempty"`
|
||||
// Maximum number of HCA objects that can be created. Default is "no limit".
|
||||
HcaObjects *uint32 `json:"hcaObjects,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxResources has container runtime resource constraints
|
||||
type LinuxResources struct {
|
||||
// Devices configures the device whitelist.
|
||||
Devices []LinuxDeviceCgroup `json:"devices,omitempty"`
|
||||
// Memory restriction configuration
|
||||
Memory *LinuxMemory `json:"memory,omitempty"`
|
||||
// CPU resource restriction configuration
|
||||
CPU *LinuxCPU `json:"cpu,omitempty"`
|
||||
// Task resource restriction configuration.
|
||||
Pids *LinuxPids `json:"pids,omitempty"`
|
||||
// BlockIO restriction configuration
|
||||
BlockIO *LinuxBlockIO `json:"blockIO,omitempty"`
|
||||
// Hugetlb limit (in bytes)
|
||||
HugepageLimits []LinuxHugepageLimit `json:"hugepageLimits,omitempty"`
|
||||
// Network restriction configuration
|
||||
Network *LinuxNetwork `json:"network,omitempty"`
|
||||
// Rdma resource restriction configuration.
|
||||
// Limits are a set of key value pairs that define RDMA resource limits,
|
||||
// where the key is device name and value is resource limits.
|
||||
Rdma map[string]LinuxRdma `json:"rdma,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxDevice represents the mknod information for a Linux special device file
|
||||
type LinuxDevice struct {
|
||||
// Path to the device.
|
||||
Path string `json:"path"`
|
||||
// Device type, block, char, etc.
|
||||
Type string `json:"type"`
|
||||
// Major is the device's major number.
|
||||
Major int64 `json:"major"`
|
||||
// Minor is the device's minor number.
|
||||
Minor int64 `json:"minor"`
|
||||
// FileMode permission bits for the device.
|
||||
FileMode *os.FileMode `json:"fileMode,omitempty"`
|
||||
// UID of the device.
|
||||
UID *uint32 `json:"uid,omitempty"`
|
||||
// Gid of the device.
|
||||
GID *uint32 `json:"gid,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxDeviceCgroup represents a device rule for the whitelist controller
|
||||
type LinuxDeviceCgroup struct {
|
||||
// Allow or deny
|
||||
Allow bool `json:"allow"`
|
||||
// Device type, block, char, etc.
|
||||
Type string `json:"type,omitempty"`
|
||||
// Major is the device's major number.
|
||||
Major *int64 `json:"major,omitempty"`
|
||||
// Minor is the device's minor number.
|
||||
Minor *int64 `json:"minor,omitempty"`
|
||||
// Cgroup access permissions format, rwm.
|
||||
Access string `json:"access,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxPersonalityDomain refers to a personality domain.
|
||||
type LinuxPersonalityDomain string
|
||||
|
||||
// LinuxPersonalityFlag refers to an additional personality flag. None are currently defined.
|
||||
type LinuxPersonalityFlag string
|
||||
|
||||
// Define domain and flags for Personality
|
||||
const (
|
||||
// PerLinux is the standard Linux personality
|
||||
PerLinux LinuxPersonalityDomain = "LINUX"
|
||||
// PerLinux32 sets personality to 32 bit
|
||||
PerLinux32 LinuxPersonalityDomain = "LINUX32"
|
||||
)
|
||||
|
||||
// LinuxPersonality represents the Linux personality syscall input
|
||||
type LinuxPersonality struct {
|
||||
// Domain for the personality
|
||||
Domain LinuxPersonalityDomain `json:"domain"`
|
||||
// Additional flags
|
||||
Flags []LinuxPersonalityFlag `json:"flags,omitempty"`
|
||||
}
|
||||
|
||||
// Solaris contains platform-specific configuration for Solaris application containers.
|
||||
type Solaris struct {
|
||||
// SMF FMRI which should go "online" before we start the container process.
|
||||
Milestone string `json:"milestone,omitempty"`
|
||||
// Maximum set of privileges any process in this container can obtain.
|
||||
LimitPriv string `json:"limitpriv,omitempty"`
|
||||
// The maximum amount of shared memory allowed for this container.
|
||||
MaxShmMemory string `json:"maxShmMemory,omitempty"`
|
||||
// Specification for automatic creation of network resources for this container.
|
||||
Anet []SolarisAnet `json:"anet,omitempty"`
|
||||
// Set limit on the amount of CPU time that can be used by container.
|
||||
CappedCPU *SolarisCappedCPU `json:"cappedCPU,omitempty"`
|
||||
// The physical and swap caps on the memory that can be used by this container.
|
||||
CappedMemory *SolarisCappedMemory `json:"cappedMemory,omitempty"`
|
||||
}
|
||||
|
||||
// SolarisCappedCPU allows users to set limit on the amount of CPU time that can be used by container.
|
||||
type SolarisCappedCPU struct {
|
||||
Ncpus string `json:"ncpus,omitempty"`
|
||||
}
|
||||
|
||||
// SolarisCappedMemory allows users to set the physical and swap caps on the memory that can be used by this container.
|
||||
type SolarisCappedMemory struct {
|
||||
Physical string `json:"physical,omitempty"`
|
||||
Swap string `json:"swap,omitempty"`
|
||||
}
|
||||
|
||||
// SolarisAnet provides the specification for automatic creation of network resources for this container.
|
||||
type SolarisAnet struct {
|
||||
// Specify a name for the automatically created VNIC datalink.
|
||||
Linkname string `json:"linkname,omitempty"`
|
||||
// Specify the link over which the VNIC will be created.
|
||||
Lowerlink string `json:"lowerLink,omitempty"`
|
||||
// The set of IP addresses that the container can use.
|
||||
Allowedaddr string `json:"allowedAddress,omitempty"`
|
||||
// Specifies whether allowedAddress limitation is to be applied to the VNIC.
|
||||
Configallowedaddr string `json:"configureAllowedAddress,omitempty"`
|
||||
// The value of the optional default router.
|
||||
Defrouter string `json:"defrouter,omitempty"`
|
||||
// Enable one or more types of link protection.
|
||||
Linkprotection string `json:"linkProtection,omitempty"`
|
||||
// Set the VNIC's macAddress
|
||||
Macaddress string `json:"macAddress,omitempty"`
|
||||
}
|
||||
|
||||
// Windows defines the runtime configuration for Windows based containers, including Hyper-V containers.
|
||||
type Windows struct {
|
||||
// LayerFolders contains a list of absolute paths to directories containing image layers.
|
||||
LayerFolders []string `json:"layerFolders"`
|
||||
// Devices are the list of devices to be mapped into the container.
|
||||
Devices []WindowsDevice `json:"devices,omitempty"`
|
||||
// Resources contains information for handling resource constraints for the container.
|
||||
Resources *WindowsResources `json:"resources,omitempty"`
|
||||
// CredentialSpec contains a JSON object describing a group Managed Service Account (gMSA) specification.
|
||||
CredentialSpec interface{} `json:"credentialSpec,omitempty"`
|
||||
// Servicing indicates if the container is being started in a mode to apply a Windows Update servicing operation.
|
||||
Servicing bool `json:"servicing,omitempty"`
|
||||
// IgnoreFlushesDuringBoot indicates if the container is being started in a mode where disk writes are not flushed during its boot process.
|
||||
IgnoreFlushesDuringBoot bool `json:"ignoreFlushesDuringBoot,omitempty"`
|
||||
// HyperV contains information for running a container with Hyper-V isolation.
|
||||
HyperV *WindowsHyperV `json:"hyperv,omitempty"`
|
||||
// Network restriction configuration.
|
||||
Network *WindowsNetwork `json:"network,omitempty"`
|
||||
}
|
||||
|
||||
// WindowsDevice represents information about a host device to be mapped into the container.
|
||||
type WindowsDevice struct {
|
||||
// Device identifier: interface class GUID, etc.
|
||||
ID string `json:"id"`
|
||||
// Device identifier type: "class", etc.
|
||||
IDType string `json:"idType"`
|
||||
}
|
||||
|
||||
// WindowsResources has container runtime resource constraints for containers running on Windows.
|
||||
type WindowsResources struct {
|
||||
// Memory restriction configuration.
|
||||
Memory *WindowsMemoryResources `json:"memory,omitempty"`
|
||||
// CPU resource restriction configuration.
|
||||
CPU *WindowsCPUResources `json:"cpu,omitempty"`
|
||||
// Storage restriction configuration.
|
||||
Storage *WindowsStorageResources `json:"storage,omitempty"`
|
||||
}
|
||||
|
||||
// WindowsMemoryResources contains memory resource management settings.
|
||||
type WindowsMemoryResources struct {
|
||||
// Memory limit in bytes.
|
||||
Limit *uint64 `json:"limit,omitempty"`
|
||||
}
|
||||
|
||||
// WindowsCPUResources contains CPU resource management settings.
|
||||
type WindowsCPUResources struct {
|
||||
// Number of CPUs available to the container.
|
||||
Count *uint64 `json:"count,omitempty"`
|
||||
// CPU shares (relative weight to other containers with cpu shares).
|
||||
Shares *uint16 `json:"shares,omitempty"`
|
||||
// Specifies the portion of processor cycles that this container can use as a percentage times 100.
|
||||
Maximum *uint16 `json:"maximum,omitempty"`
|
||||
}
|
||||
|
||||
// WindowsStorageResources contains storage resource management settings.
|
||||
type WindowsStorageResources struct {
|
||||
// Specifies maximum Iops for the system drive.
|
||||
Iops *uint64 `json:"iops,omitempty"`
|
||||
// Specifies maximum bytes per second for the system drive.
|
||||
Bps *uint64 `json:"bps,omitempty"`
|
||||
// Sandbox size specifies the minimum size of the system drive in bytes.
|
||||
SandboxSize *uint64 `json:"sandboxSize,omitempty"`
|
||||
}
|
||||
|
||||
// WindowsNetwork contains network settings for Windows containers.
|
||||
type WindowsNetwork struct {
|
||||
// List of HNS endpoints that the container should connect to.
|
||||
EndpointList []string `json:"endpointList,omitempty"`
|
||||
// Specifies if unqualified DNS name resolution is allowed.
|
||||
AllowUnqualifiedDNSQuery bool `json:"allowUnqualifiedDNSQuery,omitempty"`
|
||||
// Comma separated list of DNS suffixes to use for name resolution.
|
||||
DNSSearchList []string `json:"DNSSearchList,omitempty"`
|
||||
// Name (ID) of the container that we will share with the network stack.
|
||||
NetworkSharedContainerName string `json:"networkSharedContainerName,omitempty"`
|
||||
// name (ID) of the network namespace that will be used for the container.
|
||||
NetworkNamespace string `json:"networkNamespace,omitempty"`
|
||||
}
|
||||
|
||||
// WindowsHyperV contains information for configuring a container to run with Hyper-V isolation.
|
||||
type WindowsHyperV struct {
|
||||
// UtilityVMPath is an optional path to the image used for the Utility VM.
|
||||
UtilityVMPath string `json:"utilityVMPath,omitempty"`
|
||||
}
|
||||
|
||||
// VM contains information for virtual-machine-based containers.
|
||||
type VM struct {
|
||||
// Hypervisor specifies hypervisor-related configuration for virtual-machine-based containers.
|
||||
Hypervisor VMHypervisor `json:"hypervisor,omitempty"`
|
||||
// Kernel specifies kernel-related configuration for virtual-machine-based containers.
|
||||
Kernel VMKernel `json:"kernel"`
|
||||
// Image specifies guest image related configuration for virtual-machine-based containers.
|
||||
Image VMImage `json:"image,omitempty"`
|
||||
}
|
||||
|
||||
// VMHypervisor contains information about the hypervisor to use for a virtual machine.
|
||||
type VMHypervisor struct {
|
||||
// Path is the host path to the hypervisor used to manage the virtual machine.
|
||||
Path string `json:"path"`
|
||||
// Parameters specifies parameters to pass to the hypervisor.
|
||||
Parameters []string `json:"parameters,omitempty"`
|
||||
}
|
||||
|
||||
// VMKernel contains information about the kernel to use for a virtual machine.
|
||||
type VMKernel struct {
|
||||
// Path is the host path to the kernel used to boot the virtual machine.
|
||||
Path string `json:"path"`
|
||||
// Parameters specifies parameters to pass to the kernel.
|
||||
Parameters []string `json:"parameters,omitempty"`
|
||||
// InitRD is the host path to an initial ramdisk to be used by the kernel.
|
||||
InitRD string `json:"initrd,omitempty"`
|
||||
}
|
||||
|
||||
// VMImage contains information about the virtual machine root image.
|
||||
type VMImage struct {
|
||||
// Path is the host path to the root image that the VM kernel would boot into.
|
||||
Path string `json:"path"`
|
||||
// Format is the root image format type (e.g. "qcow2", "raw", "vhd", etc).
|
||||
Format string `json:"format"`
|
||||
}
|
||||
|
||||
// LinuxSeccomp represents syscall restrictions
|
||||
type LinuxSeccomp struct {
|
||||
DefaultAction LinuxSeccompAction `json:"defaultAction"`
|
||||
Architectures []Arch `json:"architectures,omitempty"`
|
||||
Flags []LinuxSeccompFlag `json:"flags,omitempty"`
|
||||
Syscalls []LinuxSyscall `json:"syscalls,omitempty"`
|
||||
}
|
||||
|
||||
// Arch used for additional architectures
|
||||
type Arch string
|
||||
|
||||
// LinuxSeccompFlag is a flag to pass to seccomp(2).
|
||||
type LinuxSeccompFlag string
|
||||
|
||||
// Additional architectures permitted to be used for system calls
|
||||
// By default only the native architecture of the kernel is permitted
|
||||
const (
|
||||
ArchX86 Arch = "SCMP_ARCH_X86"
|
||||
ArchX86_64 Arch = "SCMP_ARCH_X86_64"
|
||||
ArchX32 Arch = "SCMP_ARCH_X32"
|
||||
ArchARM Arch = "SCMP_ARCH_ARM"
|
||||
ArchAARCH64 Arch = "SCMP_ARCH_AARCH64"
|
||||
ArchMIPS Arch = "SCMP_ARCH_MIPS"
|
||||
ArchMIPS64 Arch = "SCMP_ARCH_MIPS64"
|
||||
ArchMIPS64N32 Arch = "SCMP_ARCH_MIPS64N32"
|
||||
ArchMIPSEL Arch = "SCMP_ARCH_MIPSEL"
|
||||
ArchMIPSEL64 Arch = "SCMP_ARCH_MIPSEL64"
|
||||
ArchMIPSEL64N32 Arch = "SCMP_ARCH_MIPSEL64N32"
|
||||
ArchPPC Arch = "SCMP_ARCH_PPC"
|
||||
ArchPPC64 Arch = "SCMP_ARCH_PPC64"
|
||||
ArchPPC64LE Arch = "SCMP_ARCH_PPC64LE"
|
||||
ArchS390 Arch = "SCMP_ARCH_S390"
|
||||
ArchS390X Arch = "SCMP_ARCH_S390X"
|
||||
ArchPARISC Arch = "SCMP_ARCH_PARISC"
|
||||
ArchPARISC64 Arch = "SCMP_ARCH_PARISC64"
|
||||
)
|
||||
|
||||
// LinuxSeccompAction taken upon Seccomp rule match
|
||||
type LinuxSeccompAction string
|
||||
|
||||
// Define actions for Seccomp rules
|
||||
const (
|
||||
ActKill LinuxSeccompAction = "SCMP_ACT_KILL"
|
||||
ActTrap LinuxSeccompAction = "SCMP_ACT_TRAP"
|
||||
ActErrno LinuxSeccompAction = "SCMP_ACT_ERRNO"
|
||||
ActTrace LinuxSeccompAction = "SCMP_ACT_TRACE"
|
||||
ActAllow LinuxSeccompAction = "SCMP_ACT_ALLOW"
|
||||
ActLog LinuxSeccompAction = "SCMP_ACT_LOG"
|
||||
)
|
||||
|
||||
// LinuxSeccompOperator used to match syscall arguments in Seccomp
|
||||
type LinuxSeccompOperator string
|
||||
|
||||
// Define operators for syscall arguments in Seccomp
|
||||
const (
|
||||
OpNotEqual LinuxSeccompOperator = "SCMP_CMP_NE"
|
||||
OpLessThan LinuxSeccompOperator = "SCMP_CMP_LT"
|
||||
OpLessEqual LinuxSeccompOperator = "SCMP_CMP_LE"
|
||||
OpEqualTo LinuxSeccompOperator = "SCMP_CMP_EQ"
|
||||
OpGreaterEqual LinuxSeccompOperator = "SCMP_CMP_GE"
|
||||
OpGreaterThan LinuxSeccompOperator = "SCMP_CMP_GT"
|
||||
OpMaskedEqual LinuxSeccompOperator = "SCMP_CMP_MASKED_EQ"
|
||||
)
|
||||
|
||||
// LinuxSeccompArg used for matching specific syscall arguments in Seccomp
|
||||
type LinuxSeccompArg struct {
|
||||
Index uint `json:"index"`
|
||||
Value uint64 `json:"value"`
|
||||
ValueTwo uint64 `json:"valueTwo,omitempty"`
|
||||
Op LinuxSeccompOperator `json:"op"`
|
||||
}
|
||||
|
||||
// LinuxSyscall is used to match a syscall in Seccomp
|
||||
type LinuxSyscall struct {
|
||||
Names []string `json:"names"`
|
||||
Action LinuxSeccompAction `json:"action"`
|
||||
Args []LinuxSeccompArg `json:"args,omitempty"`
|
||||
}
|
||||
|
||||
// LinuxIntelRdt has container runtime resource constraints for Intel RDT
|
||||
// CAT and MBA features which introduced in Linux 4.10 and 4.12 kernel
|
||||
type LinuxIntelRdt struct {
|
||||
// The identity for RDT Class of Service
|
||||
ClosID string `json:"closID,omitempty"`
|
||||
// The schema for L3 cache id and capacity bitmask (CBM)
|
||||
// Format: "L3:<cache_id0>=<cbm0>;<cache_id1>=<cbm1>;..."
|
||||
L3CacheSchema string `json:"l3CacheSchema,omitempty"`
|
||||
|
||||
// The schema of memory bandwidth per L3 cache id
|
||||
// Format: "MB:<cache_id0>=bandwidth0;<cache_id1>=bandwidth1;..."
|
||||
// The unit of memory bandwidth is specified in "percentages" by
|
||||
// default, and in "MBps" if MBA Software Controller is enabled.
|
||||
MemBwSchema string `json:"memBwSchema,omitempty"`
|
||||
}
|
||||
17
vendor/github.com/opencontainers/runtime-spec/specs-go/state.go
generated
vendored
Normal file
17
vendor/github.com/opencontainers/runtime-spec/specs-go/state.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
package specs
|
||||
|
||||
// State holds information about the runtime state of the container.
|
||||
type State struct {
|
||||
// Version is the version of the specification that is supported.
|
||||
Version string `json:"ociVersion"`
|
||||
// ID is the container ID
|
||||
ID string `json:"id"`
|
||||
// Status is the runtime status of the container.
|
||||
Status string `json:"status"`
|
||||
// Pid is the process ID for the container process.
|
||||
Pid int `json:"pid,omitempty"`
|
||||
// Bundle is the path to the container's bundle directory.
|
||||
Bundle string `json:"bundle"`
|
||||
// Annotations are key values associated with the container.
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
18
vendor/github.com/opencontainers/runtime-spec/specs-go/version.go
generated
vendored
Normal file
18
vendor/github.com/opencontainers/runtime-spec/specs-go/version.go
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
package specs
|
||||
|
||||
import "fmt"
|
||||
|
||||
const (
|
||||
// VersionMajor is for an API incompatible changes
|
||||
VersionMajor = 1
|
||||
// VersionMinor is for functionality in a backwards-compatible manner
|
||||
VersionMinor = 0
|
||||
// VersionPatch is for backwards-compatible bug fixes
|
||||
VersionPatch = 2
|
||||
|
||||
// VersionDev indicates development branch. Releases will be empty string.
|
||||
VersionDev = ""
|
||||
)
|
||||
|
||||
// Version is the specification version that the package types support.
|
||||
var Version = fmt.Sprintf("%d.%d.%d%s", VersionMajor, VersionMinor, VersionPatch, VersionDev)
|
||||
2
vendor/github.com/pelletier/go-toml/.dockerignore
generated
vendored
Normal file
2
vendor/github.com/pelletier/go-toml/.dockerignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
cmd/tomll/tomll
|
||||
cmd/tomljson/tomljson
|
||||
5
vendor/github.com/pelletier/go-toml/.gitignore
generated
vendored
Normal file
5
vendor/github.com/pelletier/go-toml/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
test_program/test_program_bin
|
||||
fuzz/
|
||||
cmd/tomll/tomll
|
||||
cmd/tomljson/tomljson
|
||||
cmd/tomltestgen/tomltestgen
|
||||
132
vendor/github.com/pelletier/go-toml/CONTRIBUTING.md
generated
vendored
Normal file
132
vendor/github.com/pelletier/go-toml/CONTRIBUTING.md
generated
vendored
Normal file
@@ -0,0 +1,132 @@
|
||||
## Contributing
|
||||
|
||||
Thank you for your interest in go-toml! We appreciate you considering
|
||||
contributing to go-toml!
|
||||
|
||||
The main goal is the project is to provide an easy-to-use TOML
|
||||
implementation for Go that gets the job done and gets out of your way –
|
||||
dealing with TOML is probably not the central piece of your project.
|
||||
|
||||
As the single maintainer of go-toml, time is scarce. All help, big or
|
||||
small, is more than welcomed!
|
||||
|
||||
### Ask questions
|
||||
|
||||
Any question you may have, somebody else might have it too. Always feel
|
||||
free to ask them on the [issues tracker][issues-tracker]. We will try to
|
||||
answer them as clearly and quickly as possible, time permitting.
|
||||
|
||||
Asking questions also helps us identify areas where the documentation needs
|
||||
improvement, or new features that weren't envisioned before. Sometimes, a
|
||||
seemingly innocent question leads to the fix of a bug. Don't hesitate and
|
||||
ask away!
|
||||
|
||||
### Improve the documentation
|
||||
|
||||
The best way to share your knowledge and experience with go-toml is to
|
||||
improve the documentation. Fix a typo, clarify an interface, add an
|
||||
example, anything goes!
|
||||
|
||||
The documentation is present in the [README][readme] and thorough the
|
||||
source code. On release, it gets updated on [pkg.go.dev][pkg.go.dev]. To make a
|
||||
change to the documentation, create a pull request with your proposed
|
||||
changes. For simple changes like that, the easiest way to go is probably
|
||||
the "Fork this project and edit the file" button on Github, displayed at
|
||||
the top right of the file. Unless it's a trivial change (for example a
|
||||
typo), provide a little bit of context in your pull request description or
|
||||
commit message.
|
||||
|
||||
### Report a bug
|
||||
|
||||
Found a bug! Sorry to hear that :(. Help us and other track them down and
|
||||
fix by reporting it. [File a new bug report][bug-report] on the [issues
|
||||
tracker][issues-tracker]. The template should provide enough guidance on
|
||||
what to include. When in doubt: add more details! By reducing ambiguity and
|
||||
providing more information, it decreases back and forth and saves everyone
|
||||
time.
|
||||
|
||||
### Code changes
|
||||
|
||||
Want to contribute a patch? Very happy to hear that!
|
||||
|
||||
First, some high-level rules:
|
||||
|
||||
* A short proposal with some POC code is better than a lengthy piece of
|
||||
text with no code. Code speaks louder than words.
|
||||
* No backward-incompatible patch will be accepted unless discussed.
|
||||
Sometimes it's hard, and Go's lack of versioning by default does not
|
||||
help, but we try not to break people's programs unless we absolutely have
|
||||
to.
|
||||
* If you are writing a new feature or extending an existing one, make sure
|
||||
to write some documentation.
|
||||
* Bug fixes need to be accompanied with regression tests.
|
||||
* New code needs to be tested.
|
||||
* Your commit messages need to explain why the change is needed, even if
|
||||
already included in the PR description.
|
||||
|
||||
It does sound like a lot, but those best practices are here to save time
|
||||
overall and continuously improve the quality of the project, which is
|
||||
something everyone benefits from.
|
||||
|
||||
#### Get started
|
||||
|
||||
The fairly standard code contribution process looks like that:
|
||||
|
||||
1. [Fork the project][fork].
|
||||
2. Make your changes, commit on any branch you like.
|
||||
3. [Open up a pull request][pull-request]
|
||||
4. Review, potential ask for changes.
|
||||
5. Merge. You're in!
|
||||
|
||||
Feel free to ask for help! You can create draft pull requests to gather
|
||||
some early feedback!
|
||||
|
||||
#### Run the tests
|
||||
|
||||
You can run tests for go-toml using Go's test tool: `go test ./...`.
|
||||
When creating a pull requests, all tests will be ran on Linux on a few Go
|
||||
versions (Travis CI), and on Windows using the latest Go version
|
||||
(AppVeyor).
|
||||
|
||||
#### Style
|
||||
|
||||
Try to look around and follow the same format and structure as the rest of
|
||||
the code. We enforce using `go fmt` on the whole code base.
|
||||
|
||||
---
|
||||
|
||||
### Maintainers-only
|
||||
|
||||
#### Merge pull request
|
||||
|
||||
Checklist:
|
||||
|
||||
* Passing CI.
|
||||
* Does not introduce backward-incompatible changes (unless discussed).
|
||||
* Has relevant doc changes.
|
||||
* Has relevant unit tests.
|
||||
|
||||
1. Merge using "squash and merge".
|
||||
2. Make sure to edit the commit message to keep all the useful information
|
||||
nice and clean.
|
||||
3. Make sure the commit title is clear and contains the PR number (#123).
|
||||
|
||||
#### New release
|
||||
|
||||
1. Go to [releases][releases]. Click on "X commits to master since this
|
||||
release".
|
||||
2. Make note of all the changes. Look for backward incompatible changes,
|
||||
new features, and bug fixes.
|
||||
3. Pick the new version using the above and semver.
|
||||
4. Create a [new release][new-release].
|
||||
5. Follow the same format as [1.1.0][release-110].
|
||||
|
||||
[issues-tracker]: https://github.com/pelletier/go-toml/issues
|
||||
[bug-report]: https://github.com/pelletier/go-toml/issues/new?template=bug_report.md
|
||||
[pkg.go.dev]: https://pkg.go.dev/github.com/pelletier/go-toml
|
||||
[readme]: ./README.md
|
||||
[fork]: https://help.github.com/articles/fork-a-repo
|
||||
[pull-request]: https://help.github.com/en/articles/creating-a-pull-request
|
||||
[releases]: https://github.com/pelletier/go-toml/releases
|
||||
[new-release]: https://github.com/pelletier/go-toml/releases/new
|
||||
[release-110]: https://github.com/pelletier/go-toml/releases/tag/v1.1.0
|
||||
11
vendor/github.com/pelletier/go-toml/Dockerfile
generated
vendored
Normal file
11
vendor/github.com/pelletier/go-toml/Dockerfile
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
FROM golang:1.12-alpine3.9 as builder
|
||||
WORKDIR /go/src/github.com/pelletier/go-toml
|
||||
COPY . .
|
||||
ENV CGO_ENABLED=0
|
||||
ENV GOOS=linux
|
||||
RUN go install ./...
|
||||
|
||||
FROM scratch
|
||||
COPY --from=builder /go/bin/tomll /usr/bin/tomll
|
||||
COPY --from=builder /go/bin/tomljson /usr/bin/tomljson
|
||||
COPY --from=builder /go/bin/jsontoml /usr/bin/jsontoml
|
||||
247
vendor/github.com/pelletier/go-toml/LICENSE
generated
vendored
Normal file
247
vendor/github.com/pelletier/go-toml/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,247 @@
|
||||
The bulk of github.com/pelletier/go-toml is distributed under the MIT license
|
||||
(see below), with the exception of localtime.go and localtime.test.go.
|
||||
Those two files have been copied over from Google's civil library at revision
|
||||
ed46f5086358513cf8c25f8e3f022cb838a49d66, and are distributed under the Apache
|
||||
2.0 license (see below).
|
||||
|
||||
|
||||
github.com/pelletier/go-toml:
|
||||
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 - 2021 Thomas Pelletier, Eric Anderton
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
localtime.go, localtime_test.go:
|
||||
|
||||
Originals:
|
||||
https://raw.githubusercontent.com/googleapis/google-cloud-go/ed46f5086358513cf8c25f8e3f022cb838a49d66/civil/civil.go
|
||||
https://raw.githubusercontent.com/googleapis/google-cloud-go/ed46f5086358513cf8c25f8e3f022cb838a49d66/civil/civil_test.go
|
||||
Changes:
|
||||
* Renamed files from civil* to localtime*.
|
||||
* Package changed from civil to toml.
|
||||
* 'Local' prefix added to all structs.
|
||||
License:
|
||||
https://raw.githubusercontent.com/googleapis/google-cloud-go/ed46f5086358513cf8c25f8e3f022cb838a49d66/LICENSE
|
||||
|
||||
|
||||
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.
|
||||
29
vendor/github.com/pelletier/go-toml/Makefile
generated
vendored
Normal file
29
vendor/github.com/pelletier/go-toml/Makefile
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
export CGO_ENABLED=0
|
||||
go := go
|
||||
go.goos ?= $(shell echo `go version`|cut -f4 -d ' '|cut -d '/' -f1)
|
||||
go.goarch ?= $(shell echo `go version`|cut -f4 -d ' '|cut -d '/' -f2)
|
||||
|
||||
out.tools := tomll tomljson jsontoml
|
||||
out.dist := $(out.tools:=_$(go.goos)_$(go.goarch).tar.xz)
|
||||
sources := $(wildcard **/*.go)
|
||||
|
||||
|
||||
.PHONY:
|
||||
tools: $(out.tools)
|
||||
|
||||
$(out.tools): $(sources)
|
||||
GOOS=$(go.goos) GOARCH=$(go.goarch) $(go) build ./cmd/$@
|
||||
|
||||
.PHONY:
|
||||
dist: $(out.dist)
|
||||
|
||||
$(out.dist):%_$(go.goos)_$(go.goarch).tar.xz: %
|
||||
if [ "$(go.goos)" = "windows" ]; then \
|
||||
tar -cJf $@ $^.exe; \
|
||||
else \
|
||||
tar -cJf $@ $^; \
|
||||
fi
|
||||
|
||||
.PHONY:
|
||||
clean:
|
||||
rm -rf $(out.tools) $(out.dist)
|
||||
5
vendor/github.com/pelletier/go-toml/PULL_REQUEST_TEMPLATE.md
generated
vendored
Normal file
5
vendor/github.com/pelletier/go-toml/PULL_REQUEST_TEMPLATE.md
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
**Issue:** add link to pelletier/go-toml issue here
|
||||
|
||||
Explanation of what this pull request does.
|
||||
|
||||
More detailed description of the decisions being made and the reasons why (if the patch is non-trivial).
|
||||
176
vendor/github.com/pelletier/go-toml/README.md
generated
vendored
Normal file
176
vendor/github.com/pelletier/go-toml/README.md
generated
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
# go-toml
|
||||
|
||||
Go library for the [TOML](https://toml.io/) format.
|
||||
|
||||
This library supports TOML version
|
||||
[v1.0.0-rc.3](https://toml.io/en/v1.0.0-rc.3)
|
||||
|
||||
[](https://pkg.go.dev/github.com/pelletier/go-toml)
|
||||
[](https://github.com/pelletier/go-toml/blob/master/LICENSE)
|
||||
[](https://dev.azure.com/pelletierthomas/go-toml-ci/_build/latest?definitionId=1&branchName=master)
|
||||
[](https://codecov.io/gh/pelletier/go-toml)
|
||||
[](https://goreportcard.com/report/github.com/pelletier/go-toml)
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fpelletier%2Fgo-toml?ref=badge_shield)
|
||||
|
||||
|
||||
## Development status
|
||||
|
||||
**ℹ️ Consider go-toml v2!**
|
||||
|
||||
The next version of go-toml is in [active development][v2-dev], and
|
||||
[nearing completion][v2-map].
|
||||
|
||||
Though technically in beta, v2 is already more tested, [fixes bugs][v1-bugs],
|
||||
and [much faster][v2-bench]. If you only need reading and writing TOML documents
|
||||
(majority of cases), those features are implemented and the API unlikely to
|
||||
change.
|
||||
|
||||
The remaining features (Document structure editing and tooling) will be added
|
||||
shortly. While pull-requests are welcome on v1, no active development is
|
||||
expected on it. When v2.0.0 is released, v1 will be deprecated.
|
||||
|
||||
👉 [go-toml v2][v2]
|
||||
|
||||
[v2]: https://github.com/pelletier/go-toml/tree/v2
|
||||
[v2-map]: https://github.com/pelletier/go-toml/discussions/506
|
||||
[v2-dev]: https://github.com/pelletier/go-toml/tree/v2
|
||||
[v1-bugs]: https://github.com/pelletier/go-toml/issues?q=is%3Aissue+is%3Aopen+label%3Av2-fixed
|
||||
[v2-bench]: https://github.com/pelletier/go-toml/tree/v2#benchmarks
|
||||
|
||||
## Features
|
||||
|
||||
Go-toml provides the following features for using data parsed from TOML documents:
|
||||
|
||||
* Load TOML documents from files and string data
|
||||
* Easily navigate TOML structure using Tree
|
||||
* Marshaling and unmarshaling to and from data structures
|
||||
* Line & column position data for all parsed elements
|
||||
* [Query support similar to JSON-Path](query/)
|
||||
* Syntax errors contain line and column numbers
|
||||
|
||||
## Import
|
||||
|
||||
```go
|
||||
import "github.com/pelletier/go-toml"
|
||||
```
|
||||
|
||||
## Usage example
|
||||
|
||||
Read a TOML document:
|
||||
|
||||
```go
|
||||
config, _ := toml.Load(`
|
||||
[postgres]
|
||||
user = "pelletier"
|
||||
password = "mypassword"`)
|
||||
// retrieve data directly
|
||||
user := config.Get("postgres.user").(string)
|
||||
|
||||
// or using an intermediate object
|
||||
postgresConfig := config.Get("postgres").(*toml.Tree)
|
||||
password := postgresConfig.Get("password").(string)
|
||||
```
|
||||
|
||||
Or use Unmarshal:
|
||||
|
||||
```go
|
||||
type Postgres struct {
|
||||
User string
|
||||
Password string
|
||||
}
|
||||
type Config struct {
|
||||
Postgres Postgres
|
||||
}
|
||||
|
||||
doc := []byte(`
|
||||
[Postgres]
|
||||
User = "pelletier"
|
||||
Password = "mypassword"`)
|
||||
|
||||
config := Config{}
|
||||
toml.Unmarshal(doc, &config)
|
||||
fmt.Println("user=", config.Postgres.User)
|
||||
```
|
||||
|
||||
Or use a query:
|
||||
|
||||
```go
|
||||
// use a query to gather elements without walking the tree
|
||||
q, _ := query.Compile("$..[user,password]")
|
||||
results := q.Execute(config)
|
||||
for ii, item := range results.Values() {
|
||||
fmt.Printf("Query result %d: %v\n", ii, item)
|
||||
}
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
The documentation and additional examples are available at
|
||||
[pkg.go.dev](https://pkg.go.dev/github.com/pelletier/go-toml).
|
||||
|
||||
## Tools
|
||||
|
||||
Go-toml provides three handy command line tools:
|
||||
|
||||
* `tomll`: Reads TOML files and lints them.
|
||||
|
||||
```
|
||||
go install github.com/pelletier/go-toml/cmd/tomll
|
||||
tomll --help
|
||||
```
|
||||
* `tomljson`: Reads a TOML file and outputs its JSON representation.
|
||||
|
||||
```
|
||||
go install github.com/pelletier/go-toml/cmd/tomljson
|
||||
tomljson --help
|
||||
```
|
||||
|
||||
* `jsontoml`: Reads a JSON file and outputs a TOML representation.
|
||||
|
||||
```
|
||||
go install github.com/pelletier/go-toml/cmd/jsontoml
|
||||
jsontoml --help
|
||||
```
|
||||
|
||||
### Docker image
|
||||
|
||||
Those tools are also available as a Docker image from
|
||||
[dockerhub](https://hub.docker.com/r/pelletier/go-toml). For example, to
|
||||
use `tomljson`:
|
||||
|
||||
```
|
||||
docker run -v $PWD:/workdir pelletier/go-toml tomljson /workdir/example.toml
|
||||
```
|
||||
|
||||
Only master (`latest`) and tagged versions are published to dockerhub. You
|
||||
can build your own image as usual:
|
||||
|
||||
```
|
||||
docker build -t go-toml .
|
||||
```
|
||||
|
||||
## Contribute
|
||||
|
||||
Feel free to report bugs and patches using GitHub's pull requests system on
|
||||
[pelletier/go-toml](https://github.com/pelletier/go-toml). Any feedback would be
|
||||
much appreciated!
|
||||
|
||||
### Run tests
|
||||
|
||||
`go test ./...`
|
||||
|
||||
### Fuzzing
|
||||
|
||||
The script `./fuzz.sh` is available to
|
||||
run [go-fuzz](https://github.com/dvyukov/go-fuzz) on go-toml.
|
||||
|
||||
## Versioning
|
||||
|
||||
Go-toml follows [Semantic Versioning](http://semver.org/). The supported version
|
||||
of [TOML](https://github.com/toml-lang/toml) is indicated at the beginning of
|
||||
this document. The last two major versions of Go are supported
|
||||
(see [Go Release Policy](https://golang.org/doc/devel/release.html#policy)).
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT) + Apache 2.0. Read [LICENSE](LICENSE).
|
||||
188
vendor/github.com/pelletier/go-toml/azure-pipelines.yml
generated
vendored
Normal file
188
vendor/github.com/pelletier/go-toml/azure-pipelines.yml
generated
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
trigger:
|
||||
- master
|
||||
|
||||
stages:
|
||||
- stage: run_checks
|
||||
displayName: "Check"
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- job: fmt
|
||||
displayName: "fmt"
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- task: GoTool@0
|
||||
displayName: "Install Go 1.16"
|
||||
inputs:
|
||||
version: "1.16"
|
||||
- task: Go@0
|
||||
displayName: "go fmt ./..."
|
||||
inputs:
|
||||
command: 'custom'
|
||||
customCommand: 'fmt'
|
||||
arguments: './...'
|
||||
- job: coverage
|
||||
displayName: "coverage"
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- task: GoTool@0
|
||||
displayName: "Install Go 1.16"
|
||||
inputs:
|
||||
version: "1.16"
|
||||
- task: Go@0
|
||||
displayName: "Generate coverage"
|
||||
inputs:
|
||||
command: 'test'
|
||||
arguments: "-race -coverprofile=coverage.txt -covermode=atomic"
|
||||
- task: Bash@3
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: 'bash <(curl -s https://codecov.io/bash) -t ${CODECOV_TOKEN}'
|
||||
env:
|
||||
CODECOV_TOKEN: $(CODECOV_TOKEN)
|
||||
- job: benchmark
|
||||
displayName: "benchmark"
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- task: GoTool@0
|
||||
displayName: "Install Go 1.16"
|
||||
inputs:
|
||||
version: "1.16"
|
||||
- script: echo "##vso[task.setvariable variable=PATH]${PATH}:/home/vsts/go/bin/"
|
||||
- task: Bash@3
|
||||
inputs:
|
||||
filePath: './benchmark.sh'
|
||||
arguments: "master $(Build.Repository.Uri)"
|
||||
|
||||
- job: go_unit_tests
|
||||
displayName: "unit tests"
|
||||
strategy:
|
||||
matrix:
|
||||
linux 1.16:
|
||||
goVersion: '1.16'
|
||||
imageName: 'ubuntu-latest'
|
||||
mac 1.16:
|
||||
goVersion: '1.16'
|
||||
imageName: 'macOS-latest'
|
||||
windows 1.16:
|
||||
goVersion: '1.16'
|
||||
imageName: 'windows-latest'
|
||||
linux 1.15:
|
||||
goVersion: '1.15'
|
||||
imageName: 'ubuntu-latest'
|
||||
mac 1.15:
|
||||
goVersion: '1.15'
|
||||
imageName: 'macOS-latest'
|
||||
windows 1.15:
|
||||
goVersion: '1.15'
|
||||
imageName: 'windows-latest'
|
||||
pool:
|
||||
vmImage: $(imageName)
|
||||
steps:
|
||||
- task: GoTool@0
|
||||
displayName: "Install Go $(goVersion)"
|
||||
inputs:
|
||||
version: $(goVersion)
|
||||
- task: Go@0
|
||||
displayName: "go test ./..."
|
||||
inputs:
|
||||
command: 'test'
|
||||
arguments: './...'
|
||||
- stage: build_binaries
|
||||
displayName: "Build binaries"
|
||||
dependsOn: run_checks
|
||||
jobs:
|
||||
- job: build_binary
|
||||
displayName: "Build binary"
|
||||
strategy:
|
||||
matrix:
|
||||
linux_amd64:
|
||||
GOOS: linux
|
||||
GOARCH: amd64
|
||||
darwin_amd64:
|
||||
GOOS: darwin
|
||||
GOARCH: amd64
|
||||
windows_amd64:
|
||||
GOOS: windows
|
||||
GOARCH: amd64
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- task: GoTool@0
|
||||
displayName: "Install Go"
|
||||
inputs:
|
||||
version: 1.16
|
||||
- task: Bash@3
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: "make dist"
|
||||
env:
|
||||
go.goos: $(GOOS)
|
||||
go.goarch: $(GOARCH)
|
||||
- task: CopyFiles@2
|
||||
inputs:
|
||||
sourceFolder: '$(Build.SourcesDirectory)'
|
||||
contents: '*.tar.xz'
|
||||
TargetFolder: '$(Build.ArtifactStagingDirectory)'
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathtoPublish: '$(Build.ArtifactStagingDirectory)'
|
||||
artifactName: binaries
|
||||
- stage: build_binaries_manifest
|
||||
displayName: "Build binaries manifest"
|
||||
dependsOn: build_binaries
|
||||
jobs:
|
||||
- job: build_manifest
|
||||
displayName: "Build binaries manifest"
|
||||
steps:
|
||||
- task: DownloadBuildArtifacts@0
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
downloadType: 'single'
|
||||
artifactName: 'binaries'
|
||||
downloadPath: '$(Build.SourcesDirectory)'
|
||||
- task: Bash@3
|
||||
inputs:
|
||||
targetType: inline
|
||||
script: "cd binaries && sha256sum --binary *.tar.xz | tee $(Build.ArtifactStagingDirectory)/sha256sums.txt"
|
||||
- task: PublishBuildArtifacts@1
|
||||
inputs:
|
||||
pathtoPublish: '$(Build.ArtifactStagingDirectory)'
|
||||
artifactName: manifest
|
||||
|
||||
- stage: build_docker_image
|
||||
displayName: "Build Docker image"
|
||||
dependsOn: run_checks
|
||||
jobs:
|
||||
- job: build
|
||||
displayName: "Build"
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- task: Docker@2
|
||||
inputs:
|
||||
command: 'build'
|
||||
Dockerfile: 'Dockerfile'
|
||||
buildContext: '.'
|
||||
addPipelineData: false
|
||||
|
||||
- stage: publish_docker_image
|
||||
displayName: "Publish Docker image"
|
||||
dependsOn: build_docker_image
|
||||
condition: and(succeeded(), eq(variables['Build.SourceBranchName'], 'master'))
|
||||
jobs:
|
||||
- job: publish
|
||||
displayName: "Publish"
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
steps:
|
||||
- task: Docker@2
|
||||
inputs:
|
||||
containerRegistry: 'DockerHub'
|
||||
repository: 'pelletier/go-toml'
|
||||
command: 'buildAndPush'
|
||||
Dockerfile: 'Dockerfile'
|
||||
buildContext: '.'
|
||||
tags: 'latest'
|
||||
35
vendor/github.com/pelletier/go-toml/benchmark.sh
generated
vendored
Normal file
35
vendor/github.com/pelletier/go-toml/benchmark.sh
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -ex
|
||||
|
||||
reference_ref=${1:-master}
|
||||
reference_git=${2:-.}
|
||||
|
||||
if ! `hash benchstat 2>/dev/null`; then
|
||||
echo "Installing benchstat"
|
||||
go get golang.org/x/perf/cmd/benchstat
|
||||
fi
|
||||
|
||||
tempdir=`mktemp -d /tmp/go-toml-benchmark-XXXXXX`
|
||||
ref_tempdir="${tempdir}/ref"
|
||||
ref_benchmark="${ref_tempdir}/benchmark-`echo -n ${reference_ref}|tr -s '/' '-'`.txt"
|
||||
local_benchmark="`pwd`/benchmark-local.txt"
|
||||
|
||||
echo "=== ${reference_ref} (${ref_tempdir})"
|
||||
git clone ${reference_git} ${ref_tempdir} >/dev/null 2>/dev/null
|
||||
pushd ${ref_tempdir} >/dev/null
|
||||
git checkout ${reference_ref} >/dev/null 2>/dev/null
|
||||
go test -bench=. -benchmem | tee ${ref_benchmark}
|
||||
cd benchmark
|
||||
go test -bench=. -benchmem | tee -a ${ref_benchmark}
|
||||
popd >/dev/null
|
||||
|
||||
echo ""
|
||||
echo "=== local"
|
||||
go test -bench=. -benchmem | tee ${local_benchmark}
|
||||
cd benchmark
|
||||
go test -bench=. -benchmem | tee -a ${local_benchmark}
|
||||
|
||||
echo ""
|
||||
echo "=== diff"
|
||||
benchstat -delta-test=none ${ref_benchmark} ${local_benchmark}
|
||||
23
vendor/github.com/pelletier/go-toml/doc.go
generated
vendored
Normal file
23
vendor/github.com/pelletier/go-toml/doc.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Package toml is a TOML parser and manipulation library.
|
||||
//
|
||||
// This version supports the specification as described in
|
||||
// https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.5.0.md
|
||||
//
|
||||
// Marshaling
|
||||
//
|
||||
// Go-toml can marshal and unmarshal TOML documents from and to data
|
||||
// structures.
|
||||
//
|
||||
// TOML document as a tree
|
||||
//
|
||||
// Go-toml can operate on a TOML document as a tree. Use one of the Load*
|
||||
// functions to parse TOML data and obtain a Tree instance, then one of its
|
||||
// methods to manipulate the tree.
|
||||
//
|
||||
// JSONPath-like queries
|
||||
//
|
||||
// The package github.com/pelletier/go-toml/query implements a system
|
||||
// similar to JSONPath to quickly retrieve elements of a TOML document using a
|
||||
// single expression. See the package documentation for more information.
|
||||
//
|
||||
package toml
|
||||
30
vendor/github.com/pelletier/go-toml/example-crlf.toml
generated
vendored
Normal file
30
vendor/github.com/pelletier/go-toml/example-crlf.toml
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# This is a TOML document. Boom.
|
||||
|
||||
title = "TOML Example"
|
||||
|
||||
[owner]
|
||||
name = "Tom Preston-Werner"
|
||||
organization = "GitHub"
|
||||
bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
|
||||
dob = 1979-05-27T07:32:00Z # First class dates? Why not?
|
||||
|
||||
[database]
|
||||
server = "192.168.1.1"
|
||||
ports = [ 8001, 8001, 8002 ]
|
||||
connection_max = 5000
|
||||
enabled = true
|
||||
|
||||
[servers]
|
||||
|
||||
# You can indent as you please. Tabs or spaces. TOML don't care.
|
||||
[servers.alpha]
|
||||
ip = "10.0.0.1"
|
||||
dc = "eqdc10"
|
||||
|
||||
[servers.beta]
|
||||
ip = "10.0.0.2"
|
||||
dc = "eqdc10"
|
||||
|
||||
[clients]
|
||||
data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it
|
||||
score = 4e-08 # to make sure leading zeroes in exponent parts of floats are supported
|
||||
30
vendor/github.com/pelletier/go-toml/example.toml
generated
vendored
Normal file
30
vendor/github.com/pelletier/go-toml/example.toml
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# This is a TOML document. Boom.
|
||||
|
||||
title = "TOML Example"
|
||||
|
||||
[owner]
|
||||
name = "Tom Preston-Werner"
|
||||
organization = "GitHub"
|
||||
bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
|
||||
dob = 1979-05-27T07:32:00Z # First class dates? Why not?
|
||||
|
||||
[database]
|
||||
server = "192.168.1.1"
|
||||
ports = [ 8001, 8001, 8002 ]
|
||||
connection_max = 5000
|
||||
enabled = true
|
||||
|
||||
[servers]
|
||||
|
||||
# You can indent as you please. Tabs or spaces. TOML don't care.
|
||||
[servers.alpha]
|
||||
ip = "10.0.0.1"
|
||||
dc = "eqdc10"
|
||||
|
||||
[servers.beta]
|
||||
ip = "10.0.0.2"
|
||||
dc = "eqdc10"
|
||||
|
||||
[clients]
|
||||
data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it
|
||||
score = 4e-08 # to make sure leading zeroes in exponent parts of floats are supported
|
||||
31
vendor/github.com/pelletier/go-toml/fuzz.go
generated
vendored
Normal file
31
vendor/github.com/pelletier/go-toml/fuzz.go
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
// +build gofuzz
|
||||
|
||||
package toml
|
||||
|
||||
func Fuzz(data []byte) int {
|
||||
tree, err := LoadBytes(data)
|
||||
if err != nil {
|
||||
if tree != nil {
|
||||
panic("tree must be nil if there is an error")
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
str, err := tree.ToTomlString()
|
||||
if err != nil {
|
||||
if str != "" {
|
||||
panic(`str must be "" if there is an error`)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
|
||||
tree, err = Load(str)
|
||||
if err != nil {
|
||||
if tree != nil {
|
||||
panic("tree must be nil if there is an error")
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
||||
15
vendor/github.com/pelletier/go-toml/fuzz.sh
generated
vendored
Normal file
15
vendor/github.com/pelletier/go-toml/fuzz.sh
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
#! /bin/sh
|
||||
set -eu
|
||||
|
||||
go get github.com/dvyukov/go-fuzz/go-fuzz
|
||||
go get github.com/dvyukov/go-fuzz/go-fuzz-build
|
||||
|
||||
if [ ! -e toml-fuzz.zip ]; then
|
||||
go-fuzz-build github.com/pelletier/go-toml
|
||||
fi
|
||||
|
||||
rm -fr fuzz
|
||||
mkdir -p fuzz/corpus
|
||||
cp *.toml fuzz/corpus
|
||||
|
||||
go-fuzz -bin=toml-fuzz.zip -workdir=fuzz
|
||||
3
vendor/github.com/pelletier/go-toml/go.mod
generated
vendored
Normal file
3
vendor/github.com/pelletier/go-toml/go.mod
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
module github.com/pelletier/go-toml
|
||||
|
||||
go 1.12
|
||||
112
vendor/github.com/pelletier/go-toml/keysparsing.go
generated
vendored
Normal file
112
vendor/github.com/pelletier/go-toml/keysparsing.go
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
// Parsing keys handling both bare and quoted keys.
|
||||
|
||||
package toml
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Convert the bare key group string to an array.
|
||||
// The input supports double quotation and single quotation,
|
||||
// but escape sequences are not supported. Lexers must unescape them beforehand.
|
||||
func parseKey(key string) ([]string, error) {
|
||||
runes := []rune(key)
|
||||
var groups []string
|
||||
|
||||
if len(key) == 0 {
|
||||
return nil, errors.New("empty key")
|
||||
}
|
||||
|
||||
idx := 0
|
||||
for idx < len(runes) {
|
||||
for ; idx < len(runes) && isSpace(runes[idx]); idx++ {
|
||||
// skip leading whitespace
|
||||
}
|
||||
if idx >= len(runes) {
|
||||
break
|
||||
}
|
||||
r := runes[idx]
|
||||
if isValidBareChar(r) {
|
||||
// parse bare key
|
||||
startIdx := idx
|
||||
endIdx := -1
|
||||
idx++
|
||||
for idx < len(runes) {
|
||||
r = runes[idx]
|
||||
if isValidBareChar(r) {
|
||||
idx++
|
||||
} else if r == '.' {
|
||||
endIdx = idx
|
||||
break
|
||||
} else if isSpace(r) {
|
||||
endIdx = idx
|
||||
for ; idx < len(runes) && isSpace(runes[idx]); idx++ {
|
||||
// skip trailing whitespace
|
||||
}
|
||||
if idx < len(runes) && runes[idx] != '.' {
|
||||
return nil, fmt.Errorf("invalid key character after whitespace: %c", runes[idx])
|
||||
}
|
||||
break
|
||||
} else {
|
||||
return nil, fmt.Errorf("invalid bare key character: %c", r)
|
||||
}
|
||||
}
|
||||
if endIdx == -1 {
|
||||
endIdx = idx
|
||||
}
|
||||
groups = append(groups, string(runes[startIdx:endIdx]))
|
||||
} else if r == '\'' {
|
||||
// parse single quoted key
|
||||
idx++
|
||||
startIdx := idx
|
||||
for {
|
||||
if idx >= len(runes) {
|
||||
return nil, fmt.Errorf("unclosed single-quoted key")
|
||||
}
|
||||
r = runes[idx]
|
||||
if r == '\'' {
|
||||
groups = append(groups, string(runes[startIdx:idx]))
|
||||
idx++
|
||||
break
|
||||
}
|
||||
idx++
|
||||
}
|
||||
} else if r == '"' {
|
||||
// parse double quoted key
|
||||
idx++
|
||||
startIdx := idx
|
||||
for {
|
||||
if idx >= len(runes) {
|
||||
return nil, fmt.Errorf("unclosed double-quoted key")
|
||||
}
|
||||
r = runes[idx]
|
||||
if r == '"' {
|
||||
groups = append(groups, string(runes[startIdx:idx]))
|
||||
idx++
|
||||
break
|
||||
}
|
||||
idx++
|
||||
}
|
||||
} else if r == '.' {
|
||||
idx++
|
||||
if idx >= len(runes) {
|
||||
return nil, fmt.Errorf("unexpected end of key")
|
||||
}
|
||||
r = runes[idx]
|
||||
if !isValidBareChar(r) && r != '\'' && r != '"' && r != ' ' {
|
||||
return nil, fmt.Errorf("expecting key part after dot")
|
||||
}
|
||||
} else {
|
||||
return nil, fmt.Errorf("invalid key character: %c", r)
|
||||
}
|
||||
}
|
||||
if len(groups) == 0 {
|
||||
return nil, fmt.Errorf("empty key")
|
||||
}
|
||||
return groups, nil
|
||||
}
|
||||
|
||||
func isValidBareChar(r rune) bool {
|
||||
return isAlphanumeric(r) || r == '-' || isDigit(r)
|
||||
}
|
||||
1031
vendor/github.com/pelletier/go-toml/lexer.go
generated
vendored
Normal file
1031
vendor/github.com/pelletier/go-toml/lexer.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
287
vendor/github.com/pelletier/go-toml/localtime.go
generated
vendored
Normal file
287
vendor/github.com/pelletier/go-toml/localtime.go
generated
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
// Implementation of TOML's local date/time.
|
||||
//
|
||||
// Copied over from Google's civil to avoid pulling all the Google dependencies.
|
||||
// Originals:
|
||||
// https://raw.githubusercontent.com/googleapis/google-cloud-go/ed46f5086358513cf8c25f8e3f022cb838a49d66/civil/civil.go
|
||||
// Changes:
|
||||
// * Renamed files from civil* to localtime*.
|
||||
// * Package changed from civil to toml.
|
||||
// * 'Local' prefix added to all structs.
|
||||
//
|
||||
// Copyright 2016 Google LLC
|
||||
//
|
||||
// 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 civil implements types for civil time, a time-zone-independent
|
||||
// representation of time that follows the rules of the proleptic
|
||||
// Gregorian calendar with exactly 24-hour days, 60-minute hours, and 60-second
|
||||
// minutes.
|
||||
//
|
||||
// Because they lack location information, these types do not represent unique
|
||||
// moments or intervals of time. Use time.Time for that purpose.
|
||||
package toml
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// A LocalDate represents a date (year, month, day).
|
||||
//
|
||||
// This type does not include location information, and therefore does not
|
||||
// describe a unique 24-hour timespan.
|
||||
type LocalDate struct {
|
||||
Year int // Year (e.g., 2014).
|
||||
Month time.Month // Month of the year (January = 1, ...).
|
||||
Day int // Day of the month, starting at 1.
|
||||
}
|
||||
|
||||
// LocalDateOf returns the LocalDate in which a time occurs in that time's location.
|
||||
func LocalDateOf(t time.Time) LocalDate {
|
||||
var d LocalDate
|
||||
d.Year, d.Month, d.Day = t.Date()
|
||||
return d
|
||||
}
|
||||
|
||||
// ParseLocalDate parses a string in RFC3339 full-date format and returns the date value it represents.
|
||||
func ParseLocalDate(s string) (LocalDate, error) {
|
||||
t, err := time.Parse("2006-01-02", s)
|
||||
if err != nil {
|
||||
return LocalDate{}, err
|
||||
}
|
||||
return LocalDateOf(t), nil
|
||||
}
|
||||
|
||||
// String returns the date in RFC3339 full-date format.
|
||||
func (d LocalDate) String() string {
|
||||
return fmt.Sprintf("%04d-%02d-%02d", d.Year, d.Month, d.Day)
|
||||
}
|
||||
|
||||
// IsValid reports whether the date is valid.
|
||||
func (d LocalDate) IsValid() bool {
|
||||
return LocalDateOf(d.In(time.UTC)) == d
|
||||
}
|
||||
|
||||
// In returns the time corresponding to time 00:00:00 of the date in the location.
|
||||
//
|
||||
// In is always consistent with time.LocalDate, even when time.LocalDate returns a time
|
||||
// on a different day. For example, if loc is America/Indiana/Vincennes, then both
|
||||
// time.LocalDate(1955, time.May, 1, 0, 0, 0, 0, loc)
|
||||
// and
|
||||
// civil.LocalDate{Year: 1955, Month: time.May, Day: 1}.In(loc)
|
||||
// return 23:00:00 on April 30, 1955.
|
||||
//
|
||||
// In panics if loc is nil.
|
||||
func (d LocalDate) In(loc *time.Location) time.Time {
|
||||
return time.Date(d.Year, d.Month, d.Day, 0, 0, 0, 0, loc)
|
||||
}
|
||||
|
||||
// AddDays returns the date that is n days in the future.
|
||||
// n can also be negative to go into the past.
|
||||
func (d LocalDate) AddDays(n int) LocalDate {
|
||||
return LocalDateOf(d.In(time.UTC).AddDate(0, 0, n))
|
||||
}
|
||||
|
||||
// DaysSince returns the signed number of days between the date and s, not including the end day.
|
||||
// This is the inverse operation to AddDays.
|
||||
func (d LocalDate) DaysSince(s LocalDate) (days int) {
|
||||
// We convert to Unix time so we do not have to worry about leap seconds:
|
||||
// Unix time increases by exactly 86400 seconds per day.
|
||||
deltaUnix := d.In(time.UTC).Unix() - s.In(time.UTC).Unix()
|
||||
return int(deltaUnix / 86400)
|
||||
}
|
||||
|
||||
// Before reports whether d1 occurs before d2.
|
||||
func (d1 LocalDate) Before(d2 LocalDate) bool {
|
||||
if d1.Year != d2.Year {
|
||||
return d1.Year < d2.Year
|
||||
}
|
||||
if d1.Month != d2.Month {
|
||||
return d1.Month < d2.Month
|
||||
}
|
||||
return d1.Day < d2.Day
|
||||
}
|
||||
|
||||
// After reports whether d1 occurs after d2.
|
||||
func (d1 LocalDate) After(d2 LocalDate) bool {
|
||||
return d2.Before(d1)
|
||||
}
|
||||
|
||||
// MarshalText implements the encoding.TextMarshaler interface.
|
||||
// The output is the result of d.String().
|
||||
func (d LocalDate) MarshalText() ([]byte, error) {
|
||||
return []byte(d.String()), nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
||||
// The date is expected to be a string in a format accepted by ParseLocalDate.
|
||||
func (d *LocalDate) UnmarshalText(data []byte) error {
|
||||
var err error
|
||||
*d, err = ParseLocalDate(string(data))
|
||||
return err
|
||||
}
|
||||
|
||||
// A LocalTime represents a time with nanosecond precision.
|
||||
//
|
||||
// This type does not include location information, and therefore does not
|
||||
// describe a unique moment in time.
|
||||
//
|
||||
// This type exists to represent the TIME type in storage-based APIs like BigQuery.
|
||||
// Most operations on Times are unlikely to be meaningful. Prefer the LocalDateTime type.
|
||||
type LocalTime struct {
|
||||
Hour int // The hour of the day in 24-hour format; range [0-23]
|
||||
Minute int // The minute of the hour; range [0-59]
|
||||
Second int // The second of the minute; range [0-59]
|
||||
Nanosecond int // The nanosecond of the second; range [0-999999999]
|
||||
}
|
||||
|
||||
// LocalTimeOf returns the LocalTime representing the time of day in which a time occurs
|
||||
// in that time's location. It ignores the date.
|
||||
func LocalTimeOf(t time.Time) LocalTime {
|
||||
var tm LocalTime
|
||||
tm.Hour, tm.Minute, tm.Second = t.Clock()
|
||||
tm.Nanosecond = t.Nanosecond()
|
||||
return tm
|
||||
}
|
||||
|
||||
// ParseLocalTime parses a string and returns the time value it represents.
|
||||
// ParseLocalTime accepts an extended form of the RFC3339 partial-time format. After
|
||||
// the HH:MM:SS part of the string, an optional fractional part may appear,
|
||||
// consisting of a decimal point followed by one to nine decimal digits.
|
||||
// (RFC3339 admits only one digit after the decimal point).
|
||||
func ParseLocalTime(s string) (LocalTime, error) {
|
||||
t, err := time.Parse("15:04:05.999999999", s)
|
||||
if err != nil {
|
||||
return LocalTime{}, err
|
||||
}
|
||||
return LocalTimeOf(t), nil
|
||||
}
|
||||
|
||||
// String returns the date in the format described in ParseLocalTime. If Nanoseconds
|
||||
// is zero, no fractional part will be generated. Otherwise, the result will
|
||||
// end with a fractional part consisting of a decimal point and nine digits.
|
||||
func (t LocalTime) String() string {
|
||||
s := fmt.Sprintf("%02d:%02d:%02d", t.Hour, t.Minute, t.Second)
|
||||
if t.Nanosecond == 0 {
|
||||
return s
|
||||
}
|
||||
return s + fmt.Sprintf(".%09d", t.Nanosecond)
|
||||
}
|
||||
|
||||
// IsValid reports whether the time is valid.
|
||||
func (t LocalTime) IsValid() bool {
|
||||
// Construct a non-zero time.
|
||||
tm := time.Date(2, 2, 2, t.Hour, t.Minute, t.Second, t.Nanosecond, time.UTC)
|
||||
return LocalTimeOf(tm) == t
|
||||
}
|
||||
|
||||
// MarshalText implements the encoding.TextMarshaler interface.
|
||||
// The output is the result of t.String().
|
||||
func (t LocalTime) MarshalText() ([]byte, error) {
|
||||
return []byte(t.String()), nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
||||
// The time is expected to be a string in a format accepted by ParseLocalTime.
|
||||
func (t *LocalTime) UnmarshalText(data []byte) error {
|
||||
var err error
|
||||
*t, err = ParseLocalTime(string(data))
|
||||
return err
|
||||
}
|
||||
|
||||
// A LocalDateTime represents a date and time.
|
||||
//
|
||||
// This type does not include location information, and therefore does not
|
||||
// describe a unique moment in time.
|
||||
type LocalDateTime struct {
|
||||
Date LocalDate
|
||||
Time LocalTime
|
||||
}
|
||||
|
||||
// Note: We deliberately do not embed LocalDate into LocalDateTime, to avoid promoting AddDays and Sub.
|
||||
|
||||
// LocalDateTimeOf returns the LocalDateTime in which a time occurs in that time's location.
|
||||
func LocalDateTimeOf(t time.Time) LocalDateTime {
|
||||
return LocalDateTime{
|
||||
Date: LocalDateOf(t),
|
||||
Time: LocalTimeOf(t),
|
||||
}
|
||||
}
|
||||
|
||||
// ParseLocalDateTime parses a string and returns the LocalDateTime it represents.
|
||||
// ParseLocalDateTime accepts a variant of the RFC3339 date-time format that omits
|
||||
// the time offset but includes an optional fractional time, as described in
|
||||
// ParseLocalTime. Informally, the accepted format is
|
||||
// YYYY-MM-DDTHH:MM:SS[.FFFFFFFFF]
|
||||
// where the 'T' may be a lower-case 't'.
|
||||
func ParseLocalDateTime(s string) (LocalDateTime, error) {
|
||||
t, err := time.Parse("2006-01-02T15:04:05.999999999", s)
|
||||
if err != nil {
|
||||
t, err = time.Parse("2006-01-02t15:04:05.999999999", s)
|
||||
if err != nil {
|
||||
return LocalDateTime{}, err
|
||||
}
|
||||
}
|
||||
return LocalDateTimeOf(t), nil
|
||||
}
|
||||
|
||||
// String returns the date in the format described in ParseLocalDate.
|
||||
func (dt LocalDateTime) String() string {
|
||||
return dt.Date.String() + "T" + dt.Time.String()
|
||||
}
|
||||
|
||||
// IsValid reports whether the datetime is valid.
|
||||
func (dt LocalDateTime) IsValid() bool {
|
||||
return dt.Date.IsValid() && dt.Time.IsValid()
|
||||
}
|
||||
|
||||
// In returns the time corresponding to the LocalDateTime in the given location.
|
||||
//
|
||||
// If the time is missing or ambigous at the location, In returns the same
|
||||
// result as time.LocalDate. For example, if loc is America/Indiana/Vincennes, then
|
||||
// both
|
||||
// time.LocalDate(1955, time.May, 1, 0, 30, 0, 0, loc)
|
||||
// and
|
||||
// civil.LocalDateTime{
|
||||
// civil.LocalDate{Year: 1955, Month: time.May, Day: 1}},
|
||||
// civil.LocalTime{Minute: 30}}.In(loc)
|
||||
// return 23:30:00 on April 30, 1955.
|
||||
//
|
||||
// In panics if loc is nil.
|
||||
func (dt LocalDateTime) In(loc *time.Location) time.Time {
|
||||
return time.Date(dt.Date.Year, dt.Date.Month, dt.Date.Day, dt.Time.Hour, dt.Time.Minute, dt.Time.Second, dt.Time.Nanosecond, loc)
|
||||
}
|
||||
|
||||
// Before reports whether dt1 occurs before dt2.
|
||||
func (dt1 LocalDateTime) Before(dt2 LocalDateTime) bool {
|
||||
return dt1.In(time.UTC).Before(dt2.In(time.UTC))
|
||||
}
|
||||
|
||||
// After reports whether dt1 occurs after dt2.
|
||||
func (dt1 LocalDateTime) After(dt2 LocalDateTime) bool {
|
||||
return dt2.Before(dt1)
|
||||
}
|
||||
|
||||
// MarshalText implements the encoding.TextMarshaler interface.
|
||||
// The output is the result of dt.String().
|
||||
func (dt LocalDateTime) MarshalText() ([]byte, error) {
|
||||
return []byte(dt.String()), nil
|
||||
}
|
||||
|
||||
// UnmarshalText implements the encoding.TextUnmarshaler interface.
|
||||
// The datetime is expected to be a string in a format accepted by ParseLocalDateTime
|
||||
func (dt *LocalDateTime) UnmarshalText(data []byte) error {
|
||||
var err error
|
||||
*dt, err = ParseLocalDateTime(string(data))
|
||||
return err
|
||||
}
|
||||
1308
vendor/github.com/pelletier/go-toml/marshal.go
generated
vendored
Normal file
1308
vendor/github.com/pelletier/go-toml/marshal.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
39
vendor/github.com/pelletier/go-toml/marshal_OrderPreserve_test.toml
generated
vendored
Normal file
39
vendor/github.com/pelletier/go-toml/marshal_OrderPreserve_test.toml
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
title = "TOML Marshal Testing"
|
||||
|
||||
[basic_lists]
|
||||
floats = [12.3,45.6,78.9]
|
||||
bools = [true,false,true]
|
||||
dates = [1979-05-27T07:32:00Z,1980-05-27T07:32:00Z]
|
||||
ints = [8001,8001,8002]
|
||||
uints = [5002,5003]
|
||||
strings = ["One","Two","Three"]
|
||||
|
||||
[[subdocptrs]]
|
||||
name = "Second"
|
||||
|
||||
[basic_map]
|
||||
one = "one"
|
||||
two = "two"
|
||||
|
||||
[subdoc]
|
||||
|
||||
[subdoc.second]
|
||||
name = "Second"
|
||||
|
||||
[subdoc.first]
|
||||
name = "First"
|
||||
|
||||
[basic]
|
||||
uint = 5001
|
||||
bool = true
|
||||
float = 123.4
|
||||
float64 = 123.456782132399
|
||||
int = 5000
|
||||
string = "Bite me"
|
||||
date = 1979-05-27T07:32:00Z
|
||||
|
||||
[[subdoclist]]
|
||||
name = "List.First"
|
||||
|
||||
[[subdoclist]]
|
||||
name = "List.Second"
|
||||
39
vendor/github.com/pelletier/go-toml/marshal_test.toml
generated
vendored
Normal file
39
vendor/github.com/pelletier/go-toml/marshal_test.toml
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
title = "TOML Marshal Testing"
|
||||
|
||||
[basic]
|
||||
bool = true
|
||||
date = 1979-05-27T07:32:00Z
|
||||
float = 123.4
|
||||
float64 = 123.456782132399
|
||||
int = 5000
|
||||
string = "Bite me"
|
||||
uint = 5001
|
||||
|
||||
[basic_lists]
|
||||
bools = [true,false,true]
|
||||
dates = [1979-05-27T07:32:00Z,1980-05-27T07:32:00Z]
|
||||
floats = [12.3,45.6,78.9]
|
||||
ints = [8001,8001,8002]
|
||||
strings = ["One","Two","Three"]
|
||||
uints = [5002,5003]
|
||||
|
||||
[basic_map]
|
||||
one = "one"
|
||||
two = "two"
|
||||
|
||||
[subdoc]
|
||||
|
||||
[subdoc.first]
|
||||
name = "First"
|
||||
|
||||
[subdoc.second]
|
||||
name = "Second"
|
||||
|
||||
[[subdoclist]]
|
||||
name = "List.First"
|
||||
|
||||
[[subdoclist]]
|
||||
name = "List.Second"
|
||||
|
||||
[[subdocptrs]]
|
||||
name = "Second"
|
||||
508
vendor/github.com/pelletier/go-toml/parser.go
generated
vendored
Normal file
508
vendor/github.com/pelletier/go-toml/parser.go
generated
vendored
Normal file
@@ -0,0 +1,508 @@
|
||||
// TOML Parser.
|
||||
|
||||
package toml
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type tomlParser struct {
|
||||
flowIdx int
|
||||
flow []token
|
||||
tree *Tree
|
||||
currentTable []string
|
||||
seenTableKeys []string
|
||||
}
|
||||
|
||||
type tomlParserStateFn func() tomlParserStateFn
|
||||
|
||||
// Formats and panics an error message based on a token
|
||||
func (p *tomlParser) raiseError(tok *token, msg string, args ...interface{}) {
|
||||
panic(tok.Position.String() + ": " + fmt.Sprintf(msg, args...))
|
||||
}
|
||||
|
||||
func (p *tomlParser) run() {
|
||||
for state := p.parseStart; state != nil; {
|
||||
state = state()
|
||||
}
|
||||
}
|
||||
|
||||
func (p *tomlParser) peek() *token {
|
||||
if p.flowIdx >= len(p.flow) {
|
||||
return nil
|
||||
}
|
||||
return &p.flow[p.flowIdx]
|
||||
}
|
||||
|
||||
func (p *tomlParser) assume(typ tokenType) {
|
||||
tok := p.getToken()
|
||||
if tok == nil {
|
||||
p.raiseError(tok, "was expecting token %s, but token stream is empty", tok)
|
||||
}
|
||||
if tok.typ != typ {
|
||||
p.raiseError(tok, "was expecting token %s, but got %s instead", typ, tok)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *tomlParser) getToken() *token {
|
||||
tok := p.peek()
|
||||
if tok == nil {
|
||||
return nil
|
||||
}
|
||||
p.flowIdx++
|
||||
return tok
|
||||
}
|
||||
|
||||
func (p *tomlParser) parseStart() tomlParserStateFn {
|
||||
tok := p.peek()
|
||||
|
||||
// end of stream, parsing is finished
|
||||
if tok == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch tok.typ {
|
||||
case tokenDoubleLeftBracket:
|
||||
return p.parseGroupArray
|
||||
case tokenLeftBracket:
|
||||
return p.parseGroup
|
||||
case tokenKey:
|
||||
return p.parseAssign
|
||||
case tokenEOF:
|
||||
return nil
|
||||
case tokenError:
|
||||
p.raiseError(tok, "parsing error: %s", tok.String())
|
||||
default:
|
||||
p.raiseError(tok, "unexpected token %s", tok.typ)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *tomlParser) parseGroupArray() tomlParserStateFn {
|
||||
startToken := p.getToken() // discard the [[
|
||||
key := p.getToken()
|
||||
if key.typ != tokenKeyGroupArray {
|
||||
p.raiseError(key, "unexpected token %s, was expecting a table array key", key)
|
||||
}
|
||||
|
||||
// get or create table array element at the indicated part in the path
|
||||
keys, err := parseKey(key.val)
|
||||
if err != nil {
|
||||
p.raiseError(key, "invalid table array key: %s", err)
|
||||
}
|
||||
p.tree.createSubTree(keys[:len(keys)-1], startToken.Position) // create parent entries
|
||||
destTree := p.tree.GetPath(keys)
|
||||
var array []*Tree
|
||||
if destTree == nil {
|
||||
array = make([]*Tree, 0)
|
||||
} else if target, ok := destTree.([]*Tree); ok && target != nil {
|
||||
array = destTree.([]*Tree)
|
||||
} else {
|
||||
p.raiseError(key, "key %s is already assigned and not of type table array", key)
|
||||
}
|
||||
p.currentTable = keys
|
||||
|
||||
// add a new tree to the end of the table array
|
||||
newTree := newTree()
|
||||
newTree.position = startToken.Position
|
||||
array = append(array, newTree)
|
||||
p.tree.SetPath(p.currentTable, array)
|
||||
|
||||
// remove all keys that were children of this table array
|
||||
prefix := key.val + "."
|
||||
found := false
|
||||
for ii := 0; ii < len(p.seenTableKeys); {
|
||||
tableKey := p.seenTableKeys[ii]
|
||||
if strings.HasPrefix(tableKey, prefix) {
|
||||
p.seenTableKeys = append(p.seenTableKeys[:ii], p.seenTableKeys[ii+1:]...)
|
||||
} else {
|
||||
found = (tableKey == key.val)
|
||||
ii++
|
||||
}
|
||||
}
|
||||
|
||||
// keep this key name from use by other kinds of assignments
|
||||
if !found {
|
||||
p.seenTableKeys = append(p.seenTableKeys, key.val)
|
||||
}
|
||||
|
||||
// move to next parser state
|
||||
p.assume(tokenDoubleRightBracket)
|
||||
return p.parseStart
|
||||
}
|
||||
|
||||
func (p *tomlParser) parseGroup() tomlParserStateFn {
|
||||
startToken := p.getToken() // discard the [
|
||||
key := p.getToken()
|
||||
if key.typ != tokenKeyGroup {
|
||||
p.raiseError(key, "unexpected token %s, was expecting a table key", key)
|
||||
}
|
||||
for _, item := range p.seenTableKeys {
|
||||
if item == key.val {
|
||||
p.raiseError(key, "duplicated tables")
|
||||
}
|
||||
}
|
||||
|
||||
p.seenTableKeys = append(p.seenTableKeys, key.val)
|
||||
keys, err := parseKey(key.val)
|
||||
if err != nil {
|
||||
p.raiseError(key, "invalid table array key: %s", err)
|
||||
}
|
||||
if err := p.tree.createSubTree(keys, startToken.Position); err != nil {
|
||||
p.raiseError(key, "%s", err)
|
||||
}
|
||||
destTree := p.tree.GetPath(keys)
|
||||
if target, ok := destTree.(*Tree); ok && target != nil && target.inline {
|
||||
p.raiseError(key, "could not re-define exist inline table or its sub-table : %s",
|
||||
strings.Join(keys, "."))
|
||||
}
|
||||
p.assume(tokenRightBracket)
|
||||
p.currentTable = keys
|
||||
return p.parseStart
|
||||
}
|
||||
|
||||
func (p *tomlParser) parseAssign() tomlParserStateFn {
|
||||
key := p.getToken()
|
||||
p.assume(tokenEqual)
|
||||
|
||||
parsedKey, err := parseKey(key.val)
|
||||
if err != nil {
|
||||
p.raiseError(key, "invalid key: %s", err.Error())
|
||||
}
|
||||
|
||||
value := p.parseRvalue()
|
||||
var tableKey []string
|
||||
if len(p.currentTable) > 0 {
|
||||
tableKey = p.currentTable
|
||||
} else {
|
||||
tableKey = []string{}
|
||||
}
|
||||
|
||||
prefixKey := parsedKey[0 : len(parsedKey)-1]
|
||||
tableKey = append(tableKey, prefixKey...)
|
||||
|
||||
// find the table to assign, looking out for arrays of tables
|
||||
var targetNode *Tree
|
||||
switch node := p.tree.GetPath(tableKey).(type) {
|
||||
case []*Tree:
|
||||
targetNode = node[len(node)-1]
|
||||
case *Tree:
|
||||
targetNode = node
|
||||
case nil:
|
||||
// create intermediate
|
||||
if err := p.tree.createSubTree(tableKey, key.Position); err != nil {
|
||||
p.raiseError(key, "could not create intermediate group: %s", err)
|
||||
}
|
||||
targetNode = p.tree.GetPath(tableKey).(*Tree)
|
||||
default:
|
||||
p.raiseError(key, "Unknown table type for path: %s",
|
||||
strings.Join(tableKey, "."))
|
||||
}
|
||||
|
||||
if targetNode.inline {
|
||||
p.raiseError(key, "could not add key or sub-table to exist inline table or its sub-table : %s",
|
||||
strings.Join(tableKey, "."))
|
||||
}
|
||||
|
||||
// assign value to the found table
|
||||
keyVal := parsedKey[len(parsedKey)-1]
|
||||
localKey := []string{keyVal}
|
||||
finalKey := append(tableKey, keyVal)
|
||||
if targetNode.GetPath(localKey) != nil {
|
||||
p.raiseError(key, "The following key was defined twice: %s",
|
||||
strings.Join(finalKey, "."))
|
||||
}
|
||||
var toInsert interface{}
|
||||
|
||||
switch value.(type) {
|
||||
case *Tree, []*Tree:
|
||||
toInsert = value
|
||||
default:
|
||||
toInsert = &tomlValue{value: value, position: key.Position}
|
||||
}
|
||||
targetNode.values[keyVal] = toInsert
|
||||
return p.parseStart
|
||||
}
|
||||
|
||||
var errInvalidUnderscore = errors.New("invalid use of _ in number")
|
||||
|
||||
func numberContainsInvalidUnderscore(value string) error {
|
||||
// For large numbers, you may use underscores between digits to enhance
|
||||
// readability. Each underscore must be surrounded by at least one digit on
|
||||
// each side.
|
||||
|
||||
hasBefore := false
|
||||
for idx, r := range value {
|
||||
if r == '_' {
|
||||
if !hasBefore || idx+1 >= len(value) {
|
||||
// can't end with an underscore
|
||||
return errInvalidUnderscore
|
||||
}
|
||||
}
|
||||
hasBefore = isDigit(r)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var errInvalidUnderscoreHex = errors.New("invalid use of _ in hex number")
|
||||
|
||||
func hexNumberContainsInvalidUnderscore(value string) error {
|
||||
hasBefore := false
|
||||
for idx, r := range value {
|
||||
if r == '_' {
|
||||
if !hasBefore || idx+1 >= len(value) {
|
||||
// can't end with an underscore
|
||||
return errInvalidUnderscoreHex
|
||||
}
|
||||
}
|
||||
hasBefore = isHexDigit(r)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func cleanupNumberToken(value string) string {
|
||||
cleanedVal := strings.Replace(value, "_", "", -1)
|
||||
return cleanedVal
|
||||
}
|
||||
|
||||
func (p *tomlParser) parseRvalue() interface{} {
|
||||
tok := p.getToken()
|
||||
if tok == nil || tok.typ == tokenEOF {
|
||||
p.raiseError(tok, "expecting a value")
|
||||
}
|
||||
|
||||
switch tok.typ {
|
||||
case tokenString:
|
||||
return tok.val
|
||||
case tokenTrue:
|
||||
return true
|
||||
case tokenFalse:
|
||||
return false
|
||||
case tokenInf:
|
||||
if tok.val[0] == '-' {
|
||||
return math.Inf(-1)
|
||||
}
|
||||
return math.Inf(1)
|
||||
case tokenNan:
|
||||
return math.NaN()
|
||||
case tokenInteger:
|
||||
cleanedVal := cleanupNumberToken(tok.val)
|
||||
var err error
|
||||
var val int64
|
||||
if len(cleanedVal) >= 3 && cleanedVal[0] == '0' {
|
||||
switch cleanedVal[1] {
|
||||
case 'x':
|
||||
err = hexNumberContainsInvalidUnderscore(tok.val)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
val, err = strconv.ParseInt(cleanedVal[2:], 16, 64)
|
||||
case 'o':
|
||||
err = numberContainsInvalidUnderscore(tok.val)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
val, err = strconv.ParseInt(cleanedVal[2:], 8, 64)
|
||||
case 'b':
|
||||
err = numberContainsInvalidUnderscore(tok.val)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
val, err = strconv.ParseInt(cleanedVal[2:], 2, 64)
|
||||
default:
|
||||
panic("invalid base") // the lexer should catch this first
|
||||
}
|
||||
} else {
|
||||
err = numberContainsInvalidUnderscore(tok.val)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
val, err = strconv.ParseInt(cleanedVal, 10, 64)
|
||||
}
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
return val
|
||||
case tokenFloat:
|
||||
err := numberContainsInvalidUnderscore(tok.val)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
cleanedVal := cleanupNumberToken(tok.val)
|
||||
val, err := strconv.ParseFloat(cleanedVal, 64)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
return val
|
||||
case tokenLocalTime:
|
||||
val, err := ParseLocalTime(tok.val)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
return val
|
||||
case tokenLocalDate:
|
||||
// a local date may be followed by:
|
||||
// * nothing: this is a local date
|
||||
// * a local time: this is a local date-time
|
||||
|
||||
next := p.peek()
|
||||
if next == nil || next.typ != tokenLocalTime {
|
||||
val, err := ParseLocalDate(tok.val)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
localDate := tok
|
||||
localTime := p.getToken()
|
||||
|
||||
next = p.peek()
|
||||
if next == nil || next.typ != tokenTimeOffset {
|
||||
v := localDate.val + "T" + localTime.val
|
||||
val, err := ParseLocalDateTime(v)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
offset := p.getToken()
|
||||
|
||||
layout := time.RFC3339Nano
|
||||
v := localDate.val + "T" + localTime.val + offset.val
|
||||
val, err := time.ParseInLocation(layout, v, time.UTC)
|
||||
if err != nil {
|
||||
p.raiseError(tok, "%s", err)
|
||||
}
|
||||
return val
|
||||
case tokenLeftBracket:
|
||||
return p.parseArray()
|
||||
case tokenLeftCurlyBrace:
|
||||
return p.parseInlineTable()
|
||||
case tokenEqual:
|
||||
p.raiseError(tok, "cannot have multiple equals for the same key")
|
||||
case tokenError:
|
||||
p.raiseError(tok, "%s", tok)
|
||||
default:
|
||||
panic(fmt.Errorf("unhandled token: %v", tok))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func tokenIsComma(t *token) bool {
|
||||
return t != nil && t.typ == tokenComma
|
||||
}
|
||||
|
||||
func (p *tomlParser) parseInlineTable() *Tree {
|
||||
tree := newTree()
|
||||
var previous *token
|
||||
Loop:
|
||||
for {
|
||||
follow := p.peek()
|
||||
if follow == nil || follow.typ == tokenEOF {
|
||||
p.raiseError(follow, "unterminated inline table")
|
||||
}
|
||||
switch follow.typ {
|
||||
case tokenRightCurlyBrace:
|
||||
p.getToken()
|
||||
break Loop
|
||||
case tokenKey, tokenInteger, tokenString:
|
||||
if !tokenIsComma(previous) && previous != nil {
|
||||
p.raiseError(follow, "comma expected between fields in inline table")
|
||||
}
|
||||
key := p.getToken()
|
||||
p.assume(tokenEqual)
|
||||
|
||||
parsedKey, err := parseKey(key.val)
|
||||
if err != nil {
|
||||
p.raiseError(key, "invalid key: %s", err)
|
||||
}
|
||||
|
||||
value := p.parseRvalue()
|
||||
tree.SetPath(parsedKey, value)
|
||||
case tokenComma:
|
||||
if tokenIsComma(previous) {
|
||||
p.raiseError(follow, "need field between two commas in inline table")
|
||||
}
|
||||
p.getToken()
|
||||
default:
|
||||
p.raiseError(follow, "unexpected token type in inline table: %s", follow.String())
|
||||
}
|
||||
previous = follow
|
||||
}
|
||||
if tokenIsComma(previous) {
|
||||
p.raiseError(previous, "trailing comma at the end of inline table")
|
||||
}
|
||||
tree.inline = true
|
||||
return tree
|
||||
}
|
||||
|
||||
func (p *tomlParser) parseArray() interface{} {
|
||||
var array []interface{}
|
||||
arrayType := reflect.TypeOf(newTree())
|
||||
for {
|
||||
follow := p.peek()
|
||||
if follow == nil || follow.typ == tokenEOF {
|
||||
p.raiseError(follow, "unterminated array")
|
||||
}
|
||||
if follow.typ == tokenRightBracket {
|
||||
p.getToken()
|
||||
break
|
||||
}
|
||||
val := p.parseRvalue()
|
||||
if reflect.TypeOf(val) != arrayType {
|
||||
arrayType = nil
|
||||
}
|
||||
array = append(array, val)
|
||||
follow = p.peek()
|
||||
if follow == nil || follow.typ == tokenEOF {
|
||||
p.raiseError(follow, "unterminated array")
|
||||
}
|
||||
if follow.typ != tokenRightBracket && follow.typ != tokenComma {
|
||||
p.raiseError(follow, "missing comma")
|
||||
}
|
||||
if follow.typ == tokenComma {
|
||||
p.getToken()
|
||||
}
|
||||
}
|
||||
|
||||
// if the array is a mixed-type array or its length is 0,
|
||||
// don't convert it to a table array
|
||||
if len(array) <= 0 {
|
||||
arrayType = nil
|
||||
}
|
||||
// An array of Trees is actually an array of inline
|
||||
// tables, which is a shorthand for a table array. If the
|
||||
// array was not converted from []interface{} to []*Tree,
|
||||
// the two notations would not be equivalent.
|
||||
if arrayType == reflect.TypeOf(newTree()) {
|
||||
tomlArray := make([]*Tree, len(array))
|
||||
for i, v := range array {
|
||||
tomlArray[i] = v.(*Tree)
|
||||
}
|
||||
return tomlArray
|
||||
}
|
||||
return array
|
||||
}
|
||||
|
||||
func parseToml(flow []token) *Tree {
|
||||
result := newTree()
|
||||
result.position = Position{1, 1}
|
||||
parser := &tomlParser{
|
||||
flowIdx: 0,
|
||||
flow: flow,
|
||||
tree: result,
|
||||
currentTable: make([]string, 0),
|
||||
seenTableKeys: make([]string, 0),
|
||||
}
|
||||
parser.run()
|
||||
return result
|
||||
}
|
||||
29
vendor/github.com/pelletier/go-toml/position.go
generated
vendored
Normal file
29
vendor/github.com/pelletier/go-toml/position.go
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Position support for go-toml
|
||||
|
||||
package toml
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Position of a document element within a TOML document.
|
||||
//
|
||||
// Line and Col are both 1-indexed positions for the element's line number and
|
||||
// column number, respectively. Values of zero or less will cause Invalid(),
|
||||
// to return true.
|
||||
type Position struct {
|
||||
Line int // line within the document
|
||||
Col int // column within the line
|
||||
}
|
||||
|
||||
// String representation of the position.
|
||||
// Displays 1-indexed line and column numbers.
|
||||
func (p Position) String() string {
|
||||
return fmt.Sprintf("(%d, %d)", p.Line, p.Col)
|
||||
}
|
||||
|
||||
// Invalid returns whether or not the position is valid (i.e. with negative or
|
||||
// null values)
|
||||
func (p Position) Invalid() bool {
|
||||
return p.Line <= 0 || p.Col <= 0
|
||||
}
|
||||
136
vendor/github.com/pelletier/go-toml/token.go
generated
vendored
Normal file
136
vendor/github.com/pelletier/go-toml/token.go
generated
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
package toml
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Define tokens
|
||||
type tokenType int
|
||||
|
||||
const (
|
||||
eof = -(iota + 1)
|
||||
)
|
||||
|
||||
const (
|
||||
tokenError tokenType = iota
|
||||
tokenEOF
|
||||
tokenComment
|
||||
tokenKey
|
||||
tokenString
|
||||
tokenInteger
|
||||
tokenTrue
|
||||
tokenFalse
|
||||
tokenFloat
|
||||
tokenInf
|
||||
tokenNan
|
||||
tokenEqual
|
||||
tokenLeftBracket
|
||||
tokenRightBracket
|
||||
tokenLeftCurlyBrace
|
||||
tokenRightCurlyBrace
|
||||
tokenLeftParen
|
||||
tokenRightParen
|
||||
tokenDoubleLeftBracket
|
||||
tokenDoubleRightBracket
|
||||
tokenLocalDate
|
||||
tokenLocalTime
|
||||
tokenTimeOffset
|
||||
tokenKeyGroup
|
||||
tokenKeyGroupArray
|
||||
tokenComma
|
||||
tokenColon
|
||||
tokenDollar
|
||||
tokenStar
|
||||
tokenQuestion
|
||||
tokenDot
|
||||
tokenDotDot
|
||||
tokenEOL
|
||||
)
|
||||
|
||||
var tokenTypeNames = []string{
|
||||
"Error",
|
||||
"EOF",
|
||||
"Comment",
|
||||
"Key",
|
||||
"String",
|
||||
"Integer",
|
||||
"True",
|
||||
"False",
|
||||
"Float",
|
||||
"Inf",
|
||||
"NaN",
|
||||
"=",
|
||||
"[",
|
||||
"]",
|
||||
"{",
|
||||
"}",
|
||||
"(",
|
||||
")",
|
||||
"]]",
|
||||
"[[",
|
||||
"LocalDate",
|
||||
"LocalTime",
|
||||
"TimeOffset",
|
||||
"KeyGroup",
|
||||
"KeyGroupArray",
|
||||
",",
|
||||
":",
|
||||
"$",
|
||||
"*",
|
||||
"?",
|
||||
".",
|
||||
"..",
|
||||
"EOL",
|
||||
}
|
||||
|
||||
type token struct {
|
||||
Position
|
||||
typ tokenType
|
||||
val string
|
||||
}
|
||||
|
||||
func (tt tokenType) String() string {
|
||||
idx := int(tt)
|
||||
if idx < len(tokenTypeNames) {
|
||||
return tokenTypeNames[idx]
|
||||
}
|
||||
return "Unknown"
|
||||
}
|
||||
|
||||
func (t token) String() string {
|
||||
switch t.typ {
|
||||
case tokenEOF:
|
||||
return "EOF"
|
||||
case tokenError:
|
||||
return t.val
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%q", t.val)
|
||||
}
|
||||
|
||||
func isSpace(r rune) bool {
|
||||
return r == ' ' || r == '\t'
|
||||
}
|
||||
|
||||
func isAlphanumeric(r rune) bool {
|
||||
return 'a' <= r && r <= 'z' || 'A' <= r && r <= 'Z' || r == '_'
|
||||
}
|
||||
|
||||
func isKeyChar(r rune) bool {
|
||||
// Keys start with the first character that isn't whitespace or [ and end
|
||||
// with the last non-whitespace character before the equals sign. Keys
|
||||
// cannot contain a # character."
|
||||
return !(r == '\r' || r == '\n' || r == eof || r == '=')
|
||||
}
|
||||
|
||||
func isKeyStartChar(r rune) bool {
|
||||
return !(isSpace(r) || r == '\r' || r == '\n' || r == eof || r == '[')
|
||||
}
|
||||
|
||||
func isDigit(r rune) bool {
|
||||
return '0' <= r && r <= '9'
|
||||
}
|
||||
|
||||
func isHexDigit(r rune) bool {
|
||||
return isDigit(r) ||
|
||||
(r >= 'a' && r <= 'f') ||
|
||||
(r >= 'A' && r <= 'F')
|
||||
}
|
||||
533
vendor/github.com/pelletier/go-toml/toml.go
generated
vendored
Normal file
533
vendor/github.com/pelletier/go-toml/toml.go
generated
vendored
Normal file
@@ -0,0 +1,533 @@
|
||||
package toml
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type tomlValue struct {
|
||||
value interface{} // string, int64, uint64, float64, bool, time.Time, [] of any of this list
|
||||
comment string
|
||||
commented bool
|
||||
multiline bool
|
||||
literal bool
|
||||
position Position
|
||||
}
|
||||
|
||||
// Tree is the result of the parsing of a TOML file.
|
||||
type Tree struct {
|
||||
values map[string]interface{} // string -> *tomlValue, *Tree, []*Tree
|
||||
comment string
|
||||
commented bool
|
||||
inline bool
|
||||
position Position
|
||||
}
|
||||
|
||||
func newTree() *Tree {
|
||||
return newTreeWithPosition(Position{})
|
||||
}
|
||||
|
||||
func newTreeWithPosition(pos Position) *Tree {
|
||||
return &Tree{
|
||||
values: make(map[string]interface{}),
|
||||
position: pos,
|
||||
}
|
||||
}
|
||||
|
||||
// TreeFromMap initializes a new Tree object using the given map.
|
||||
func TreeFromMap(m map[string]interface{}) (*Tree, error) {
|
||||
result, err := toTree(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(*Tree), nil
|
||||
}
|
||||
|
||||
// Position returns the position of the tree.
|
||||
func (t *Tree) Position() Position {
|
||||
return t.position
|
||||
}
|
||||
|
||||
// Has returns a boolean indicating if the given key exists.
|
||||
func (t *Tree) Has(key string) bool {
|
||||
if key == "" {
|
||||
return false
|
||||
}
|
||||
return t.HasPath(strings.Split(key, "."))
|
||||
}
|
||||
|
||||
// HasPath returns true if the given path of keys exists, false otherwise.
|
||||
func (t *Tree) HasPath(keys []string) bool {
|
||||
return t.GetPath(keys) != nil
|
||||
}
|
||||
|
||||
// Keys returns the keys of the toplevel tree (does not recurse).
|
||||
func (t *Tree) Keys() []string {
|
||||
keys := make([]string, len(t.values))
|
||||
i := 0
|
||||
for k := range t.values {
|
||||
keys[i] = k
|
||||
i++
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
// Get the value at key in the Tree.
|
||||
// Key is a dot-separated path (e.g. a.b.c) without single/double quoted strings.
|
||||
// If you need to retrieve non-bare keys, use GetPath.
|
||||
// Returns nil if the path does not exist in the tree.
|
||||
// If keys is of length zero, the current tree is returned.
|
||||
func (t *Tree) Get(key string) interface{} {
|
||||
if key == "" {
|
||||
return t
|
||||
}
|
||||
return t.GetPath(strings.Split(key, "."))
|
||||
}
|
||||
|
||||
// GetPath returns the element in the tree indicated by 'keys'.
|
||||
// If keys is of length zero, the current tree is returned.
|
||||
func (t *Tree) GetPath(keys []string) interface{} {
|
||||
if len(keys) == 0 {
|
||||
return t
|
||||
}
|
||||
subtree := t
|
||||
for _, intermediateKey := range keys[:len(keys)-1] {
|
||||
value, exists := subtree.values[intermediateKey]
|
||||
if !exists {
|
||||
return nil
|
||||
}
|
||||
switch node := value.(type) {
|
||||
case *Tree:
|
||||
subtree = node
|
||||
case []*Tree:
|
||||
// go to most recent element
|
||||
if len(node) == 0 {
|
||||
return nil
|
||||
}
|
||||
subtree = node[len(node)-1]
|
||||
default:
|
||||
return nil // cannot navigate through other node types
|
||||
}
|
||||
}
|
||||
// branch based on final node type
|
||||
switch node := subtree.values[keys[len(keys)-1]].(type) {
|
||||
case *tomlValue:
|
||||
return node.value
|
||||
default:
|
||||
return node
|
||||
}
|
||||
}
|
||||
|
||||
// GetArray returns the value at key in the Tree.
|
||||
// It returns []string, []int64, etc type if key has homogeneous lists
|
||||
// Key is a dot-separated path (e.g. a.b.c) without single/double quoted strings.
|
||||
// Returns nil if the path does not exist in the tree.
|
||||
// If keys is of length zero, the current tree is returned.
|
||||
func (t *Tree) GetArray(key string) interface{} {
|
||||
if key == "" {
|
||||
return t
|
||||
}
|
||||
return t.GetArrayPath(strings.Split(key, "."))
|
||||
}
|
||||
|
||||
// GetArrayPath returns the element in the tree indicated by 'keys'.
|
||||
// If keys is of length zero, the current tree is returned.
|
||||
func (t *Tree) GetArrayPath(keys []string) interface{} {
|
||||
if len(keys) == 0 {
|
||||
return t
|
||||
}
|
||||
subtree := t
|
||||
for _, intermediateKey := range keys[:len(keys)-1] {
|
||||
value, exists := subtree.values[intermediateKey]
|
||||
if !exists {
|
||||
return nil
|
||||
}
|
||||
switch node := value.(type) {
|
||||
case *Tree:
|
||||
subtree = node
|
||||
case []*Tree:
|
||||
// go to most recent element
|
||||
if len(node) == 0 {
|
||||
return nil
|
||||
}
|
||||
subtree = node[len(node)-1]
|
||||
default:
|
||||
return nil // cannot navigate through other node types
|
||||
}
|
||||
}
|
||||
// branch based on final node type
|
||||
switch node := subtree.values[keys[len(keys)-1]].(type) {
|
||||
case *tomlValue:
|
||||
switch n := node.value.(type) {
|
||||
case []interface{}:
|
||||
return getArray(n)
|
||||
default:
|
||||
return node.value
|
||||
}
|
||||
default:
|
||||
return node
|
||||
}
|
||||
}
|
||||
|
||||
// if homogeneous array, then return slice type object over []interface{}
|
||||
func getArray(n []interface{}) interface{} {
|
||||
var s []string
|
||||
var i64 []int64
|
||||
var f64 []float64
|
||||
var bl []bool
|
||||
for _, value := range n {
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
s = append(s, v)
|
||||
case int64:
|
||||
i64 = append(i64, v)
|
||||
case float64:
|
||||
f64 = append(f64, v)
|
||||
case bool:
|
||||
bl = append(bl, v)
|
||||
default:
|
||||
return n
|
||||
}
|
||||
}
|
||||
if len(s) == len(n) {
|
||||
return s
|
||||
} else if len(i64) == len(n) {
|
||||
return i64
|
||||
} else if len(f64) == len(n) {
|
||||
return f64
|
||||
} else if len(bl) == len(n) {
|
||||
return bl
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// GetPosition returns the position of the given key.
|
||||
func (t *Tree) GetPosition(key string) Position {
|
||||
if key == "" {
|
||||
return t.position
|
||||
}
|
||||
return t.GetPositionPath(strings.Split(key, "."))
|
||||
}
|
||||
|
||||
// SetPositionPath sets the position of element in the tree indicated by 'keys'.
|
||||
// If keys is of length zero, the current tree position is set.
|
||||
func (t *Tree) SetPositionPath(keys []string, pos Position) {
|
||||
if len(keys) == 0 {
|
||||
t.position = pos
|
||||
return
|
||||
}
|
||||
subtree := t
|
||||
for _, intermediateKey := range keys[:len(keys)-1] {
|
||||
value, exists := subtree.values[intermediateKey]
|
||||
if !exists {
|
||||
return
|
||||
}
|
||||
switch node := value.(type) {
|
||||
case *Tree:
|
||||
subtree = node
|
||||
case []*Tree:
|
||||
// go to most recent element
|
||||
if len(node) == 0 {
|
||||
return
|
||||
}
|
||||
subtree = node[len(node)-1]
|
||||
default:
|
||||
return
|
||||
}
|
||||
}
|
||||
// branch based on final node type
|
||||
switch node := subtree.values[keys[len(keys)-1]].(type) {
|
||||
case *tomlValue:
|
||||
node.position = pos
|
||||
return
|
||||
case *Tree:
|
||||
node.position = pos
|
||||
return
|
||||
case []*Tree:
|
||||
// go to most recent element
|
||||
if len(node) == 0 {
|
||||
return
|
||||
}
|
||||
node[len(node)-1].position = pos
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// GetPositionPath returns the element in the tree indicated by 'keys'.
|
||||
// If keys is of length zero, the current tree is returned.
|
||||
func (t *Tree) GetPositionPath(keys []string) Position {
|
||||
if len(keys) == 0 {
|
||||
return t.position
|
||||
}
|
||||
subtree := t
|
||||
for _, intermediateKey := range keys[:len(keys)-1] {
|
||||
value, exists := subtree.values[intermediateKey]
|
||||
if !exists {
|
||||
return Position{0, 0}
|
||||
}
|
||||
switch node := value.(type) {
|
||||
case *Tree:
|
||||
subtree = node
|
||||
case []*Tree:
|
||||
// go to most recent element
|
||||
if len(node) == 0 {
|
||||
return Position{0, 0}
|
||||
}
|
||||
subtree = node[len(node)-1]
|
||||
default:
|
||||
return Position{0, 0}
|
||||
}
|
||||
}
|
||||
// branch based on final node type
|
||||
switch node := subtree.values[keys[len(keys)-1]].(type) {
|
||||
case *tomlValue:
|
||||
return node.position
|
||||
case *Tree:
|
||||
return node.position
|
||||
case []*Tree:
|
||||
// go to most recent element
|
||||
if len(node) == 0 {
|
||||
return Position{0, 0}
|
||||
}
|
||||
return node[len(node)-1].position
|
||||
default:
|
||||
return Position{0, 0}
|
||||
}
|
||||
}
|
||||
|
||||
// GetDefault works like Get but with a default value
|
||||
func (t *Tree) GetDefault(key string, def interface{}) interface{} {
|
||||
val := t.Get(key)
|
||||
if val == nil {
|
||||
return def
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// SetOptions arguments are supplied to the SetWithOptions and SetPathWithOptions functions to modify marshalling behaviour.
|
||||
// The default values within the struct are valid default options.
|
||||
type SetOptions struct {
|
||||
Comment string
|
||||
Commented bool
|
||||
Multiline bool
|
||||
Literal bool
|
||||
}
|
||||
|
||||
// SetWithOptions is the same as Set, but allows you to provide formatting
|
||||
// instructions to the key, that will be used by Marshal().
|
||||
func (t *Tree) SetWithOptions(key string, opts SetOptions, value interface{}) {
|
||||
t.SetPathWithOptions(strings.Split(key, "."), opts, value)
|
||||
}
|
||||
|
||||
// SetPathWithOptions is the same as SetPath, but allows you to provide
|
||||
// formatting instructions to the key, that will be reused by Marshal().
|
||||
func (t *Tree) SetPathWithOptions(keys []string, opts SetOptions, value interface{}) {
|
||||
subtree := t
|
||||
for i, intermediateKey := range keys[:len(keys)-1] {
|
||||
nextTree, exists := subtree.values[intermediateKey]
|
||||
if !exists {
|
||||
nextTree = newTreeWithPosition(Position{Line: t.position.Line + i, Col: t.position.Col})
|
||||
subtree.values[intermediateKey] = nextTree // add new element here
|
||||
}
|
||||
switch node := nextTree.(type) {
|
||||
case *Tree:
|
||||
subtree = node
|
||||
case []*Tree:
|
||||
// go to most recent element
|
||||
if len(node) == 0 {
|
||||
// create element if it does not exist
|
||||
node = append(node, newTreeWithPosition(Position{Line: t.position.Line + i, Col: t.position.Col}))
|
||||
subtree.values[intermediateKey] = node
|
||||
}
|
||||
subtree = node[len(node)-1]
|
||||
}
|
||||
}
|
||||
|
||||
var toInsert interface{}
|
||||
|
||||
switch v := value.(type) {
|
||||
case *Tree:
|
||||
v.comment = opts.Comment
|
||||
v.commented = opts.Commented
|
||||
toInsert = value
|
||||
case []*Tree:
|
||||
for i := range v {
|
||||
v[i].commented = opts.Commented
|
||||
}
|
||||
toInsert = value
|
||||
case *tomlValue:
|
||||
v.comment = opts.Comment
|
||||
v.commented = opts.Commented
|
||||
v.multiline = opts.Multiline
|
||||
v.literal = opts.Literal
|
||||
toInsert = v
|
||||
default:
|
||||
toInsert = &tomlValue{value: value,
|
||||
comment: opts.Comment,
|
||||
commented: opts.Commented,
|
||||
multiline: opts.Multiline,
|
||||
literal: opts.Literal,
|
||||
position: Position{Line: subtree.position.Line + len(subtree.values) + 1, Col: subtree.position.Col}}
|
||||
}
|
||||
|
||||
subtree.values[keys[len(keys)-1]] = toInsert
|
||||
}
|
||||
|
||||
// Set an element in the tree.
|
||||
// Key is a dot-separated path (e.g. a.b.c).
|
||||
// Creates all necessary intermediate trees, if needed.
|
||||
func (t *Tree) Set(key string, value interface{}) {
|
||||
t.SetWithComment(key, "", false, value)
|
||||
}
|
||||
|
||||
// SetWithComment is the same as Set, but allows you to provide comment
|
||||
// information to the key, that will be reused by Marshal().
|
||||
func (t *Tree) SetWithComment(key string, comment string, commented bool, value interface{}) {
|
||||
t.SetPathWithComment(strings.Split(key, "."), comment, commented, value)
|
||||
}
|
||||
|
||||
// SetPath sets an element in the tree.
|
||||
// Keys is an array of path elements (e.g. {"a","b","c"}).
|
||||
// Creates all necessary intermediate trees, if needed.
|
||||
func (t *Tree) SetPath(keys []string, value interface{}) {
|
||||
t.SetPathWithComment(keys, "", false, value)
|
||||
}
|
||||
|
||||
// SetPathWithComment is the same as SetPath, but allows you to provide comment
|
||||
// information to the key, that will be reused by Marshal().
|
||||
func (t *Tree) SetPathWithComment(keys []string, comment string, commented bool, value interface{}) {
|
||||
t.SetPathWithOptions(keys, SetOptions{Comment: comment, Commented: commented}, value)
|
||||
}
|
||||
|
||||
// Delete removes a key from the tree.
|
||||
// Key is a dot-separated path (e.g. a.b.c).
|
||||
func (t *Tree) Delete(key string) error {
|
||||
keys, err := parseKey(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return t.DeletePath(keys)
|
||||
}
|
||||
|
||||
// DeletePath removes a key from the tree.
|
||||
// Keys is an array of path elements (e.g. {"a","b","c"}).
|
||||
func (t *Tree) DeletePath(keys []string) error {
|
||||
keyLen := len(keys)
|
||||
if keyLen == 1 {
|
||||
delete(t.values, keys[0])
|
||||
return nil
|
||||
}
|
||||
tree := t.GetPath(keys[:keyLen-1])
|
||||
item := keys[keyLen-1]
|
||||
switch node := tree.(type) {
|
||||
case *Tree:
|
||||
delete(node.values, item)
|
||||
return nil
|
||||
}
|
||||
return errors.New("no such key to delete")
|
||||
}
|
||||
|
||||
// createSubTree takes a tree and a key and create the necessary intermediate
|
||||
// subtrees to create a subtree at that point. In-place.
|
||||
//
|
||||
// e.g. passing a.b.c will create (assuming tree is empty) tree[a], tree[a][b]
|
||||
// and tree[a][b][c]
|
||||
//
|
||||
// Returns nil on success, error object on failure
|
||||
func (t *Tree) createSubTree(keys []string, pos Position) error {
|
||||
subtree := t
|
||||
for i, intermediateKey := range keys {
|
||||
nextTree, exists := subtree.values[intermediateKey]
|
||||
if !exists {
|
||||
tree := newTreeWithPosition(Position{Line: t.position.Line + i, Col: t.position.Col})
|
||||
tree.position = pos
|
||||
tree.inline = subtree.inline
|
||||
subtree.values[intermediateKey] = tree
|
||||
nextTree = tree
|
||||
}
|
||||
|
||||
switch node := nextTree.(type) {
|
||||
case []*Tree:
|
||||
subtree = node[len(node)-1]
|
||||
case *Tree:
|
||||
subtree = node
|
||||
default:
|
||||
return fmt.Errorf("unknown type for path %s (%s): %T (%#v)",
|
||||
strings.Join(keys, "."), intermediateKey, nextTree, nextTree)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadBytes creates a Tree from a []byte.
|
||||
func LoadBytes(b []byte) (tree *Tree, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
if _, ok := r.(runtime.Error); ok {
|
||||
panic(r)
|
||||
}
|
||||
err = errors.New(r.(string))
|
||||
}
|
||||
}()
|
||||
|
||||
if len(b) >= 4 && (hasUTF32BigEndianBOM4(b) || hasUTF32LittleEndianBOM4(b)) {
|
||||
b = b[4:]
|
||||
} else if len(b) >= 3 && hasUTF8BOM3(b) {
|
||||
b = b[3:]
|
||||
} else if len(b) >= 2 && (hasUTF16BigEndianBOM2(b) || hasUTF16LittleEndianBOM2(b)) {
|
||||
b = b[2:]
|
||||
}
|
||||
|
||||
tree = parseToml(lexToml(b))
|
||||
return
|
||||
}
|
||||
|
||||
func hasUTF16BigEndianBOM2(b []byte) bool {
|
||||
return b[0] == 0xFE && b[1] == 0xFF
|
||||
}
|
||||
|
||||
func hasUTF16LittleEndianBOM2(b []byte) bool {
|
||||
return b[0] == 0xFF && b[1] == 0xFE
|
||||
}
|
||||
|
||||
func hasUTF8BOM3(b []byte) bool {
|
||||
return b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF
|
||||
}
|
||||
|
||||
func hasUTF32BigEndianBOM4(b []byte) bool {
|
||||
return b[0] == 0x00 && b[1] == 0x00 && b[2] == 0xFE && b[3] == 0xFF
|
||||
}
|
||||
|
||||
func hasUTF32LittleEndianBOM4(b []byte) bool {
|
||||
return b[0] == 0xFF && b[1] == 0xFE && b[2] == 0x00 && b[3] == 0x00
|
||||
}
|
||||
|
||||
// LoadReader creates a Tree from any io.Reader.
|
||||
func LoadReader(reader io.Reader) (tree *Tree, err error) {
|
||||
inputBytes, err := ioutil.ReadAll(reader)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
tree, err = LoadBytes(inputBytes)
|
||||
return
|
||||
}
|
||||
|
||||
// Load creates a Tree from a string.
|
||||
func Load(content string) (tree *Tree, err error) {
|
||||
return LoadBytes([]byte(content))
|
||||
}
|
||||
|
||||
// LoadFile creates a Tree from a file.
|
||||
func LoadFile(path string) (tree *Tree, err error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
return LoadReader(file)
|
||||
}
|
||||
71
vendor/github.com/pelletier/go-toml/tomlpub.go
generated
vendored
Normal file
71
vendor/github.com/pelletier/go-toml/tomlpub.go
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
package toml
|
||||
|
||||
// PubTOMLValue wrapping tomlValue in order to access all properties from outside.
|
||||
type PubTOMLValue = tomlValue
|
||||
|
||||
func (ptv *PubTOMLValue) Value() interface{} {
|
||||
return ptv.value
|
||||
}
|
||||
func (ptv *PubTOMLValue) Comment() string {
|
||||
return ptv.comment
|
||||
}
|
||||
func (ptv *PubTOMLValue) Commented() bool {
|
||||
return ptv.commented
|
||||
}
|
||||
func (ptv *PubTOMLValue) Multiline() bool {
|
||||
return ptv.multiline
|
||||
}
|
||||
func (ptv *PubTOMLValue) Position() Position {
|
||||
return ptv.position
|
||||
}
|
||||
|
||||
func (ptv *PubTOMLValue) SetValue(v interface{}) {
|
||||
ptv.value = v
|
||||
}
|
||||
func (ptv *PubTOMLValue) SetComment(s string) {
|
||||
ptv.comment = s
|
||||
}
|
||||
func (ptv *PubTOMLValue) SetCommented(c bool) {
|
||||
ptv.commented = c
|
||||
}
|
||||
func (ptv *PubTOMLValue) SetMultiline(m bool) {
|
||||
ptv.multiline = m
|
||||
}
|
||||
func (ptv *PubTOMLValue) SetPosition(p Position) {
|
||||
ptv.position = p
|
||||
}
|
||||
|
||||
// PubTree wrapping Tree in order to access all properties from outside.
|
||||
type PubTree = Tree
|
||||
|
||||
func (pt *PubTree) Values() map[string]interface{} {
|
||||
return pt.values
|
||||
}
|
||||
|
||||
func (pt *PubTree) Comment() string {
|
||||
return pt.comment
|
||||
}
|
||||
|
||||
func (pt *PubTree) Commented() bool {
|
||||
return pt.commented
|
||||
}
|
||||
|
||||
func (pt *PubTree) Inline() bool {
|
||||
return pt.inline
|
||||
}
|
||||
|
||||
func (pt *PubTree) SetValues(v map[string]interface{}) {
|
||||
pt.values = v
|
||||
}
|
||||
|
||||
func (pt *PubTree) SetComment(c string) {
|
||||
pt.comment = c
|
||||
}
|
||||
|
||||
func (pt *PubTree) SetCommented(c bool) {
|
||||
pt.commented = c
|
||||
}
|
||||
|
||||
func (pt *PubTree) SetInline(i bool) {
|
||||
pt.inline = i
|
||||
}
|
||||
155
vendor/github.com/pelletier/go-toml/tomltree_create.go
generated
vendored
Normal file
155
vendor/github.com/pelletier/go-toml/tomltree_create.go
generated
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
package toml
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
var kindToType = [reflect.String + 1]reflect.Type{
|
||||
reflect.Bool: reflect.TypeOf(true),
|
||||
reflect.String: reflect.TypeOf(""),
|
||||
reflect.Float32: reflect.TypeOf(float64(1)),
|
||||
reflect.Float64: reflect.TypeOf(float64(1)),
|
||||
reflect.Int: reflect.TypeOf(int64(1)),
|
||||
reflect.Int8: reflect.TypeOf(int64(1)),
|
||||
reflect.Int16: reflect.TypeOf(int64(1)),
|
||||
reflect.Int32: reflect.TypeOf(int64(1)),
|
||||
reflect.Int64: reflect.TypeOf(int64(1)),
|
||||
reflect.Uint: reflect.TypeOf(uint64(1)),
|
||||
reflect.Uint8: reflect.TypeOf(uint64(1)),
|
||||
reflect.Uint16: reflect.TypeOf(uint64(1)),
|
||||
reflect.Uint32: reflect.TypeOf(uint64(1)),
|
||||
reflect.Uint64: reflect.TypeOf(uint64(1)),
|
||||
}
|
||||
|
||||
// typeFor returns a reflect.Type for a reflect.Kind, or nil if none is found.
|
||||
// supported values:
|
||||
// string, bool, int64, uint64, float64, time.Time, int, int8, int16, int32, uint, uint8, uint16, uint32, float32
|
||||
func typeFor(k reflect.Kind) reflect.Type {
|
||||
if k > 0 && int(k) < len(kindToType) {
|
||||
return kindToType[k]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func simpleValueCoercion(object interface{}) (interface{}, error) {
|
||||
switch original := object.(type) {
|
||||
case string, bool, int64, uint64, float64, time.Time:
|
||||
return original, nil
|
||||
case int:
|
||||
return int64(original), nil
|
||||
case int8:
|
||||
return int64(original), nil
|
||||
case int16:
|
||||
return int64(original), nil
|
||||
case int32:
|
||||
return int64(original), nil
|
||||
case uint:
|
||||
return uint64(original), nil
|
||||
case uint8:
|
||||
return uint64(original), nil
|
||||
case uint16:
|
||||
return uint64(original), nil
|
||||
case uint32:
|
||||
return uint64(original), nil
|
||||
case float32:
|
||||
return float64(original), nil
|
||||
case fmt.Stringer:
|
||||
return original.String(), nil
|
||||
case []interface{}:
|
||||
value := reflect.ValueOf(original)
|
||||
length := value.Len()
|
||||
arrayValue := reflect.MakeSlice(value.Type(), 0, length)
|
||||
for i := 0; i < length; i++ {
|
||||
val := value.Index(i).Interface()
|
||||
simpleValue, err := simpleValueCoercion(val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
arrayValue = reflect.Append(arrayValue, reflect.ValueOf(simpleValue))
|
||||
}
|
||||
return arrayValue.Interface(), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot convert type %T to Tree", object)
|
||||
}
|
||||
}
|
||||
|
||||
func sliceToTree(object interface{}) (interface{}, error) {
|
||||
// arrays are a bit tricky, since they can represent either a
|
||||
// collection of simple values, which is represented by one
|
||||
// *tomlValue, or an array of tables, which is represented by an
|
||||
// array of *Tree.
|
||||
|
||||
// holding the assumption that this function is called from toTree only when value.Kind() is Array or Slice
|
||||
value := reflect.ValueOf(object)
|
||||
insideType := value.Type().Elem()
|
||||
length := value.Len()
|
||||
if length > 0 {
|
||||
insideType = reflect.ValueOf(value.Index(0).Interface()).Type()
|
||||
}
|
||||
if insideType.Kind() == reflect.Map {
|
||||
// this is considered as an array of tables
|
||||
tablesArray := make([]*Tree, 0, length)
|
||||
for i := 0; i < length; i++ {
|
||||
table := value.Index(i)
|
||||
tree, err := toTree(table.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tablesArray = append(tablesArray, tree.(*Tree))
|
||||
}
|
||||
return tablesArray, nil
|
||||
}
|
||||
|
||||
sliceType := typeFor(insideType.Kind())
|
||||
if sliceType == nil {
|
||||
sliceType = insideType
|
||||
}
|
||||
|
||||
arrayValue := reflect.MakeSlice(reflect.SliceOf(sliceType), 0, length)
|
||||
|
||||
for i := 0; i < length; i++ {
|
||||
val := value.Index(i).Interface()
|
||||
simpleValue, err := simpleValueCoercion(val)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
arrayValue = reflect.Append(arrayValue, reflect.ValueOf(simpleValue))
|
||||
}
|
||||
return &tomlValue{value: arrayValue.Interface(), position: Position{}}, nil
|
||||
}
|
||||
|
||||
func toTree(object interface{}) (interface{}, error) {
|
||||
value := reflect.ValueOf(object)
|
||||
|
||||
if value.Kind() == reflect.Map {
|
||||
values := map[string]interface{}{}
|
||||
keys := value.MapKeys()
|
||||
for _, key := range keys {
|
||||
if key.Kind() != reflect.String {
|
||||
if _, ok := key.Interface().(string); !ok {
|
||||
return nil, fmt.Errorf("map key needs to be a string, not %T (%v)", key.Interface(), key.Kind())
|
||||
}
|
||||
}
|
||||
|
||||
v := value.MapIndex(key)
|
||||
newValue, err := toTree(v.Interface())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
values[key.String()] = newValue
|
||||
}
|
||||
return &Tree{values: values, position: Position{}}, nil
|
||||
}
|
||||
|
||||
if value.Kind() == reflect.Array || value.Kind() == reflect.Slice {
|
||||
return sliceToTree(object)
|
||||
}
|
||||
|
||||
simpleValue, err := simpleValueCoercion(object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &tomlValue{value: simpleValue, position: Position{}}, nil
|
||||
}
|
||||
552
vendor/github.com/pelletier/go-toml/tomltree_write.go
generated
vendored
Normal file
552
vendor/github.com/pelletier/go-toml/tomltree_write.go
generated
vendored
Normal file
@@ -0,0 +1,552 @@
|
||||
package toml
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type valueComplexity int
|
||||
|
||||
const (
|
||||
valueSimple valueComplexity = iota + 1
|
||||
valueComplex
|
||||
)
|
||||
|
||||
type sortNode struct {
|
||||
key string
|
||||
complexity valueComplexity
|
||||
}
|
||||
|
||||
// Encodes a string to a TOML-compliant multi-line string value
|
||||
// This function is a clone of the existing encodeTomlString function, except that whitespace characters
|
||||
// are preserved. Quotation marks and backslashes are also not escaped.
|
||||
func encodeMultilineTomlString(value string, commented string) string {
|
||||
var b bytes.Buffer
|
||||
adjacentQuoteCount := 0
|
||||
|
||||
b.WriteString(commented)
|
||||
for i, rr := range value {
|
||||
if rr != '"' {
|
||||
adjacentQuoteCount = 0
|
||||
} else {
|
||||
adjacentQuoteCount++
|
||||
}
|
||||
switch rr {
|
||||
case '\b':
|
||||
b.WriteString(`\b`)
|
||||
case '\t':
|
||||
b.WriteString("\t")
|
||||
case '\n':
|
||||
b.WriteString("\n" + commented)
|
||||
case '\f':
|
||||
b.WriteString(`\f`)
|
||||
case '\r':
|
||||
b.WriteString("\r")
|
||||
case '"':
|
||||
if adjacentQuoteCount >= 3 || i == len(value)-1 {
|
||||
adjacentQuoteCount = 0
|
||||
b.WriteString(`\"`)
|
||||
} else {
|
||||
b.WriteString(`"`)
|
||||
}
|
||||
case '\\':
|
||||
b.WriteString(`\`)
|
||||
default:
|
||||
intRr := uint16(rr)
|
||||
if intRr < 0x001F {
|
||||
b.WriteString(fmt.Sprintf("\\u%0.4X", intRr))
|
||||
} else {
|
||||
b.WriteRune(rr)
|
||||
}
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// Encodes a string to a TOML-compliant string value
|
||||
func encodeTomlString(value string) string {
|
||||
var b bytes.Buffer
|
||||
|
||||
for _, rr := range value {
|
||||
switch rr {
|
||||
case '\b':
|
||||
b.WriteString(`\b`)
|
||||
case '\t':
|
||||
b.WriteString(`\t`)
|
||||
case '\n':
|
||||
b.WriteString(`\n`)
|
||||
case '\f':
|
||||
b.WriteString(`\f`)
|
||||
case '\r':
|
||||
b.WriteString(`\r`)
|
||||
case '"':
|
||||
b.WriteString(`\"`)
|
||||
case '\\':
|
||||
b.WriteString(`\\`)
|
||||
default:
|
||||
intRr := uint16(rr)
|
||||
if intRr < 0x001F {
|
||||
b.WriteString(fmt.Sprintf("\\u%0.4X", intRr))
|
||||
} else {
|
||||
b.WriteRune(rr)
|
||||
}
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func tomlTreeStringRepresentation(t *Tree, ord MarshalOrder) (string, error) {
|
||||
var orderedVals []sortNode
|
||||
switch ord {
|
||||
case OrderPreserve:
|
||||
orderedVals = sortByLines(t)
|
||||
default:
|
||||
orderedVals = sortAlphabetical(t)
|
||||
}
|
||||
|
||||
var values []string
|
||||
for _, node := range orderedVals {
|
||||
k := node.key
|
||||
v := t.values[k]
|
||||
|
||||
repr, err := tomlValueStringRepresentation(v, "", "", ord, false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
values = append(values, quoteKeyIfNeeded(k)+" = "+repr)
|
||||
}
|
||||
return "{ " + strings.Join(values, ", ") + " }", nil
|
||||
}
|
||||
|
||||
func tomlValueStringRepresentation(v interface{}, commented string, indent string, ord MarshalOrder, arraysOneElementPerLine bool) (string, error) {
|
||||
// this interface check is added to dereference the change made in the writeTo function.
|
||||
// That change was made to allow this function to see formatting options.
|
||||
tv, ok := v.(*tomlValue)
|
||||
if ok {
|
||||
v = tv.value
|
||||
} else {
|
||||
tv = &tomlValue{}
|
||||
}
|
||||
|
||||
switch value := v.(type) {
|
||||
case uint64:
|
||||
return strconv.FormatUint(value, 10), nil
|
||||
case int64:
|
||||
return strconv.FormatInt(value, 10), nil
|
||||
case float64:
|
||||
// Default bit length is full 64
|
||||
bits := 64
|
||||
// Float panics if nan is used
|
||||
if !math.IsNaN(value) {
|
||||
// if 32 bit accuracy is enough to exactly show, use 32
|
||||
_, acc := big.NewFloat(value).Float32()
|
||||
if acc == big.Exact {
|
||||
bits = 32
|
||||
}
|
||||
}
|
||||
if math.Trunc(value) == value {
|
||||
return strings.ToLower(strconv.FormatFloat(value, 'f', 1, bits)), nil
|
||||
}
|
||||
return strings.ToLower(strconv.FormatFloat(value, 'f', -1, bits)), nil
|
||||
case string:
|
||||
if tv.multiline {
|
||||
if tv.literal {
|
||||
b := strings.Builder{}
|
||||
b.WriteString("'''\n")
|
||||
b.Write([]byte(value))
|
||||
b.WriteString("\n'''")
|
||||
return b.String(), nil
|
||||
} else {
|
||||
return "\"\"\"\n" + encodeMultilineTomlString(value, commented) + "\"\"\"", nil
|
||||
}
|
||||
}
|
||||
return "\"" + encodeTomlString(value) + "\"", nil
|
||||
case []byte:
|
||||
b, _ := v.([]byte)
|
||||
return string(b), nil
|
||||
case bool:
|
||||
if value {
|
||||
return "true", nil
|
||||
}
|
||||
return "false", nil
|
||||
case time.Time:
|
||||
return value.Format(time.RFC3339), nil
|
||||
case LocalDate:
|
||||
return value.String(), nil
|
||||
case LocalDateTime:
|
||||
return value.String(), nil
|
||||
case LocalTime:
|
||||
return value.String(), nil
|
||||
case *Tree:
|
||||
return tomlTreeStringRepresentation(value, ord)
|
||||
case nil:
|
||||
return "", nil
|
||||
}
|
||||
|
||||
rv := reflect.ValueOf(v)
|
||||
|
||||
if rv.Kind() == reflect.Slice {
|
||||
var values []string
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
item := rv.Index(i).Interface()
|
||||
itemRepr, err := tomlValueStringRepresentation(item, commented, indent, ord, arraysOneElementPerLine)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
values = append(values, itemRepr)
|
||||
}
|
||||
if arraysOneElementPerLine && len(values) > 1 {
|
||||
stringBuffer := bytes.Buffer{}
|
||||
valueIndent := indent + ` ` // TODO: move that to a shared encoder state
|
||||
|
||||
stringBuffer.WriteString("[\n")
|
||||
|
||||
for _, value := range values {
|
||||
stringBuffer.WriteString(valueIndent)
|
||||
stringBuffer.WriteString(commented + value)
|
||||
stringBuffer.WriteString(`,`)
|
||||
stringBuffer.WriteString("\n")
|
||||
}
|
||||
|
||||
stringBuffer.WriteString(indent + commented + "]")
|
||||
|
||||
return stringBuffer.String(), nil
|
||||
}
|
||||
return "[" + strings.Join(values, ", ") + "]", nil
|
||||
}
|
||||
return "", fmt.Errorf("unsupported value type %T: %v", v, v)
|
||||
}
|
||||
|
||||
func getTreeArrayLine(trees []*Tree) (line int) {
|
||||
// Prevent returning 0 for empty trees
|
||||
line = int(^uint(0) >> 1)
|
||||
// get lowest line number >= 0
|
||||
for _, tv := range trees {
|
||||
if tv.position.Line < line || line == 0 {
|
||||
line = tv.position.Line
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func sortByLines(t *Tree) (vals []sortNode) {
|
||||
var (
|
||||
line int
|
||||
lines []int
|
||||
tv *Tree
|
||||
tom *tomlValue
|
||||
node sortNode
|
||||
)
|
||||
vals = make([]sortNode, 0)
|
||||
m := make(map[int]sortNode)
|
||||
|
||||
for k := range t.values {
|
||||
v := t.values[k]
|
||||
switch v.(type) {
|
||||
case *Tree:
|
||||
tv = v.(*Tree)
|
||||
line = tv.position.Line
|
||||
node = sortNode{key: k, complexity: valueComplex}
|
||||
case []*Tree:
|
||||
line = getTreeArrayLine(v.([]*Tree))
|
||||
node = sortNode{key: k, complexity: valueComplex}
|
||||
default:
|
||||
tom = v.(*tomlValue)
|
||||
line = tom.position.Line
|
||||
node = sortNode{key: k, complexity: valueSimple}
|
||||
}
|
||||
lines = append(lines, line)
|
||||
vals = append(vals, node)
|
||||
m[line] = node
|
||||
}
|
||||
sort.Ints(lines)
|
||||
|
||||
for i, line := range lines {
|
||||
vals[i] = m[line]
|
||||
}
|
||||
|
||||
return vals
|
||||
}
|
||||
|
||||
func sortAlphabetical(t *Tree) (vals []sortNode) {
|
||||
var (
|
||||
node sortNode
|
||||
simpVals []string
|
||||
compVals []string
|
||||
)
|
||||
vals = make([]sortNode, 0)
|
||||
m := make(map[string]sortNode)
|
||||
|
||||
for k := range t.values {
|
||||
v := t.values[k]
|
||||
switch v.(type) {
|
||||
case *Tree, []*Tree:
|
||||
node = sortNode{key: k, complexity: valueComplex}
|
||||
compVals = append(compVals, node.key)
|
||||
default:
|
||||
node = sortNode{key: k, complexity: valueSimple}
|
||||
simpVals = append(simpVals, node.key)
|
||||
}
|
||||
vals = append(vals, node)
|
||||
m[node.key] = node
|
||||
}
|
||||
|
||||
// Simples first to match previous implementation
|
||||
sort.Strings(simpVals)
|
||||
i := 0
|
||||
for _, key := range simpVals {
|
||||
vals[i] = m[key]
|
||||
i++
|
||||
}
|
||||
|
||||
sort.Strings(compVals)
|
||||
for _, key := range compVals {
|
||||
vals[i] = m[key]
|
||||
i++
|
||||
}
|
||||
|
||||
return vals
|
||||
}
|
||||
|
||||
func (t *Tree) writeTo(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool) (int64, error) {
|
||||
return t.writeToOrdered(w, indent, keyspace, bytesCount, arraysOneElementPerLine, OrderAlphabetical, " ", false, false)
|
||||
}
|
||||
|
||||
func (t *Tree) writeToOrdered(w io.Writer, indent, keyspace string, bytesCount int64, arraysOneElementPerLine bool, ord MarshalOrder, indentString string, compactComments, parentCommented bool) (int64, error) {
|
||||
var orderedVals []sortNode
|
||||
|
||||
switch ord {
|
||||
case OrderPreserve:
|
||||
orderedVals = sortByLines(t)
|
||||
default:
|
||||
orderedVals = sortAlphabetical(t)
|
||||
}
|
||||
|
||||
for _, node := range orderedVals {
|
||||
switch node.complexity {
|
||||
case valueComplex:
|
||||
k := node.key
|
||||
v := t.values[k]
|
||||
|
||||
combinedKey := quoteKeyIfNeeded(k)
|
||||
if keyspace != "" {
|
||||
combinedKey = keyspace + "." + combinedKey
|
||||
}
|
||||
|
||||
switch node := v.(type) {
|
||||
// node has to be of those two types given how keys are sorted above
|
||||
case *Tree:
|
||||
tv, ok := t.values[k].(*Tree)
|
||||
if !ok {
|
||||
return bytesCount, fmt.Errorf("invalid value type at %s: %T", k, t.values[k])
|
||||
}
|
||||
if tv.comment != "" {
|
||||
comment := strings.Replace(tv.comment, "\n", "\n"+indent+"#", -1)
|
||||
start := "# "
|
||||
if strings.HasPrefix(comment, "#") {
|
||||
start = ""
|
||||
}
|
||||
writtenBytesCountComment, errc := writeStrings(w, "\n", indent, start, comment)
|
||||
bytesCount += int64(writtenBytesCountComment)
|
||||
if errc != nil {
|
||||
return bytesCount, errc
|
||||
}
|
||||
}
|
||||
|
||||
var commented string
|
||||
if parentCommented || t.commented || tv.commented {
|
||||
commented = "# "
|
||||
}
|
||||
writtenBytesCount, err := writeStrings(w, "\n", indent, commented, "[", combinedKey, "]\n")
|
||||
bytesCount += int64(writtenBytesCount)
|
||||
if err != nil {
|
||||
return bytesCount, err
|
||||
}
|
||||
bytesCount, err = node.writeToOrdered(w, indent+indentString, combinedKey, bytesCount, arraysOneElementPerLine, ord, indentString, compactComments, parentCommented || t.commented || tv.commented)
|
||||
if err != nil {
|
||||
return bytesCount, err
|
||||
}
|
||||
case []*Tree:
|
||||
for _, subTree := range node {
|
||||
var commented string
|
||||
if parentCommented || t.commented || subTree.commented {
|
||||
commented = "# "
|
||||
}
|
||||
writtenBytesCount, err := writeStrings(w, "\n", indent, commented, "[[", combinedKey, "]]\n")
|
||||
bytesCount += int64(writtenBytesCount)
|
||||
if err != nil {
|
||||
return bytesCount, err
|
||||
}
|
||||
|
||||
bytesCount, err = subTree.writeToOrdered(w, indent+indentString, combinedKey, bytesCount, arraysOneElementPerLine, ord, indentString, compactComments, parentCommented || t.commented || subTree.commented)
|
||||
if err != nil {
|
||||
return bytesCount, err
|
||||
}
|
||||
}
|
||||
}
|
||||
default: // Simple
|
||||
k := node.key
|
||||
v, ok := t.values[k].(*tomlValue)
|
||||
if !ok {
|
||||
return bytesCount, fmt.Errorf("invalid value type at %s: %T", k, t.values[k])
|
||||
}
|
||||
|
||||
var commented string
|
||||
if parentCommented || t.commented || v.commented {
|
||||
commented = "# "
|
||||
}
|
||||
repr, err := tomlValueStringRepresentation(v, commented, indent, ord, arraysOneElementPerLine)
|
||||
if err != nil {
|
||||
return bytesCount, err
|
||||
}
|
||||
|
||||
if v.comment != "" {
|
||||
comment := strings.Replace(v.comment, "\n", "\n"+indent+"#", -1)
|
||||
start := "# "
|
||||
if strings.HasPrefix(comment, "#") {
|
||||
start = ""
|
||||
}
|
||||
if !compactComments {
|
||||
writtenBytesCountComment, errc := writeStrings(w, "\n")
|
||||
bytesCount += int64(writtenBytesCountComment)
|
||||
if errc != nil {
|
||||
return bytesCount, errc
|
||||
}
|
||||
}
|
||||
writtenBytesCountComment, errc := writeStrings(w, indent, start, comment, "\n")
|
||||
bytesCount += int64(writtenBytesCountComment)
|
||||
if errc != nil {
|
||||
return bytesCount, errc
|
||||
}
|
||||
}
|
||||
|
||||
quotedKey := quoteKeyIfNeeded(k)
|
||||
writtenBytesCount, err := writeStrings(w, indent, commented, quotedKey, " = ", repr, "\n")
|
||||
bytesCount += int64(writtenBytesCount)
|
||||
if err != nil {
|
||||
return bytesCount, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bytesCount, nil
|
||||
}
|
||||
|
||||
// quote a key if it does not fit the bare key format (A-Za-z0-9_-)
|
||||
// quoted keys use the same rules as strings
|
||||
func quoteKeyIfNeeded(k string) string {
|
||||
// when encoding a map with the 'quoteMapKeys' option enabled, the tree will contain
|
||||
// keys that have already been quoted.
|
||||
// not an ideal situation, but good enough of a stop gap.
|
||||
if len(k) >= 2 && k[0] == '"' && k[len(k)-1] == '"' {
|
||||
return k
|
||||
}
|
||||
isBare := true
|
||||
for _, r := range k {
|
||||
if !isValidBareChar(r) {
|
||||
isBare = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if isBare {
|
||||
return k
|
||||
}
|
||||
return quoteKey(k)
|
||||
}
|
||||
|
||||
func quoteKey(k string) string {
|
||||
return "\"" + encodeTomlString(k) + "\""
|
||||
}
|
||||
|
||||
func writeStrings(w io.Writer, s ...string) (int, error) {
|
||||
var n int
|
||||
for i := range s {
|
||||
b, err := io.WriteString(w, s[i])
|
||||
n += b
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// WriteTo encode the Tree as Toml and writes it to the writer w.
|
||||
// Returns the number of bytes written in case of success, or an error if anything happened.
|
||||
func (t *Tree) WriteTo(w io.Writer) (int64, error) {
|
||||
return t.writeTo(w, "", "", 0, false)
|
||||
}
|
||||
|
||||
// ToTomlString generates a human-readable representation of the current tree.
|
||||
// Output spans multiple lines, and is suitable for ingest by a TOML parser.
|
||||
// If the conversion cannot be performed, ToString returns a non-nil error.
|
||||
func (t *Tree) ToTomlString() (string, error) {
|
||||
b, err := t.Marshal()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(b), nil
|
||||
}
|
||||
|
||||
// String generates a human-readable representation of the current tree.
|
||||
// Alias of ToString. Present to implement the fmt.Stringer interface.
|
||||
func (t *Tree) String() string {
|
||||
result, _ := t.ToTomlString()
|
||||
return result
|
||||
}
|
||||
|
||||
// ToMap recursively generates a representation of the tree using Go built-in structures.
|
||||
// The following types are used:
|
||||
//
|
||||
// * bool
|
||||
// * float64
|
||||
// * int64
|
||||
// * string
|
||||
// * uint64
|
||||
// * time.Time
|
||||
// * map[string]interface{} (where interface{} is any of this list)
|
||||
// * []interface{} (where interface{} is any of this list)
|
||||
func (t *Tree) ToMap() map[string]interface{} {
|
||||
result := map[string]interface{}{}
|
||||
|
||||
for k, v := range t.values {
|
||||
switch node := v.(type) {
|
||||
case []*Tree:
|
||||
var array []interface{}
|
||||
for _, item := range node {
|
||||
array = append(array, item.ToMap())
|
||||
}
|
||||
result[k] = array
|
||||
case *Tree:
|
||||
result[k] = node.ToMap()
|
||||
case *tomlValue:
|
||||
result[k] = tomlValueToGo(node.value)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func tomlValueToGo(v interface{}) interface{} {
|
||||
if tree, ok := v.(*Tree); ok {
|
||||
return tree.ToMap()
|
||||
}
|
||||
|
||||
rv := reflect.ValueOf(v)
|
||||
|
||||
if rv.Kind() != reflect.Slice {
|
||||
return v
|
||||
}
|
||||
values := make([]interface{}, rv.Len())
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
item := rv.Index(i).Interface()
|
||||
values[i] = tomlValueToGo(item)
|
||||
}
|
||||
return values
|
||||
}
|
||||
6
vendor/github.com/pelletier/go-toml/tomltree_writepub.go
generated
vendored
Normal file
6
vendor/github.com/pelletier/go-toml/tomltree_writepub.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
package toml
|
||||
|
||||
// ValueStringRepresentation transforms an interface{} value into its toml string representation.
|
||||
func ValueStringRepresentation(v interface{}, commented string, indent string, ord MarshalOrder, arraysOneElementPerLine bool) (string, error) {
|
||||
return tomlValueStringRepresentation(v, commented, indent, ord, arraysOneElementPerLine)
|
||||
}
|
||||
4
vendor/github.com/sirupsen/logrus/.gitignore
generated
vendored
Normal file
4
vendor/github.com/sirupsen/logrus/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
logrus
|
||||
vendor
|
||||
|
||||
.idea/
|
||||
40
vendor/github.com/sirupsen/logrus/.golangci.yml
generated
vendored
Normal file
40
vendor/github.com/sirupsen/logrus/.golangci.yml
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
run:
|
||||
# do not run on test files yet
|
||||
tests: false
|
||||
|
||||
# all available settings of specific linters
|
||||
linters-settings:
|
||||
errcheck:
|
||||
# report about not checking of errors in type assetions: `a := b.(MyStruct)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-type-assertions: false
|
||||
|
||||
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
|
||||
# default is false: such cases aren't reported by default.
|
||||
check-blank: false
|
||||
|
||||
lll:
|
||||
line-length: 100
|
||||
tab-width: 4
|
||||
|
||||
prealloc:
|
||||
simple: false
|
||||
range-loops: false
|
||||
for-loops: false
|
||||
|
||||
whitespace:
|
||||
multi-if: false # Enforces newlines (or comments) after every multi-line if statement
|
||||
multi-func: false # Enforces newlines (or comments) after every multi-line function signature
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- megacheck
|
||||
- govet
|
||||
disable:
|
||||
- maligned
|
||||
- prealloc
|
||||
disable-all: false
|
||||
presets:
|
||||
- bugs
|
||||
- unused
|
||||
fast: false
|
||||
15
vendor/github.com/sirupsen/logrus/.travis.yml
generated
vendored
Normal file
15
vendor/github.com/sirupsen/logrus/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
language: go
|
||||
go_import_path: github.com/sirupsen/logrus
|
||||
git:
|
||||
depth: 1
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
go: 1.15.x
|
||||
os: linux
|
||||
install:
|
||||
- ./travis/install.sh
|
||||
script:
|
||||
- cd ci
|
||||
- go run mage.go -v -w ../ crossBuild
|
||||
- go run mage.go -v -w ../ lint
|
||||
- go run mage.go -v -w ../ test
|
||||
259
vendor/github.com/sirupsen/logrus/CHANGELOG.md
generated
vendored
Normal file
259
vendor/github.com/sirupsen/logrus/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,259 @@
|
||||
# 1.8.1
|
||||
Code quality:
|
||||
* move magefile in its own subdir/submodule to remove magefile dependency on logrus consumer
|
||||
* improve timestamp format documentation
|
||||
|
||||
Fixes:
|
||||
* fix race condition on logger hooks
|
||||
|
||||
|
||||
# 1.8.0
|
||||
|
||||
Correct versioning number replacing v1.7.1.
|
||||
|
||||
# 1.7.1
|
||||
|
||||
Beware this release has introduced a new public API and its semver is therefore incorrect.
|
||||
|
||||
Code quality:
|
||||
* use go 1.15 in travis
|
||||
* use magefile as task runner
|
||||
|
||||
Fixes:
|
||||
* small fixes about new go 1.13 error formatting system
|
||||
* Fix for long time race condiction with mutating data hooks
|
||||
|
||||
Features:
|
||||
* build support for zos
|
||||
|
||||
# 1.7.0
|
||||
Fixes:
|
||||
* the dependency toward a windows terminal library has been removed
|
||||
|
||||
Features:
|
||||
* a new buffer pool management API has been added
|
||||
* a set of `<LogLevel>Fn()` functions have been added
|
||||
|
||||
# 1.6.0
|
||||
Fixes:
|
||||
* end of line cleanup
|
||||
* revert the entry concurrency bug fix whic leads to deadlock under some circumstances
|
||||
* update dependency on go-windows-terminal-sequences to fix a crash with go 1.14
|
||||
|
||||
Features:
|
||||
* add an option to the `TextFormatter` to completely disable fields quoting
|
||||
|
||||
# 1.5.0
|
||||
Code quality:
|
||||
* add golangci linter run on travis
|
||||
|
||||
Fixes:
|
||||
* add mutex for hooks concurrent access on `Entry` data
|
||||
* caller function field for go1.14
|
||||
* fix build issue for gopherjs target
|
||||
|
||||
Feature:
|
||||
* add an hooks/writer sub-package whose goal is to split output on different stream depending on the trace level
|
||||
* add a `DisableHTMLEscape` option in the `JSONFormatter`
|
||||
* add `ForceQuote` and `PadLevelText` options in the `TextFormatter`
|
||||
|
||||
# 1.4.2
|
||||
* Fixes build break for plan9, nacl, solaris
|
||||
# 1.4.1
|
||||
This new release introduces:
|
||||
* Enhance TextFormatter to not print caller information when they are empty (#944)
|
||||
* Remove dependency on golang.org/x/crypto (#932, #943)
|
||||
|
||||
Fixes:
|
||||
* Fix Entry.WithContext method to return a copy of the initial entry (#941)
|
||||
|
||||
# 1.4.0
|
||||
This new release introduces:
|
||||
* Add `DeferExitHandler`, similar to `RegisterExitHandler` but prepending the handler to the list of handlers (semantically like `defer`) (#848).
|
||||
* Add `CallerPrettyfier` to `JSONFormatter` and `TextFormatter` (#909, #911)
|
||||
* Add `Entry.WithContext()` and `Entry.Context`, to set a context on entries to be used e.g. in hooks (#919).
|
||||
|
||||
Fixes:
|
||||
* Fix wrong method calls `Logger.Print` and `Logger.Warningln` (#893).
|
||||
* Update `Entry.Logf` to not do string formatting unless the log level is enabled (#903)
|
||||
* Fix infinite recursion on unknown `Level.String()` (#907)
|
||||
* Fix race condition in `getCaller` (#916).
|
||||
|
||||
|
||||
# 1.3.0
|
||||
This new release introduces:
|
||||
* Log, Logf, Logln functions for Logger and Entry that take a Level
|
||||
|
||||
Fixes:
|
||||
* Building prometheus node_exporter on AIX (#840)
|
||||
* Race condition in TextFormatter (#468)
|
||||
* Travis CI import path (#868)
|
||||
* Remove coloured output on Windows (#862)
|
||||
* Pointer to func as field in JSONFormatter (#870)
|
||||
* Properly marshal Levels (#873)
|
||||
|
||||
# 1.2.0
|
||||
This new release introduces:
|
||||
* A new method `SetReportCaller` in the `Logger` to enable the file, line and calling function from which the trace has been issued
|
||||
* A new trace level named `Trace` whose level is below `Debug`
|
||||
* A configurable exit function to be called upon a Fatal trace
|
||||
* The `Level` object now implements `encoding.TextUnmarshaler` interface
|
||||
|
||||
# 1.1.1
|
||||
This is a bug fix release.
|
||||
* fix the build break on Solaris
|
||||
* don't drop a whole trace in JSONFormatter when a field param is a function pointer which can not be serialized
|
||||
|
||||
# 1.1.0
|
||||
This new release introduces:
|
||||
* several fixes:
|
||||
* a fix for a race condition on entry formatting
|
||||
* proper cleanup of previously used entries before putting them back in the pool
|
||||
* the extra new line at the end of message in text formatter has been removed
|
||||
* a new global public API to check if a level is activated: IsLevelEnabled
|
||||
* the following methods have been added to the Logger object
|
||||
* IsLevelEnabled
|
||||
* SetFormatter
|
||||
* SetOutput
|
||||
* ReplaceHooks
|
||||
* introduction of go module
|
||||
* an indent configuration for the json formatter
|
||||
* output colour support for windows
|
||||
* the field sort function is now configurable for text formatter
|
||||
* the CLICOLOR and CLICOLOR\_FORCE environment variable support in text formater
|
||||
|
||||
# 1.0.6
|
||||
|
||||
This new release introduces:
|
||||
* a new api WithTime which allows to easily force the time of the log entry
|
||||
which is mostly useful for logger wrapper
|
||||
* a fix reverting the immutability of the entry given as parameter to the hooks
|
||||
a new configuration field of the json formatter in order to put all the fields
|
||||
in a nested dictionnary
|
||||
* a new SetOutput method in the Logger
|
||||
* a new configuration of the textformatter to configure the name of the default keys
|
||||
* a new configuration of the text formatter to disable the level truncation
|
||||
|
||||
# 1.0.5
|
||||
|
||||
* Fix hooks race (#707)
|
||||
* Fix panic deadlock (#695)
|
||||
|
||||
# 1.0.4
|
||||
|
||||
* Fix race when adding hooks (#612)
|
||||
* Fix terminal check in AppEngine (#635)
|
||||
|
||||
# 1.0.3
|
||||
|
||||
* Replace example files with testable examples
|
||||
|
||||
# 1.0.2
|
||||
|
||||
* bug: quote non-string values in text formatter (#583)
|
||||
* Make (*Logger) SetLevel a public method
|
||||
|
||||
# 1.0.1
|
||||
|
||||
* bug: fix escaping in text formatter (#575)
|
||||
|
||||
# 1.0.0
|
||||
|
||||
* Officially changed name to lower-case
|
||||
* bug: colors on Windows 10 (#541)
|
||||
* bug: fix race in accessing level (#512)
|
||||
|
||||
# 0.11.5
|
||||
|
||||
* feature: add writer and writerlevel to entry (#372)
|
||||
|
||||
# 0.11.4
|
||||
|
||||
* bug: fix undefined variable on solaris (#493)
|
||||
|
||||
# 0.11.3
|
||||
|
||||
* formatter: configure quoting of empty values (#484)
|
||||
* formatter: configure quoting character (default is `"`) (#484)
|
||||
* bug: fix not importing io correctly in non-linux environments (#481)
|
||||
|
||||
# 0.11.2
|
||||
|
||||
* bug: fix windows terminal detection (#476)
|
||||
|
||||
# 0.11.1
|
||||
|
||||
* bug: fix tty detection with custom out (#471)
|
||||
|
||||
# 0.11.0
|
||||
|
||||
* performance: Use bufferpool to allocate (#370)
|
||||
* terminal: terminal detection for app-engine (#343)
|
||||
* feature: exit handler (#375)
|
||||
|
||||
# 0.10.0
|
||||
|
||||
* feature: Add a test hook (#180)
|
||||
* feature: `ParseLevel` is now case-insensitive (#326)
|
||||
* feature: `FieldLogger` interface that generalizes `Logger` and `Entry` (#308)
|
||||
* performance: avoid re-allocations on `WithFields` (#335)
|
||||
|
||||
# 0.9.0
|
||||
|
||||
* logrus/text_formatter: don't emit empty msg
|
||||
* logrus/hooks/airbrake: move out of main repository
|
||||
* logrus/hooks/sentry: move out of main repository
|
||||
* logrus/hooks/papertrail: move out of main repository
|
||||
* logrus/hooks/bugsnag: move out of main repository
|
||||
* logrus/core: run tests with `-race`
|
||||
* logrus/core: detect TTY based on `stderr`
|
||||
* logrus/core: support `WithError` on logger
|
||||
* logrus/core: Solaris support
|
||||
|
||||
# 0.8.7
|
||||
|
||||
* logrus/core: fix possible race (#216)
|
||||
* logrus/doc: small typo fixes and doc improvements
|
||||
|
||||
|
||||
# 0.8.6
|
||||
|
||||
* hooks/raven: allow passing an initialized client
|
||||
|
||||
# 0.8.5
|
||||
|
||||
* logrus/core: revert #208
|
||||
|
||||
# 0.8.4
|
||||
|
||||
* formatter/text: fix data race (#218)
|
||||
|
||||
# 0.8.3
|
||||
|
||||
* logrus/core: fix entry log level (#208)
|
||||
* logrus/core: improve performance of text formatter by 40%
|
||||
* logrus/core: expose `LevelHooks` type
|
||||
* logrus/core: add support for DragonflyBSD and NetBSD
|
||||
* formatter/text: print structs more verbosely
|
||||
|
||||
# 0.8.2
|
||||
|
||||
* logrus: fix more Fatal family functions
|
||||
|
||||
# 0.8.1
|
||||
|
||||
* logrus: fix not exiting on `Fatalf` and `Fatalln`
|
||||
|
||||
# 0.8.0
|
||||
|
||||
* logrus: defaults to stderr instead of stdout
|
||||
* hooks/sentry: add special field for `*http.Request`
|
||||
* formatter/text: ignore Windows for colors
|
||||
|
||||
# 0.7.3
|
||||
|
||||
* formatter/\*: allow configuration of timestamp layout
|
||||
|
||||
# 0.7.2
|
||||
|
||||
* formatter/text: Add configuration option for time format (#158)
|
||||
21
vendor/github.com/sirupsen/logrus/LICENSE
generated
vendored
Normal file
21
vendor/github.com/sirupsen/logrus/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Simon Eskildsen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
513
vendor/github.com/sirupsen/logrus/README.md
generated
vendored
Normal file
513
vendor/github.com/sirupsen/logrus/README.md
generated
vendored
Normal file
@@ -0,0 +1,513 @@
|
||||
# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/> [](https://travis-ci.org/sirupsen/logrus) [](https://godoc.org/github.com/sirupsen/logrus)
|
||||
|
||||
Logrus is a structured logger for Go (golang), completely API compatible with
|
||||
the standard library logger.
|
||||
|
||||
**Logrus is in maintenance-mode.** We will not be introducing new features. It's
|
||||
simply too hard to do in a way that won't break many people's projects, which is
|
||||
the last thing you want from your Logging library (again...).
|
||||
|
||||
This does not mean Logrus is dead. Logrus will continue to be maintained for
|
||||
security, (backwards compatible) bug fixes, and performance (where we are
|
||||
limited by the interface).
|
||||
|
||||
I believe Logrus' biggest contribution is to have played a part in today's
|
||||
widespread use of structured logging in Golang. There doesn't seem to be a
|
||||
reason to do a major, breaking iteration into Logrus V2, since the fantastic Go
|
||||
community has built those independently. Many fantastic alternatives have sprung
|
||||
up. Logrus would look like those, had it been re-designed with what we know
|
||||
about structured logging in Go today. Check out, for example,
|
||||
[Zerolog][zerolog], [Zap][zap], and [Apex][apex].
|
||||
|
||||
[zerolog]: https://github.com/rs/zerolog
|
||||
[zap]: https://github.com/uber-go/zap
|
||||
[apex]: https://github.com/apex/log
|
||||
|
||||
**Seeing weird case-sensitive problems?** It's in the past been possible to
|
||||
import Logrus as both upper- and lower-case. Due to the Go package environment,
|
||||
this caused issues in the community and we needed a standard. Some environments
|
||||
experienced problems with the upper-case variant, so the lower-case was decided.
|
||||
Everything using `logrus` will need to use the lower-case:
|
||||
`github.com/sirupsen/logrus`. Any package that isn't, should be changed.
|
||||
|
||||
To fix Glide, see [these
|
||||
comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437).
|
||||
For an in-depth explanation of the casing issue, see [this
|
||||
comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276).
|
||||
|
||||
Nicely color-coded in development (when a TTY is attached, otherwise just
|
||||
plain text):
|
||||
|
||||

|
||||
|
||||
With `log.SetFormatter(&log.JSONFormatter{})`, for easy parsing by logstash
|
||||
or Splunk:
|
||||
|
||||
```json
|
||||
{"animal":"walrus","level":"info","msg":"A group of walrus emerges from the
|
||||
ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"}
|
||||
|
||||
{"level":"warning","msg":"The group's number increased tremendously!",
|
||||
"number":122,"omg":true,"time":"2014-03-10 19:57:38.562471297 -0400 EDT"}
|
||||
|
||||
{"animal":"walrus","level":"info","msg":"A giant walrus appears!",
|
||||
"size":10,"time":"2014-03-10 19:57:38.562500591 -0400 EDT"}
|
||||
|
||||
{"animal":"walrus","level":"info","msg":"Tremendously sized cow enters the ocean.",
|
||||
"size":9,"time":"2014-03-10 19:57:38.562527896 -0400 EDT"}
|
||||
|
||||
{"level":"fatal","msg":"The ice breaks!","number":100,"omg":true,
|
||||
"time":"2014-03-10 19:57:38.562543128 -0400 EDT"}
|
||||
```
|
||||
|
||||
With the default `log.SetFormatter(&log.TextFormatter{})` when a TTY is not
|
||||
attached, the output is compatible with the
|
||||
[logfmt](http://godoc.org/github.com/kr/logfmt) format:
|
||||
|
||||
```text
|
||||
time="2015-03-26T01:27:38-04:00" level=debug msg="Started observing beach" animal=walrus number=8
|
||||
time="2015-03-26T01:27:38-04:00" level=info msg="A group of walrus emerges from the ocean" animal=walrus size=10
|
||||
time="2015-03-26T01:27:38-04:00" level=warning msg="The group's number increased tremendously!" number=122 omg=true
|
||||
time="2015-03-26T01:27:38-04:00" level=debug msg="Temperature changes" temperature=-4
|
||||
time="2015-03-26T01:27:38-04:00" level=panic msg="It's over 9000!" animal=orca size=9009
|
||||
time="2015-03-26T01:27:38-04:00" level=fatal msg="The ice breaks!" err=&{0x2082280c0 map[animal:orca size:9009] 2015-03-26 01:27:38.441574009 -0400 EDT panic It's over 9000!} number=100 omg=true
|
||||
```
|
||||
To ensure this behaviour even if a TTY is attached, set your formatter as follows:
|
||||
|
||||
```go
|
||||
log.SetFormatter(&log.TextFormatter{
|
||||
DisableColors: true,
|
||||
FullTimestamp: true,
|
||||
})
|
||||
```
|
||||
|
||||
#### Logging Method Name
|
||||
|
||||
If you wish to add the calling method as a field, instruct the logger via:
|
||||
```go
|
||||
log.SetReportCaller(true)
|
||||
```
|
||||
This adds the caller as 'method' like so:
|
||||
|
||||
```json
|
||||
{"animal":"penguin","level":"fatal","method":"github.com/sirupsen/arcticcreatures.migrate","msg":"a penguin swims by",
|
||||
"time":"2014-03-10 19:57:38.562543129 -0400 EDT"}
|
||||
```
|
||||
|
||||
```text
|
||||
time="2015-03-26T01:27:38-04:00" level=fatal method=github.com/sirupsen/arcticcreatures.migrate msg="a penguin swims by" animal=penguin
|
||||
```
|
||||
Note that this does add measurable overhead - the cost will depend on the version of Go, but is
|
||||
between 20 and 40% in recent tests with 1.6 and 1.7. You can validate this in your
|
||||
environment via benchmarks:
|
||||
```
|
||||
go test -bench=.*CallerTracing
|
||||
```
|
||||
|
||||
|
||||
#### Case-sensitivity
|
||||
|
||||
The organization's name was changed to lower-case--and this will not be changed
|
||||
back. If you are getting import conflicts due to case sensitivity, please use
|
||||
the lower-case import: `github.com/sirupsen/logrus`.
|
||||
|
||||
#### Example
|
||||
|
||||
The simplest way to use Logrus is simply the package-level exported logger:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.WithFields(log.Fields{
|
||||
"animal": "walrus",
|
||||
}).Info("A walrus appears")
|
||||
}
|
||||
```
|
||||
|
||||
Note that it's completely api-compatible with the stdlib logger, so you can
|
||||
replace your `log` imports everywhere with `log "github.com/sirupsen/logrus"`
|
||||
and you'll now have the flexibility of Logrus. You can customize it all you
|
||||
want:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Log as JSON instead of the default ASCII formatter.
|
||||
log.SetFormatter(&log.JSONFormatter{})
|
||||
|
||||
// Output to stdout instead of the default stderr
|
||||
// Can be any io.Writer, see below for File example
|
||||
log.SetOutput(os.Stdout)
|
||||
|
||||
// Only log the warning severity or above.
|
||||
log.SetLevel(log.WarnLevel)
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.WithFields(log.Fields{
|
||||
"animal": "walrus",
|
||||
"size": 10,
|
||||
}).Info("A group of walrus emerges from the ocean")
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"omg": true,
|
||||
"number": 122,
|
||||
}).Warn("The group's number increased tremendously!")
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"omg": true,
|
||||
"number": 100,
|
||||
}).Fatal("The ice breaks!")
|
||||
|
||||
// A common pattern is to re-use fields between logging statements by re-using
|
||||
// the logrus.Entry returned from WithFields()
|
||||
contextLogger := log.WithFields(log.Fields{
|
||||
"common": "this is a common field",
|
||||
"other": "I also should be logged always",
|
||||
})
|
||||
|
||||
contextLogger.Info("I'll be logged with common and other field")
|
||||
contextLogger.Info("Me too")
|
||||
}
|
||||
```
|
||||
|
||||
For more advanced usage such as logging to multiple locations from the same
|
||||
application, you can also create an instance of the `logrus` Logger:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Create a new instance of the logger. You can have any number of instances.
|
||||
var log = logrus.New()
|
||||
|
||||
func main() {
|
||||
// The API for setting attributes is a little different than the package level
|
||||
// exported logger. See Godoc.
|
||||
log.Out = os.Stdout
|
||||
|
||||
// You could set this to any `io.Writer` such as a file
|
||||
// file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
// if err == nil {
|
||||
// log.Out = file
|
||||
// } else {
|
||||
// log.Info("Failed to log to file, using default stderr")
|
||||
// }
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"animal": "walrus",
|
||||
"size": 10,
|
||||
}).Info("A group of walrus emerges from the ocean")
|
||||
}
|
||||
```
|
||||
|
||||
#### Fields
|
||||
|
||||
Logrus encourages careful, structured logging through logging fields instead of
|
||||
long, unparseable error messages. For example, instead of: `log.Fatalf("Failed
|
||||
to send event %s to topic %s with key %d")`, you should log the much more
|
||||
discoverable:
|
||||
|
||||
```go
|
||||
log.WithFields(log.Fields{
|
||||
"event": event,
|
||||
"topic": topic,
|
||||
"key": key,
|
||||
}).Fatal("Failed to send event")
|
||||
```
|
||||
|
||||
We've found this API forces you to think about logging in a way that produces
|
||||
much more useful logging messages. We've been in countless situations where just
|
||||
a single added field to a log statement that was already there would've saved us
|
||||
hours. The `WithFields` call is optional.
|
||||
|
||||
In general, with Logrus using any of the `printf`-family functions should be
|
||||
seen as a hint you should add a field, however, you can still use the
|
||||
`printf`-family functions with Logrus.
|
||||
|
||||
#### Default Fields
|
||||
|
||||
Often it's helpful to have fields _always_ attached to log statements in an
|
||||
application or parts of one. For example, you may want to always log the
|
||||
`request_id` and `user_ip` in the context of a request. Instead of writing
|
||||
`log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})` on
|
||||
every line, you can create a `logrus.Entry` to pass around instead:
|
||||
|
||||
```go
|
||||
requestLogger := log.WithFields(log.Fields{"request_id": request_id, "user_ip": user_ip})
|
||||
requestLogger.Info("something happened on that request") # will log request_id and user_ip
|
||||
requestLogger.Warn("something not great happened")
|
||||
```
|
||||
|
||||
#### Hooks
|
||||
|
||||
You can add hooks for logging levels. For example to send errors to an exception
|
||||
tracking service on `Error`, `Fatal` and `Panic`, info to StatsD or log to
|
||||
multiple places simultaneously, e.g. syslog.
|
||||
|
||||
Logrus comes with [built-in hooks](hooks/). Add those, or your custom hook, in
|
||||
`init`:
|
||||
|
||||
```go
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gopkg.in/gemnasium/logrus-airbrake-hook.v2" // the package is named "airbrake"
|
||||
logrus_syslog "github.com/sirupsen/logrus/hooks/syslog"
|
||||
"log/syslog"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
// Use the Airbrake hook to report errors that have Error severity or above to
|
||||
// an exception tracker. You can create custom hooks, see the Hooks section.
|
||||
log.AddHook(airbrake.NewHook(123, "xyz", "production"))
|
||||
|
||||
hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "")
|
||||
if err != nil {
|
||||
log.Error("Unable to connect to local syslog daemon")
|
||||
} else {
|
||||
log.AddHook(hook)
|
||||
}
|
||||
}
|
||||
```
|
||||
Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md).
|
||||
|
||||
A list of currently known service hooks can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks)
|
||||
|
||||
|
||||
#### Level logging
|
||||
|
||||
Logrus has seven logging levels: Trace, Debug, Info, Warning, Error, Fatal and Panic.
|
||||
|
||||
```go
|
||||
log.Trace("Something very low level.")
|
||||
log.Debug("Useful debugging information.")
|
||||
log.Info("Something noteworthy happened!")
|
||||
log.Warn("You should probably take a look at this.")
|
||||
log.Error("Something failed but I'm not quitting.")
|
||||
// Calls os.Exit(1) after logging
|
||||
log.Fatal("Bye.")
|
||||
// Calls panic() after logging
|
||||
log.Panic("I'm bailing.")
|
||||
```
|
||||
|
||||
You can set the logging level on a `Logger`, then it will only log entries with
|
||||
that severity or anything above it:
|
||||
|
||||
```go
|
||||
// Will log anything that is info or above (warn, error, fatal, panic). Default.
|
||||
log.SetLevel(log.InfoLevel)
|
||||
```
|
||||
|
||||
It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose
|
||||
environment if your application has that.
|
||||
|
||||
#### Entries
|
||||
|
||||
Besides the fields added with `WithField` or `WithFields` some fields are
|
||||
automatically added to all logging events:
|
||||
|
||||
1. `time`. The timestamp when the entry was created.
|
||||
2. `msg`. The logging message passed to `{Info,Warn,Error,Fatal,Panic}` after
|
||||
the `AddFields` call. E.g. `Failed to send event.`
|
||||
3. `level`. The logging level. E.g. `info`.
|
||||
|
||||
#### Environments
|
||||
|
||||
Logrus has no notion of environment.
|
||||
|
||||
If you wish for hooks and formatters to only be used in specific environments,
|
||||
you should handle that yourself. For example, if your application has a global
|
||||
variable `Environment`, which is a string representation of the environment you
|
||||
could do:
|
||||
|
||||
```go
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
init() {
|
||||
// do something here to set environment depending on an environment variable
|
||||
// or command-line flag
|
||||
if Environment == "production" {
|
||||
log.SetFormatter(&log.JSONFormatter{})
|
||||
} else {
|
||||
// The TextFormatter is default, you don't actually have to do this.
|
||||
log.SetFormatter(&log.TextFormatter{})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This configuration is how `logrus` was intended to be used, but JSON in
|
||||
production is mostly only useful if you do log aggregation with tools like
|
||||
Splunk or Logstash.
|
||||
|
||||
#### Formatters
|
||||
|
||||
The built-in logging formatters are:
|
||||
|
||||
* `logrus.TextFormatter`. Logs the event in colors if stdout is a tty, otherwise
|
||||
without colors.
|
||||
* *Note:* to force colored output when there is no TTY, set the `ForceColors`
|
||||
field to `true`. To force no colored output even if there is a TTY set the
|
||||
`DisableColors` field to `true`. For Windows, see
|
||||
[github.com/mattn/go-colorable](https://github.com/mattn/go-colorable).
|
||||
* When colors are enabled, levels are truncated to 4 characters by default. To disable
|
||||
truncation set the `DisableLevelTruncation` field to `true`.
|
||||
* When outputting to a TTY, it's often helpful to visually scan down a column where all the levels are the same width. Setting the `PadLevelText` field to `true` enables this behavior, by adding padding to the level text.
|
||||
* All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter).
|
||||
* `logrus.JSONFormatter`. Logs fields as JSON.
|
||||
* All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter).
|
||||
|
||||
Third party logging formatters:
|
||||
|
||||
* [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can be parsed by Kubernetes and Google Container Engine.
|
||||
* [`GELF`](https://github.com/fabienm/go-logrus-formatters). Formats entries so they comply to Graylog's [GELF 1.1 specification](http://docs.graylog.org/en/2.4/pages/gelf.html).
|
||||
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
|
||||
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
|
||||
* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the Power of Zalgo.
|
||||
* [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure.
|
||||
* [`powerful-logrus-formatter`](https://github.com/zput/zxcTool). get fileName, log's line number and the latest function's name when print log; Sava log to files.
|
||||
* [`caption-json-formatter`](https://github.com/nolleh/caption_json_formatter). logrus's message json formatter with human-readable caption added.
|
||||
|
||||
You can define your formatter by implementing the `Formatter` interface,
|
||||
requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a
|
||||
`Fields` type (`map[string]interface{}`) with all your fields as well as the
|
||||
default ones (see Entries section above):
|
||||
|
||||
```go
|
||||
type MyJSONFormatter struct {
|
||||
}
|
||||
|
||||
log.SetFormatter(new(MyJSONFormatter))
|
||||
|
||||
func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
// Note this doesn't include Time, Level and Message which are available on
|
||||
// the Entry. Consult `godoc` on information about those fields or read the
|
||||
// source of the official loggers.
|
||||
serialized, err := json.Marshal(entry.Data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to marshal fields to JSON, %w", err)
|
||||
}
|
||||
return append(serialized, '\n'), nil
|
||||
}
|
||||
```
|
||||
|
||||
#### Logger as an `io.Writer`
|
||||
|
||||
Logrus can be transformed into an `io.Writer`. That writer is the end of an `io.Pipe` and it is your responsibility to close it.
|
||||
|
||||
```go
|
||||
w := logger.Writer()
|
||||
defer w.Close()
|
||||
|
||||
srv := http.Server{
|
||||
// create a stdlib log.Logger that writes to
|
||||
// logrus.Logger.
|
||||
ErrorLog: log.New(w, "", 0),
|
||||
}
|
||||
```
|
||||
|
||||
Each line written to that writer will be printed the usual way, using formatters
|
||||
and hooks. The level for those entries is `info`.
|
||||
|
||||
This means that we can override the standard library logger easily:
|
||||
|
||||
```go
|
||||
logger := logrus.New()
|
||||
logger.Formatter = &logrus.JSONFormatter{}
|
||||
|
||||
// Use logrus for standard log output
|
||||
// Note that `log` here references stdlib's log
|
||||
// Not logrus imported under the name `log`.
|
||||
log.SetOutput(logger.Writer())
|
||||
```
|
||||
|
||||
#### Rotation
|
||||
|
||||
Log rotation is not provided with Logrus. Log rotation should be done by an
|
||||
external program (like `logrotate(8)`) that can compress and delete old log
|
||||
entries. It should not be a feature of the application-level logger.
|
||||
|
||||
#### Tools
|
||||
|
||||
| Tool | Description |
|
||||
| ---- | ----------- |
|
||||
|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will be generated with different configs in different environments.|
|
||||
|[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper around Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) |
|
||||
|
||||
#### Testing
|
||||
|
||||
Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides:
|
||||
|
||||
* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just adds the `test` hook
|
||||
* a test logger (`test.NewNullLogger`) that just records log messages (and does not output any):
|
||||
|
||||
```go
|
||||
import(
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus/hooks/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSomething(t*testing.T){
|
||||
logger, hook := test.NewNullLogger()
|
||||
logger.Error("Helloerror")
|
||||
|
||||
assert.Equal(t, 1, len(hook.Entries))
|
||||
assert.Equal(t, logrus.ErrorLevel, hook.LastEntry().Level)
|
||||
assert.Equal(t, "Helloerror", hook.LastEntry().Message)
|
||||
|
||||
hook.Reset()
|
||||
assert.Nil(t, hook.LastEntry())
|
||||
}
|
||||
```
|
||||
|
||||
#### Fatal handlers
|
||||
|
||||
Logrus can register one or more functions that will be called when any `fatal`
|
||||
level message is logged. The registered handlers will be executed before
|
||||
logrus performs an `os.Exit(1)`. This behavior may be helpful if callers need
|
||||
to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted.
|
||||
|
||||
```
|
||||
...
|
||||
handler := func() {
|
||||
// gracefully shutdown something...
|
||||
}
|
||||
logrus.RegisterExitHandler(handler)
|
||||
...
|
||||
```
|
||||
|
||||
#### Thread safety
|
||||
|
||||
By default, Logger is protected by a mutex for concurrent writes. The mutex is held when calling hooks and writing logs.
|
||||
If you are sure such locking is not needed, you can call logger.SetNoLock() to disable the locking.
|
||||
|
||||
Situation when locking is not needed includes:
|
||||
|
||||
* You have no hooks registered, or hooks calling is already thread-safe.
|
||||
|
||||
* Writing to logger.Out is already thread-safe, for example:
|
||||
|
||||
1) logger.Out is protected by locks.
|
||||
|
||||
2) logger.Out is an os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allows multi-thread/multi-process writing)
|
||||
|
||||
(Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/)
|
||||
76
vendor/github.com/sirupsen/logrus/alt_exit.go
generated
vendored
Normal file
76
vendor/github.com/sirupsen/logrus/alt_exit.go
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
package logrus
|
||||
|
||||
// The following code was sourced and modified from the
|
||||
// https://github.com/tebeka/atexit package governed by the following license:
|
||||
//
|
||||
// Copyright (c) 2012 Miki Tebeka <miki.tebeka@gmail.com>.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
// this software and associated documentation files (the "Software"), to deal in
|
||||
// the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
// subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
var handlers = []func(){}
|
||||
|
||||
func runHandler(handler func()) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Error: Logrus exit handler error:", err)
|
||||
}
|
||||
}()
|
||||
|
||||
handler()
|
||||
}
|
||||
|
||||
func runHandlers() {
|
||||
for _, handler := range handlers {
|
||||
runHandler(handler)
|
||||
}
|
||||
}
|
||||
|
||||
// Exit runs all the Logrus atexit handlers and then terminates the program using os.Exit(code)
|
||||
func Exit(code int) {
|
||||
runHandlers()
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// RegisterExitHandler appends a Logrus Exit handler to the list of handlers,
|
||||
// call logrus.Exit to invoke all handlers. The handlers will also be invoked when
|
||||
// any Fatal log entry is made.
|
||||
//
|
||||
// This method is useful when a caller wishes to use logrus to log a fatal
|
||||
// message but also needs to gracefully shutdown. An example usecase could be
|
||||
// closing database connections, or sending a alert that the application is
|
||||
// closing.
|
||||
func RegisterExitHandler(handler func()) {
|
||||
handlers = append(handlers, handler)
|
||||
}
|
||||
|
||||
// DeferExitHandler prepends a Logrus Exit handler to the list of handlers,
|
||||
// call logrus.Exit to invoke all handlers. The handlers will also be invoked when
|
||||
// any Fatal log entry is made.
|
||||
//
|
||||
// This method is useful when a caller wishes to use logrus to log a fatal
|
||||
// message but also needs to gracefully shutdown. An example usecase could be
|
||||
// closing database connections, or sending a alert that the application is
|
||||
// closing.
|
||||
func DeferExitHandler(handler func()) {
|
||||
handlers = append([]func(){handler}, handlers...)
|
||||
}
|
||||
14
vendor/github.com/sirupsen/logrus/appveyor.yml
generated
vendored
Normal file
14
vendor/github.com/sirupsen/logrus/appveyor.yml
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
version: "{build}"
|
||||
platform: x64
|
||||
clone_folder: c:\gopath\src\github.com\sirupsen\logrus
|
||||
environment:
|
||||
GOPATH: c:\gopath
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
install:
|
||||
- set PATH=%GOPATH%\bin;c:\go\bin;%PATH%
|
||||
- go version
|
||||
build_script:
|
||||
- go get -t
|
||||
- go test
|
||||
52
vendor/github.com/sirupsen/logrus/buffer_pool.go
generated
vendored
Normal file
52
vendor/github.com/sirupsen/logrus/buffer_pool.go
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
bufferPool BufferPool
|
||||
)
|
||||
|
||||
type BufferPool interface {
|
||||
Put(*bytes.Buffer)
|
||||
Get() *bytes.Buffer
|
||||
}
|
||||
|
||||
type defaultPool struct {
|
||||
pool *sync.Pool
|
||||
}
|
||||
|
||||
func (p *defaultPool) Put(buf *bytes.Buffer) {
|
||||
p.pool.Put(buf)
|
||||
}
|
||||
|
||||
func (p *defaultPool) Get() *bytes.Buffer {
|
||||
return p.pool.Get().(*bytes.Buffer)
|
||||
}
|
||||
|
||||
func getBuffer() *bytes.Buffer {
|
||||
return bufferPool.Get()
|
||||
}
|
||||
|
||||
func putBuffer(buf *bytes.Buffer) {
|
||||
buf.Reset()
|
||||
bufferPool.Put(buf)
|
||||
}
|
||||
|
||||
// SetBufferPool allows to replace the default logrus buffer pool
|
||||
// to better meets the specific needs of an application.
|
||||
func SetBufferPool(bp BufferPool) {
|
||||
bufferPool = bp
|
||||
}
|
||||
|
||||
func init() {
|
||||
SetBufferPool(&defaultPool{
|
||||
pool: &sync.Pool{
|
||||
New: func() interface{} {
|
||||
return new(bytes.Buffer)
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
26
vendor/github.com/sirupsen/logrus/doc.go
generated
vendored
Normal file
26
vendor/github.com/sirupsen/logrus/doc.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
Package logrus is a structured logger for Go, completely API compatible with the standard library logger.
|
||||
|
||||
|
||||
The simplest way to use Logrus is simply the package-level exported logger:
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func main() {
|
||||
log.WithFields(log.Fields{
|
||||
"animal": "walrus",
|
||||
"number": 1,
|
||||
"size": 10,
|
||||
}).Info("A walrus appears")
|
||||
}
|
||||
|
||||
Output:
|
||||
time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10
|
||||
|
||||
For a full guide visit https://github.com/sirupsen/logrus
|
||||
*/
|
||||
package logrus
|
||||
431
vendor/github.com/sirupsen/logrus/entry.go
generated
vendored
Normal file
431
vendor/github.com/sirupsen/logrus/entry.go
generated
vendored
Normal file
@@ -0,0 +1,431 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
// qualified package name, cached at first use
|
||||
logrusPackage string
|
||||
|
||||
// Positions in the call stack when tracing to report the calling method
|
||||
minimumCallerDepth int
|
||||
|
||||
// Used for caller information initialisation
|
||||
callerInitOnce sync.Once
|
||||
)
|
||||
|
||||
const (
|
||||
maximumCallerDepth int = 25
|
||||
knownLogrusFrames int = 4
|
||||
)
|
||||
|
||||
func init() {
|
||||
// start at the bottom of the stack before the package-name cache is primed
|
||||
minimumCallerDepth = 1
|
||||
}
|
||||
|
||||
// Defines the key when adding errors using WithError.
|
||||
var ErrorKey = "error"
|
||||
|
||||
// An entry is the final or intermediate Logrus logging entry. It contains all
|
||||
// the fields passed with WithField{,s}. It's finally logged when Trace, Debug,
|
||||
// Info, Warn, Error, Fatal or Panic is called on it. These objects can be
|
||||
// reused and passed around as much as you wish to avoid field duplication.
|
||||
type Entry struct {
|
||||
Logger *Logger
|
||||
|
||||
// Contains all the fields set by the user.
|
||||
Data Fields
|
||||
|
||||
// Time at which the log entry was created
|
||||
Time time.Time
|
||||
|
||||
// Level the log entry was logged at: Trace, Debug, Info, Warn, Error, Fatal or Panic
|
||||
// This field will be set on entry firing and the value will be equal to the one in Logger struct field.
|
||||
Level Level
|
||||
|
||||
// Calling method, with package name
|
||||
Caller *runtime.Frame
|
||||
|
||||
// Message passed to Trace, Debug, Info, Warn, Error, Fatal or Panic
|
||||
Message string
|
||||
|
||||
// When formatter is called in entry.log(), a Buffer may be set to entry
|
||||
Buffer *bytes.Buffer
|
||||
|
||||
// Contains the context set by the user. Useful for hook processing etc.
|
||||
Context context.Context
|
||||
|
||||
// err may contain a field formatting error
|
||||
err string
|
||||
}
|
||||
|
||||
func NewEntry(logger *Logger) *Entry {
|
||||
return &Entry{
|
||||
Logger: logger,
|
||||
// Default is three fields, plus one optional. Give a little extra room.
|
||||
Data: make(Fields, 6),
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Dup() *Entry {
|
||||
data := make(Fields, len(entry.Data))
|
||||
for k, v := range entry.Data {
|
||||
data[k] = v
|
||||
}
|
||||
return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, Context: entry.Context, err: entry.err}
|
||||
}
|
||||
|
||||
// Returns the bytes representation of this entry from the formatter.
|
||||
func (entry *Entry) Bytes() ([]byte, error) {
|
||||
return entry.Logger.Formatter.Format(entry)
|
||||
}
|
||||
|
||||
// Returns the string representation from the reader and ultimately the
|
||||
// formatter.
|
||||
func (entry *Entry) String() (string, error) {
|
||||
serialized, err := entry.Bytes()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
str := string(serialized)
|
||||
return str, nil
|
||||
}
|
||||
|
||||
// Add an error as single field (using the key defined in ErrorKey) to the Entry.
|
||||
func (entry *Entry) WithError(err error) *Entry {
|
||||
return entry.WithField(ErrorKey, err)
|
||||
}
|
||||
|
||||
// Add a context to the Entry.
|
||||
func (entry *Entry) WithContext(ctx context.Context) *Entry {
|
||||
dataCopy := make(Fields, len(entry.Data))
|
||||
for k, v := range entry.Data {
|
||||
dataCopy[k] = v
|
||||
}
|
||||
return &Entry{Logger: entry.Logger, Data: dataCopy, Time: entry.Time, err: entry.err, Context: ctx}
|
||||
}
|
||||
|
||||
// Add a single field to the Entry.
|
||||
func (entry *Entry) WithField(key string, value interface{}) *Entry {
|
||||
return entry.WithFields(Fields{key: value})
|
||||
}
|
||||
|
||||
// Add a map of fields to the Entry.
|
||||
func (entry *Entry) WithFields(fields Fields) *Entry {
|
||||
data := make(Fields, len(entry.Data)+len(fields))
|
||||
for k, v := range entry.Data {
|
||||
data[k] = v
|
||||
}
|
||||
fieldErr := entry.err
|
||||
for k, v := range fields {
|
||||
isErrField := false
|
||||
if t := reflect.TypeOf(v); t != nil {
|
||||
switch {
|
||||
case t.Kind() == reflect.Func, t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Func:
|
||||
isErrField = true
|
||||
}
|
||||
}
|
||||
if isErrField {
|
||||
tmp := fmt.Sprintf("can not add field %q", k)
|
||||
if fieldErr != "" {
|
||||
fieldErr = entry.err + ", " + tmp
|
||||
} else {
|
||||
fieldErr = tmp
|
||||
}
|
||||
} else {
|
||||
data[k] = v
|
||||
}
|
||||
}
|
||||
return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, err: fieldErr, Context: entry.Context}
|
||||
}
|
||||
|
||||
// Overrides the time of the Entry.
|
||||
func (entry *Entry) WithTime(t time.Time) *Entry {
|
||||
dataCopy := make(Fields, len(entry.Data))
|
||||
for k, v := range entry.Data {
|
||||
dataCopy[k] = v
|
||||
}
|
||||
return &Entry{Logger: entry.Logger, Data: dataCopy, Time: t, err: entry.err, Context: entry.Context}
|
||||
}
|
||||
|
||||
// getPackageName reduces a fully qualified function name to the package name
|
||||
// There really ought to be to be a better way...
|
||||
func getPackageName(f string) string {
|
||||
for {
|
||||
lastPeriod := strings.LastIndex(f, ".")
|
||||
lastSlash := strings.LastIndex(f, "/")
|
||||
if lastPeriod > lastSlash {
|
||||
f = f[:lastPeriod]
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
// getCaller retrieves the name of the first non-logrus calling function
|
||||
func getCaller() *runtime.Frame {
|
||||
// cache this package's fully-qualified name
|
||||
callerInitOnce.Do(func() {
|
||||
pcs := make([]uintptr, maximumCallerDepth)
|
||||
_ = runtime.Callers(0, pcs)
|
||||
|
||||
// dynamic get the package name and the minimum caller depth
|
||||
for i := 0; i < maximumCallerDepth; i++ {
|
||||
funcName := runtime.FuncForPC(pcs[i]).Name()
|
||||
if strings.Contains(funcName, "getCaller") {
|
||||
logrusPackage = getPackageName(funcName)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
minimumCallerDepth = knownLogrusFrames
|
||||
})
|
||||
|
||||
// Restrict the lookback frames to avoid runaway lookups
|
||||
pcs := make([]uintptr, maximumCallerDepth)
|
||||
depth := runtime.Callers(minimumCallerDepth, pcs)
|
||||
frames := runtime.CallersFrames(pcs[:depth])
|
||||
|
||||
for f, again := frames.Next(); again; f, again = frames.Next() {
|
||||
pkg := getPackageName(f.Function)
|
||||
|
||||
// If the caller isn't part of this package, we're done
|
||||
if pkg != logrusPackage {
|
||||
return &f //nolint:scopelint
|
||||
}
|
||||
}
|
||||
|
||||
// if we got here, we failed to find the caller's context
|
||||
return nil
|
||||
}
|
||||
|
||||
func (entry Entry) HasCaller() (has bool) {
|
||||
return entry.Logger != nil &&
|
||||
entry.Logger.ReportCaller &&
|
||||
entry.Caller != nil
|
||||
}
|
||||
|
||||
func (entry *Entry) log(level Level, msg string) {
|
||||
var buffer *bytes.Buffer
|
||||
|
||||
newEntry := entry.Dup()
|
||||
|
||||
if newEntry.Time.IsZero() {
|
||||
newEntry.Time = time.Now()
|
||||
}
|
||||
|
||||
newEntry.Level = level
|
||||
newEntry.Message = msg
|
||||
|
||||
newEntry.Logger.mu.Lock()
|
||||
reportCaller := newEntry.Logger.ReportCaller
|
||||
newEntry.Logger.mu.Unlock()
|
||||
|
||||
if reportCaller {
|
||||
newEntry.Caller = getCaller()
|
||||
}
|
||||
|
||||
newEntry.fireHooks()
|
||||
|
||||
buffer = getBuffer()
|
||||
defer func() {
|
||||
newEntry.Buffer = nil
|
||||
putBuffer(buffer)
|
||||
}()
|
||||
buffer.Reset()
|
||||
newEntry.Buffer = buffer
|
||||
|
||||
newEntry.write()
|
||||
|
||||
newEntry.Buffer = nil
|
||||
|
||||
// To avoid Entry#log() returning a value that only would make sense for
|
||||
// panic() to use in Entry#Panic(), we avoid the allocation by checking
|
||||
// directly here.
|
||||
if level <= PanicLevel {
|
||||
panic(newEntry)
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) fireHooks() {
|
||||
var tmpHooks LevelHooks
|
||||
entry.Logger.mu.Lock()
|
||||
tmpHooks = make(LevelHooks, len(entry.Logger.Hooks))
|
||||
for k, v := range entry.Logger.Hooks {
|
||||
tmpHooks[k] = v
|
||||
}
|
||||
entry.Logger.mu.Unlock()
|
||||
|
||||
err := tmpHooks.Fire(entry.Level, entry)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) write() {
|
||||
serialized, err := entry.Logger.Formatter.Format(entry)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err)
|
||||
return
|
||||
}
|
||||
entry.Logger.mu.Lock()
|
||||
defer entry.Logger.mu.Unlock()
|
||||
if _, err := entry.Logger.Out.Write(serialized); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Log(level Level, args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(level) {
|
||||
entry.log(level, fmt.Sprint(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Trace(args ...interface{}) {
|
||||
entry.Log(TraceLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Debug(args ...interface{}) {
|
||||
entry.Log(DebugLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Print(args ...interface{}) {
|
||||
entry.Info(args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Info(args ...interface{}) {
|
||||
entry.Log(InfoLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warn(args ...interface{}) {
|
||||
entry.Log(WarnLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warning(args ...interface{}) {
|
||||
entry.Warn(args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Error(args ...interface{}) {
|
||||
entry.Log(ErrorLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Fatal(args ...interface{}) {
|
||||
entry.Log(FatalLevel, args...)
|
||||
entry.Logger.Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panic(args ...interface{}) {
|
||||
entry.Log(PanicLevel, args...)
|
||||
}
|
||||
|
||||
// Entry Printf family functions
|
||||
|
||||
func (entry *Entry) Logf(level Level, format string, args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(level) {
|
||||
entry.Log(level, fmt.Sprintf(format, args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Tracef(format string, args ...interface{}) {
|
||||
entry.Logf(TraceLevel, format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Debugf(format string, args ...interface{}) {
|
||||
entry.Logf(DebugLevel, format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Infof(format string, args ...interface{}) {
|
||||
entry.Logf(InfoLevel, format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Printf(format string, args ...interface{}) {
|
||||
entry.Infof(format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warnf(format string, args ...interface{}) {
|
||||
entry.Logf(WarnLevel, format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warningf(format string, args ...interface{}) {
|
||||
entry.Warnf(format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Errorf(format string, args ...interface{}) {
|
||||
entry.Logf(ErrorLevel, format, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Fatalf(format string, args ...interface{}) {
|
||||
entry.Logf(FatalLevel, format, args...)
|
||||
entry.Logger.Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panicf(format string, args ...interface{}) {
|
||||
entry.Logf(PanicLevel, format, args...)
|
||||
}
|
||||
|
||||
// Entry Println family functions
|
||||
|
||||
func (entry *Entry) Logln(level Level, args ...interface{}) {
|
||||
if entry.Logger.IsLevelEnabled(level) {
|
||||
entry.Log(level, entry.sprintlnn(args...))
|
||||
}
|
||||
}
|
||||
|
||||
func (entry *Entry) Traceln(args ...interface{}) {
|
||||
entry.Logln(TraceLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Debugln(args ...interface{}) {
|
||||
entry.Logln(DebugLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Infoln(args ...interface{}) {
|
||||
entry.Logln(InfoLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Println(args ...interface{}) {
|
||||
entry.Infoln(args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warnln(args ...interface{}) {
|
||||
entry.Logln(WarnLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Warningln(args ...interface{}) {
|
||||
entry.Warnln(args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Errorln(args ...interface{}) {
|
||||
entry.Logln(ErrorLevel, args...)
|
||||
}
|
||||
|
||||
func (entry *Entry) Fatalln(args ...interface{}) {
|
||||
entry.Logln(FatalLevel, args...)
|
||||
entry.Logger.Exit(1)
|
||||
}
|
||||
|
||||
func (entry *Entry) Panicln(args ...interface{}) {
|
||||
entry.Logln(PanicLevel, args...)
|
||||
}
|
||||
|
||||
// Sprintlnn => Sprint no newline. This is to get the behavior of how
|
||||
// fmt.Sprintln where spaces are always added between operands, regardless of
|
||||
// their type. Instead of vendoring the Sprintln implementation to spare a
|
||||
// string allocation, we do the simplest thing.
|
||||
func (entry *Entry) sprintlnn(args ...interface{}) string {
|
||||
msg := fmt.Sprintln(args...)
|
||||
return msg[:len(msg)-1]
|
||||
}
|
||||
270
vendor/github.com/sirupsen/logrus/exported.go
generated
vendored
Normal file
270
vendor/github.com/sirupsen/logrus/exported.go
generated
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
// std is the name of the standard logger in stdlib `log`
|
||||
std = New()
|
||||
)
|
||||
|
||||
func StandardLogger() *Logger {
|
||||
return std
|
||||
}
|
||||
|
||||
// SetOutput sets the standard logger output.
|
||||
func SetOutput(out io.Writer) {
|
||||
std.SetOutput(out)
|
||||
}
|
||||
|
||||
// SetFormatter sets the standard logger formatter.
|
||||
func SetFormatter(formatter Formatter) {
|
||||
std.SetFormatter(formatter)
|
||||
}
|
||||
|
||||
// SetReportCaller sets whether the standard logger will include the calling
|
||||
// method as a field.
|
||||
func SetReportCaller(include bool) {
|
||||
std.SetReportCaller(include)
|
||||
}
|
||||
|
||||
// SetLevel sets the standard logger level.
|
||||
func SetLevel(level Level) {
|
||||
std.SetLevel(level)
|
||||
}
|
||||
|
||||
// GetLevel returns the standard logger level.
|
||||
func GetLevel() Level {
|
||||
return std.GetLevel()
|
||||
}
|
||||
|
||||
// IsLevelEnabled checks if the log level of the standard logger is greater than the level param
|
||||
func IsLevelEnabled(level Level) bool {
|
||||
return std.IsLevelEnabled(level)
|
||||
}
|
||||
|
||||
// AddHook adds a hook to the standard logger hooks.
|
||||
func AddHook(hook Hook) {
|
||||
std.AddHook(hook)
|
||||
}
|
||||
|
||||
// WithError creates an entry from the standard logger and adds an error to it, using the value defined in ErrorKey as key.
|
||||
func WithError(err error) *Entry {
|
||||
return std.WithField(ErrorKey, err)
|
||||
}
|
||||
|
||||
// WithContext creates an entry from the standard logger and adds a context to it.
|
||||
func WithContext(ctx context.Context) *Entry {
|
||||
return std.WithContext(ctx)
|
||||
}
|
||||
|
||||
// WithField creates an entry from the standard logger and adds a field to
|
||||
// it. If you want multiple fields, use `WithFields`.
|
||||
//
|
||||
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
|
||||
// or Panic on the Entry it returns.
|
||||
func WithField(key string, value interface{}) *Entry {
|
||||
return std.WithField(key, value)
|
||||
}
|
||||
|
||||
// WithFields creates an entry from the standard logger and adds multiple
|
||||
// fields to it. This is simply a helper for `WithField`, invoking it
|
||||
// once for each field.
|
||||
//
|
||||
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
|
||||
// or Panic on the Entry it returns.
|
||||
func WithFields(fields Fields) *Entry {
|
||||
return std.WithFields(fields)
|
||||
}
|
||||
|
||||
// WithTime creates an entry from the standard logger and overrides the time of
|
||||
// logs generated with it.
|
||||
//
|
||||
// Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal
|
||||
// or Panic on the Entry it returns.
|
||||
func WithTime(t time.Time) *Entry {
|
||||
return std.WithTime(t)
|
||||
}
|
||||
|
||||
// Trace logs a message at level Trace on the standard logger.
|
||||
func Trace(args ...interface{}) {
|
||||
std.Trace(args...)
|
||||
}
|
||||
|
||||
// Debug logs a message at level Debug on the standard logger.
|
||||
func Debug(args ...interface{}) {
|
||||
std.Debug(args...)
|
||||
}
|
||||
|
||||
// Print logs a message at level Info on the standard logger.
|
||||
func Print(args ...interface{}) {
|
||||
std.Print(args...)
|
||||
}
|
||||
|
||||
// Info logs a message at level Info on the standard logger.
|
||||
func Info(args ...interface{}) {
|
||||
std.Info(args...)
|
||||
}
|
||||
|
||||
// Warn logs a message at level Warn on the standard logger.
|
||||
func Warn(args ...interface{}) {
|
||||
std.Warn(args...)
|
||||
}
|
||||
|
||||
// Warning logs a message at level Warn on the standard logger.
|
||||
func Warning(args ...interface{}) {
|
||||
std.Warning(args...)
|
||||
}
|
||||
|
||||
// Error logs a message at level Error on the standard logger.
|
||||
func Error(args ...interface{}) {
|
||||
std.Error(args...)
|
||||
}
|
||||
|
||||
// Panic logs a message at level Panic on the standard logger.
|
||||
func Panic(args ...interface{}) {
|
||||
std.Panic(args...)
|
||||
}
|
||||
|
||||
// Fatal logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
|
||||
func Fatal(args ...interface{}) {
|
||||
std.Fatal(args...)
|
||||
}
|
||||
|
||||
// TraceFn logs a message from a func at level Trace on the standard logger.
|
||||
func TraceFn(fn LogFunction) {
|
||||
std.TraceFn(fn)
|
||||
}
|
||||
|
||||
// DebugFn logs a message from a func at level Debug on the standard logger.
|
||||
func DebugFn(fn LogFunction) {
|
||||
std.DebugFn(fn)
|
||||
}
|
||||
|
||||
// PrintFn logs a message from a func at level Info on the standard logger.
|
||||
func PrintFn(fn LogFunction) {
|
||||
std.PrintFn(fn)
|
||||
}
|
||||
|
||||
// InfoFn logs a message from a func at level Info on the standard logger.
|
||||
func InfoFn(fn LogFunction) {
|
||||
std.InfoFn(fn)
|
||||
}
|
||||
|
||||
// WarnFn logs a message from a func at level Warn on the standard logger.
|
||||
func WarnFn(fn LogFunction) {
|
||||
std.WarnFn(fn)
|
||||
}
|
||||
|
||||
// WarningFn logs a message from a func at level Warn on the standard logger.
|
||||
func WarningFn(fn LogFunction) {
|
||||
std.WarningFn(fn)
|
||||
}
|
||||
|
||||
// ErrorFn logs a message from a func at level Error on the standard logger.
|
||||
func ErrorFn(fn LogFunction) {
|
||||
std.ErrorFn(fn)
|
||||
}
|
||||
|
||||
// PanicFn logs a message from a func at level Panic on the standard logger.
|
||||
func PanicFn(fn LogFunction) {
|
||||
std.PanicFn(fn)
|
||||
}
|
||||
|
||||
// FatalFn logs a message from a func at level Fatal on the standard logger then the process will exit with status set to 1.
|
||||
func FatalFn(fn LogFunction) {
|
||||
std.FatalFn(fn)
|
||||
}
|
||||
|
||||
// Tracef logs a message at level Trace on the standard logger.
|
||||
func Tracef(format string, args ...interface{}) {
|
||||
std.Tracef(format, args...)
|
||||
}
|
||||
|
||||
// Debugf logs a message at level Debug on the standard logger.
|
||||
func Debugf(format string, args ...interface{}) {
|
||||
std.Debugf(format, args...)
|
||||
}
|
||||
|
||||
// Printf logs a message at level Info on the standard logger.
|
||||
func Printf(format string, args ...interface{}) {
|
||||
std.Printf(format, args...)
|
||||
}
|
||||
|
||||
// Infof logs a message at level Info on the standard logger.
|
||||
func Infof(format string, args ...interface{}) {
|
||||
std.Infof(format, args...)
|
||||
}
|
||||
|
||||
// Warnf logs a message at level Warn on the standard logger.
|
||||
func Warnf(format string, args ...interface{}) {
|
||||
std.Warnf(format, args...)
|
||||
}
|
||||
|
||||
// Warningf logs a message at level Warn on the standard logger.
|
||||
func Warningf(format string, args ...interface{}) {
|
||||
std.Warningf(format, args...)
|
||||
}
|
||||
|
||||
// Errorf logs a message at level Error on the standard logger.
|
||||
func Errorf(format string, args ...interface{}) {
|
||||
std.Errorf(format, args...)
|
||||
}
|
||||
|
||||
// Panicf logs a message at level Panic on the standard logger.
|
||||
func Panicf(format string, args ...interface{}) {
|
||||
std.Panicf(format, args...)
|
||||
}
|
||||
|
||||
// Fatalf logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
|
||||
func Fatalf(format string, args ...interface{}) {
|
||||
std.Fatalf(format, args...)
|
||||
}
|
||||
|
||||
// Traceln logs a message at level Trace on the standard logger.
|
||||
func Traceln(args ...interface{}) {
|
||||
std.Traceln(args...)
|
||||
}
|
||||
|
||||
// Debugln logs a message at level Debug on the standard logger.
|
||||
func Debugln(args ...interface{}) {
|
||||
std.Debugln(args...)
|
||||
}
|
||||
|
||||
// Println logs a message at level Info on the standard logger.
|
||||
func Println(args ...interface{}) {
|
||||
std.Println(args...)
|
||||
}
|
||||
|
||||
// Infoln logs a message at level Info on the standard logger.
|
||||
func Infoln(args ...interface{}) {
|
||||
std.Infoln(args...)
|
||||
}
|
||||
|
||||
// Warnln logs a message at level Warn on the standard logger.
|
||||
func Warnln(args ...interface{}) {
|
||||
std.Warnln(args...)
|
||||
}
|
||||
|
||||
// Warningln logs a message at level Warn on the standard logger.
|
||||
func Warningln(args ...interface{}) {
|
||||
std.Warningln(args...)
|
||||
}
|
||||
|
||||
// Errorln logs a message at level Error on the standard logger.
|
||||
func Errorln(args ...interface{}) {
|
||||
std.Errorln(args...)
|
||||
}
|
||||
|
||||
// Panicln logs a message at level Panic on the standard logger.
|
||||
func Panicln(args ...interface{}) {
|
||||
std.Panicln(args...)
|
||||
}
|
||||
|
||||
// Fatalln logs a message at level Fatal on the standard logger then the process will exit with status set to 1.
|
||||
func Fatalln(args ...interface{}) {
|
||||
std.Fatalln(args...)
|
||||
}
|
||||
78
vendor/github.com/sirupsen/logrus/formatter.go
generated
vendored
Normal file
78
vendor/github.com/sirupsen/logrus/formatter.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
package logrus
|
||||
|
||||
import "time"
|
||||
|
||||
// Default key names for the default fields
|
||||
const (
|
||||
defaultTimestampFormat = time.RFC3339
|
||||
FieldKeyMsg = "msg"
|
||||
FieldKeyLevel = "level"
|
||||
FieldKeyTime = "time"
|
||||
FieldKeyLogrusError = "logrus_error"
|
||||
FieldKeyFunc = "func"
|
||||
FieldKeyFile = "file"
|
||||
)
|
||||
|
||||
// The Formatter interface is used to implement a custom Formatter. It takes an
|
||||
// `Entry`. It exposes all the fields, including the default ones:
|
||||
//
|
||||
// * `entry.Data["msg"]`. The message passed from Info, Warn, Error ..
|
||||
// * `entry.Data["time"]`. The timestamp.
|
||||
// * `entry.Data["level"]. The level the entry was logged at.
|
||||
//
|
||||
// Any additional fields added with `WithField` or `WithFields` are also in
|
||||
// `entry.Data`. Format is expected to return an array of bytes which are then
|
||||
// logged to `logger.Out`.
|
||||
type Formatter interface {
|
||||
Format(*Entry) ([]byte, error)
|
||||
}
|
||||
|
||||
// This is to not silently overwrite `time`, `msg`, `func` and `level` fields when
|
||||
// dumping it. If this code wasn't there doing:
|
||||
//
|
||||
// logrus.WithField("level", 1).Info("hello")
|
||||
//
|
||||
// Would just silently drop the user provided level. Instead with this code
|
||||
// it'll logged as:
|
||||
//
|
||||
// {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."}
|
||||
//
|
||||
// It's not exported because it's still using Data in an opinionated way. It's to
|
||||
// avoid code duplication between the two default formatters.
|
||||
func prefixFieldClashes(data Fields, fieldMap FieldMap, reportCaller bool) {
|
||||
timeKey := fieldMap.resolve(FieldKeyTime)
|
||||
if t, ok := data[timeKey]; ok {
|
||||
data["fields."+timeKey] = t
|
||||
delete(data, timeKey)
|
||||
}
|
||||
|
||||
msgKey := fieldMap.resolve(FieldKeyMsg)
|
||||
if m, ok := data[msgKey]; ok {
|
||||
data["fields."+msgKey] = m
|
||||
delete(data, msgKey)
|
||||
}
|
||||
|
||||
levelKey := fieldMap.resolve(FieldKeyLevel)
|
||||
if l, ok := data[levelKey]; ok {
|
||||
data["fields."+levelKey] = l
|
||||
delete(data, levelKey)
|
||||
}
|
||||
|
||||
logrusErrKey := fieldMap.resolve(FieldKeyLogrusError)
|
||||
if l, ok := data[logrusErrKey]; ok {
|
||||
data["fields."+logrusErrKey] = l
|
||||
delete(data, logrusErrKey)
|
||||
}
|
||||
|
||||
// If reportCaller is not set, 'func' will not conflict.
|
||||
if reportCaller {
|
||||
funcKey := fieldMap.resolve(FieldKeyFunc)
|
||||
if l, ok := data[funcKey]; ok {
|
||||
data["fields."+funcKey] = l
|
||||
}
|
||||
fileKey := fieldMap.resolve(FieldKeyFile)
|
||||
if l, ok := data[fileKey]; ok {
|
||||
data["fields."+fileKey] = l
|
||||
}
|
||||
}
|
||||
}
|
||||
10
vendor/github.com/sirupsen/logrus/go.mod
generated
vendored
Normal file
10
vendor/github.com/sirupsen/logrus/go.mod
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
module github.com/sirupsen/logrus
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/testify v1.2.2
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037
|
||||
)
|
||||
|
||||
go 1.13
|
||||
8
vendor/github.com/sirupsen/logrus/go.sum
generated
vendored
Normal file
8
vendor/github.com/sirupsen/logrus/go.sum
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
34
vendor/github.com/sirupsen/logrus/hooks.go
generated
vendored
Normal file
34
vendor/github.com/sirupsen/logrus/hooks.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
package logrus
|
||||
|
||||
// A hook to be fired when logging on the logging levels returned from
|
||||
// `Levels()` on your implementation of the interface. Note that this is not
|
||||
// fired in a goroutine or a channel with workers, you should handle such
|
||||
// functionality yourself if your call is non-blocking and you don't wish for
|
||||
// the logging calls for levels returned from `Levels()` to block.
|
||||
type Hook interface {
|
||||
Levels() []Level
|
||||
Fire(*Entry) error
|
||||
}
|
||||
|
||||
// Internal type for storing the hooks on a logger instance.
|
||||
type LevelHooks map[Level][]Hook
|
||||
|
||||
// Add a hook to an instance of logger. This is called with
|
||||
// `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface.
|
||||
func (hooks LevelHooks) Add(hook Hook) {
|
||||
for _, level := range hook.Levels() {
|
||||
hooks[level] = append(hooks[level], hook)
|
||||
}
|
||||
}
|
||||
|
||||
// Fire all the hooks for the passed level. Used by `entry.log` to fire
|
||||
// appropriate hooks for a log entry.
|
||||
func (hooks LevelHooks) Fire(level Level, entry *Entry) error {
|
||||
for _, hook := range hooks[level] {
|
||||
if err := hook.Fire(entry); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
91
vendor/github.com/sirupsen/logrus/hooks/test/test.go
generated
vendored
Normal file
91
vendor/github.com/sirupsen/logrus/hooks/test/test.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
// The Test package is used for testing logrus.
|
||||
// It provides a simple hooks which register logged messages.
|
||||
package test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"sync"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Hook is a hook designed for dealing with logs in test scenarios.
|
||||
type Hook struct {
|
||||
// Entries is an array of all entries that have been received by this hook.
|
||||
// For safe access, use the AllEntries() method, rather than reading this
|
||||
// value directly.
|
||||
Entries []logrus.Entry
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// NewGlobal installs a test hook for the global logger.
|
||||
func NewGlobal() *Hook {
|
||||
|
||||
hook := new(Hook)
|
||||
logrus.AddHook(hook)
|
||||
|
||||
return hook
|
||||
|
||||
}
|
||||
|
||||
// NewLocal installs a test hook for a given local logger.
|
||||
func NewLocal(logger *logrus.Logger) *Hook {
|
||||
|
||||
hook := new(Hook)
|
||||
logger.Hooks.Add(hook)
|
||||
|
||||
return hook
|
||||
|
||||
}
|
||||
|
||||
// NewNullLogger creates a discarding logger and installs the test hook.
|
||||
func NewNullLogger() (*logrus.Logger, *Hook) {
|
||||
|
||||
logger := logrus.New()
|
||||
logger.Out = ioutil.Discard
|
||||
|
||||
return logger, NewLocal(logger)
|
||||
|
||||
}
|
||||
|
||||
func (t *Hook) Fire(e *logrus.Entry) error {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
t.Entries = append(t.Entries, *e)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Hook) Levels() []logrus.Level {
|
||||
return logrus.AllLevels
|
||||
}
|
||||
|
||||
// LastEntry returns the last entry that was logged or nil.
|
||||
func (t *Hook) LastEntry() *logrus.Entry {
|
||||
t.mu.RLock()
|
||||
defer t.mu.RUnlock()
|
||||
i := len(t.Entries) - 1
|
||||
if i < 0 {
|
||||
return nil
|
||||
}
|
||||
return &t.Entries[i]
|
||||
}
|
||||
|
||||
// AllEntries returns all entries that were logged.
|
||||
func (t *Hook) AllEntries() []*logrus.Entry {
|
||||
t.mu.RLock()
|
||||
defer t.mu.RUnlock()
|
||||
// Make a copy so the returned value won't race with future log requests
|
||||
entries := make([]*logrus.Entry, len(t.Entries))
|
||||
for i := 0; i < len(t.Entries); i++ {
|
||||
// Make a copy, for safety
|
||||
entries[i] = &t.Entries[i]
|
||||
}
|
||||
return entries
|
||||
}
|
||||
|
||||
// Reset removes all Entries from this test hook.
|
||||
func (t *Hook) Reset() {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
t.Entries = make([]logrus.Entry, 0)
|
||||
}
|
||||
128
vendor/github.com/sirupsen/logrus/json_formatter.go
generated
vendored
Normal file
128
vendor/github.com/sirupsen/logrus/json_formatter.go
generated
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
type fieldKey string
|
||||
|
||||
// FieldMap allows customization of the key names for default fields.
|
||||
type FieldMap map[fieldKey]string
|
||||
|
||||
func (f FieldMap) resolve(key fieldKey) string {
|
||||
if k, ok := f[key]; ok {
|
||||
return k
|
||||
}
|
||||
|
||||
return string(key)
|
||||
}
|
||||
|
||||
// JSONFormatter formats logs into parsable json
|
||||
type JSONFormatter struct {
|
||||
// TimestampFormat sets the format used for marshaling timestamps.
|
||||
// The format to use is the same than for time.Format or time.Parse from the standard
|
||||
// library.
|
||||
// The standard Library already provides a set of predefined format.
|
||||
TimestampFormat string
|
||||
|
||||
// DisableTimestamp allows disabling automatic timestamps in output
|
||||
DisableTimestamp bool
|
||||
|
||||
// DisableHTMLEscape allows disabling html escaping in output
|
||||
DisableHTMLEscape bool
|
||||
|
||||
// DataKey allows users to put all the log entry parameters into a nested dictionary at a given key.
|
||||
DataKey string
|
||||
|
||||
// FieldMap allows users to customize the names of keys for default fields.
|
||||
// As an example:
|
||||
// formatter := &JSONFormatter{
|
||||
// FieldMap: FieldMap{
|
||||
// FieldKeyTime: "@timestamp",
|
||||
// FieldKeyLevel: "@level",
|
||||
// FieldKeyMsg: "@message",
|
||||
// FieldKeyFunc: "@caller",
|
||||
// },
|
||||
// }
|
||||
FieldMap FieldMap
|
||||
|
||||
// CallerPrettyfier can be set by the user to modify the content
|
||||
// of the function and file keys in the json data when ReportCaller is
|
||||
// activated. If any of the returned value is the empty string the
|
||||
// corresponding key will be removed from json fields.
|
||||
CallerPrettyfier func(*runtime.Frame) (function string, file string)
|
||||
|
||||
// PrettyPrint will indent all json logs
|
||||
PrettyPrint bool
|
||||
}
|
||||
|
||||
// Format renders a single log entry
|
||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
data := make(Fields, len(entry.Data)+4)
|
||||
for k, v := range entry.Data {
|
||||
switch v := v.(type) {
|
||||
case error:
|
||||
// Otherwise errors are ignored by `encoding/json`
|
||||
// https://github.com/sirupsen/logrus/issues/137
|
||||
data[k] = v.Error()
|
||||
default:
|
||||
data[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
if f.DataKey != "" {
|
||||
newData := make(Fields, 4)
|
||||
newData[f.DataKey] = data
|
||||
data = newData
|
||||
}
|
||||
|
||||
prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
|
||||
|
||||
timestampFormat := f.TimestampFormat
|
||||
if timestampFormat == "" {
|
||||
timestampFormat = defaultTimestampFormat
|
||||
}
|
||||
|
||||
if entry.err != "" {
|
||||
data[f.FieldMap.resolve(FieldKeyLogrusError)] = entry.err
|
||||
}
|
||||
if !f.DisableTimestamp {
|
||||
data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
|
||||
}
|
||||
data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
|
||||
data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
|
||||
if entry.HasCaller() {
|
||||
funcVal := entry.Caller.Function
|
||||
fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
|
||||
if f.CallerPrettyfier != nil {
|
||||
funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
|
||||
}
|
||||
if funcVal != "" {
|
||||
data[f.FieldMap.resolve(FieldKeyFunc)] = funcVal
|
||||
}
|
||||
if fileVal != "" {
|
||||
data[f.FieldMap.resolve(FieldKeyFile)] = fileVal
|
||||
}
|
||||
}
|
||||
|
||||
var b *bytes.Buffer
|
||||
if entry.Buffer != nil {
|
||||
b = entry.Buffer
|
||||
} else {
|
||||
b = &bytes.Buffer{}
|
||||
}
|
||||
|
||||
encoder := json.NewEncoder(b)
|
||||
encoder.SetEscapeHTML(!f.DisableHTMLEscape)
|
||||
if f.PrettyPrint {
|
||||
encoder.SetIndent("", " ")
|
||||
}
|
||||
if err := encoder.Encode(data); err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal fields to JSON, %w", err)
|
||||
}
|
||||
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
404
vendor/github.com/sirupsen/logrus/logger.go
generated
vendored
Normal file
404
vendor/github.com/sirupsen/logrus/logger.go
generated
vendored
Normal file
@@ -0,0 +1,404 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
// LogFunction For big messages, it can be more efficient to pass a function
|
||||
// and only call it if the log level is actually enables rather than
|
||||
// generating the log message and then checking if the level is enabled
|
||||
type LogFunction func() []interface{}
|
||||
|
||||
type Logger struct {
|
||||
// The logs are `io.Copy`'d to this in a mutex. It's common to set this to a
|
||||
// file, or leave it default which is `os.Stderr`. You can also set this to
|
||||
// something more adventurous, such as logging to Kafka.
|
||||
Out io.Writer
|
||||
// Hooks for the logger instance. These allow firing events based on logging
|
||||
// levels and log entries. For example, to send errors to an error tracking
|
||||
// service, log to StatsD or dump the core on fatal errors.
|
||||
Hooks LevelHooks
|
||||
// All log entries pass through the formatter before logged to Out. The
|
||||
// included formatters are `TextFormatter` and `JSONFormatter` for which
|
||||
// TextFormatter is the default. In development (when a TTY is attached) it
|
||||
// logs with colors, but to a file it wouldn't. You can easily implement your
|
||||
// own that implements the `Formatter` interface, see the `README` or included
|
||||
// formatters for examples.
|
||||
Formatter Formatter
|
||||
|
||||
// Flag for whether to log caller info (off by default)
|
||||
ReportCaller bool
|
||||
|
||||
// The logging level the logger should log at. This is typically (and defaults
|
||||
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
||||
// logged.
|
||||
Level Level
|
||||
// Used to sync writing to the log. Locking is enabled by Default
|
||||
mu MutexWrap
|
||||
// Reusable empty entry
|
||||
entryPool sync.Pool
|
||||
// Function to exit the application, defaults to `os.Exit()`
|
||||
ExitFunc exitFunc
|
||||
}
|
||||
|
||||
type exitFunc func(int)
|
||||
|
||||
type MutexWrap struct {
|
||||
lock sync.Mutex
|
||||
disabled bool
|
||||
}
|
||||
|
||||
func (mw *MutexWrap) Lock() {
|
||||
if !mw.disabled {
|
||||
mw.lock.Lock()
|
||||
}
|
||||
}
|
||||
|
||||
func (mw *MutexWrap) Unlock() {
|
||||
if !mw.disabled {
|
||||
mw.lock.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (mw *MutexWrap) Disable() {
|
||||
mw.disabled = true
|
||||
}
|
||||
|
||||
// Creates a new logger. Configuration should be set by changing `Formatter`,
|
||||
// `Out` and `Hooks` directly on the default logger instance. You can also just
|
||||
// instantiate your own:
|
||||
//
|
||||
// var log = &logrus.Logger{
|
||||
// Out: os.Stderr,
|
||||
// Formatter: new(logrus.TextFormatter),
|
||||
// Hooks: make(logrus.LevelHooks),
|
||||
// Level: logrus.DebugLevel,
|
||||
// }
|
||||
//
|
||||
// It's recommended to make this a global instance called `log`.
|
||||
func New() *Logger {
|
||||
return &Logger{
|
||||
Out: os.Stderr,
|
||||
Formatter: new(TextFormatter),
|
||||
Hooks: make(LevelHooks),
|
||||
Level: InfoLevel,
|
||||
ExitFunc: os.Exit,
|
||||
ReportCaller: false,
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) newEntry() *Entry {
|
||||
entry, ok := logger.entryPool.Get().(*Entry)
|
||||
if ok {
|
||||
return entry
|
||||
}
|
||||
return NewEntry(logger)
|
||||
}
|
||||
|
||||
func (logger *Logger) releaseEntry(entry *Entry) {
|
||||
entry.Data = map[string]interface{}{}
|
||||
logger.entryPool.Put(entry)
|
||||
}
|
||||
|
||||
// WithField allocates a new entry and adds a field to it.
|
||||
// Debug, Print, Info, Warn, Error, Fatal or Panic must be then applied to
|
||||
// this new returned entry.
|
||||
// If you want multiple fields, use `WithFields`.
|
||||
func (logger *Logger) WithField(key string, value interface{}) *Entry {
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithField(key, value)
|
||||
}
|
||||
|
||||
// Adds a struct of fields to the log entry. All it does is call `WithField` for
|
||||
// each `Field`.
|
||||
func (logger *Logger) WithFields(fields Fields) *Entry {
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithFields(fields)
|
||||
}
|
||||
|
||||
// Add an error as single field to the log entry. All it does is call
|
||||
// `WithError` for the given `error`.
|
||||
func (logger *Logger) WithError(err error) *Entry {
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithError(err)
|
||||
}
|
||||
|
||||
// Add a context to the log entry.
|
||||
func (logger *Logger) WithContext(ctx context.Context) *Entry {
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithContext(ctx)
|
||||
}
|
||||
|
||||
// Overrides the time of the log entry.
|
||||
func (logger *Logger) WithTime(t time.Time) *Entry {
|
||||
entry := logger.newEntry()
|
||||
defer logger.releaseEntry(entry)
|
||||
return entry.WithTime(t)
|
||||
}
|
||||
|
||||
func (logger *Logger) Logf(level Level, format string, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(level) {
|
||||
entry := logger.newEntry()
|
||||
entry.Logf(level, format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Tracef(format string, args ...interface{}) {
|
||||
logger.Logf(TraceLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Debugf(format string, args ...interface{}) {
|
||||
logger.Logf(DebugLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Infof(format string, args ...interface{}) {
|
||||
logger.Logf(InfoLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Printf(format string, args ...interface{}) {
|
||||
entry := logger.newEntry()
|
||||
entry.Printf(format, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warnf(format string, args ...interface{}) {
|
||||
logger.Logf(WarnLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warningf(format string, args ...interface{}) {
|
||||
logger.Warnf(format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Errorf(format string, args ...interface{}) {
|
||||
logger.Logf(ErrorLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatalf(format string, args ...interface{}) {
|
||||
logger.Logf(FatalLevel, format, args...)
|
||||
logger.Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panicf(format string, args ...interface{}) {
|
||||
logger.Logf(PanicLevel, format, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Log(level Level, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(level) {
|
||||
entry := logger.newEntry()
|
||||
entry.Log(level, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) LogFn(level Level, fn LogFunction) {
|
||||
if logger.IsLevelEnabled(level) {
|
||||
entry := logger.newEntry()
|
||||
entry.Log(level, fn()...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Trace(args ...interface{}) {
|
||||
logger.Log(TraceLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Debug(args ...interface{}) {
|
||||
logger.Log(DebugLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Info(args ...interface{}) {
|
||||
logger.Log(InfoLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Print(args ...interface{}) {
|
||||
entry := logger.newEntry()
|
||||
entry.Print(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warn(args ...interface{}) {
|
||||
logger.Log(WarnLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warning(args ...interface{}) {
|
||||
logger.Warn(args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Error(args ...interface{}) {
|
||||
logger.Log(ErrorLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatal(args ...interface{}) {
|
||||
logger.Log(FatalLevel, args...)
|
||||
logger.Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panic(args ...interface{}) {
|
||||
logger.Log(PanicLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) TraceFn(fn LogFunction) {
|
||||
logger.LogFn(TraceLevel, fn)
|
||||
}
|
||||
|
||||
func (logger *Logger) DebugFn(fn LogFunction) {
|
||||
logger.LogFn(DebugLevel, fn)
|
||||
}
|
||||
|
||||
func (logger *Logger) InfoFn(fn LogFunction) {
|
||||
logger.LogFn(InfoLevel, fn)
|
||||
}
|
||||
|
||||
func (logger *Logger) PrintFn(fn LogFunction) {
|
||||
entry := logger.newEntry()
|
||||
entry.Print(fn()...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
|
||||
func (logger *Logger) WarnFn(fn LogFunction) {
|
||||
logger.LogFn(WarnLevel, fn)
|
||||
}
|
||||
|
||||
func (logger *Logger) WarningFn(fn LogFunction) {
|
||||
logger.WarnFn(fn)
|
||||
}
|
||||
|
||||
func (logger *Logger) ErrorFn(fn LogFunction) {
|
||||
logger.LogFn(ErrorLevel, fn)
|
||||
}
|
||||
|
||||
func (logger *Logger) FatalFn(fn LogFunction) {
|
||||
logger.LogFn(FatalLevel, fn)
|
||||
logger.Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) PanicFn(fn LogFunction) {
|
||||
logger.LogFn(PanicLevel, fn)
|
||||
}
|
||||
|
||||
func (logger *Logger) Logln(level Level, args ...interface{}) {
|
||||
if logger.IsLevelEnabled(level) {
|
||||
entry := logger.newEntry()
|
||||
entry.Logln(level, args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
}
|
||||
|
||||
func (logger *Logger) Traceln(args ...interface{}) {
|
||||
logger.Logln(TraceLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Debugln(args ...interface{}) {
|
||||
logger.Logln(DebugLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Infoln(args ...interface{}) {
|
||||
logger.Logln(InfoLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Println(args ...interface{}) {
|
||||
entry := logger.newEntry()
|
||||
entry.Println(args...)
|
||||
logger.releaseEntry(entry)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warnln(args ...interface{}) {
|
||||
logger.Logln(WarnLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Warningln(args ...interface{}) {
|
||||
logger.Warnln(args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Errorln(args ...interface{}) {
|
||||
logger.Logln(ErrorLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Fatalln(args ...interface{}) {
|
||||
logger.Logln(FatalLevel, args...)
|
||||
logger.Exit(1)
|
||||
}
|
||||
|
||||
func (logger *Logger) Panicln(args ...interface{}) {
|
||||
logger.Logln(PanicLevel, args...)
|
||||
}
|
||||
|
||||
func (logger *Logger) Exit(code int) {
|
||||
runHandlers()
|
||||
if logger.ExitFunc == nil {
|
||||
logger.ExitFunc = os.Exit
|
||||
}
|
||||
logger.ExitFunc(code)
|
||||
}
|
||||
|
||||
//When file is opened with appending mode, it's safe to
|
||||
//write concurrently to a file (within 4k message on Linux).
|
||||
//In these cases user can choose to disable the lock.
|
||||
func (logger *Logger) SetNoLock() {
|
||||
logger.mu.Disable()
|
||||
}
|
||||
|
||||
func (logger *Logger) level() Level {
|
||||
return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
|
||||
}
|
||||
|
||||
// SetLevel sets the logger level.
|
||||
func (logger *Logger) SetLevel(level Level) {
|
||||
atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
|
||||
}
|
||||
|
||||
// GetLevel returns the logger level.
|
||||
func (logger *Logger) GetLevel() Level {
|
||||
return logger.level()
|
||||
}
|
||||
|
||||
// AddHook adds a hook to the logger hooks.
|
||||
func (logger *Logger) AddHook(hook Hook) {
|
||||
logger.mu.Lock()
|
||||
defer logger.mu.Unlock()
|
||||
logger.Hooks.Add(hook)
|
||||
}
|
||||
|
||||
// IsLevelEnabled checks if the log level of the logger is greater than the level param
|
||||
func (logger *Logger) IsLevelEnabled(level Level) bool {
|
||||
return logger.level() >= level
|
||||
}
|
||||
|
||||
// SetFormatter sets the logger formatter.
|
||||
func (logger *Logger) SetFormatter(formatter Formatter) {
|
||||
logger.mu.Lock()
|
||||
defer logger.mu.Unlock()
|
||||
logger.Formatter = formatter
|
||||
}
|
||||
|
||||
// SetOutput sets the logger output.
|
||||
func (logger *Logger) SetOutput(output io.Writer) {
|
||||
logger.mu.Lock()
|
||||
defer logger.mu.Unlock()
|
||||
logger.Out = output
|
||||
}
|
||||
|
||||
func (logger *Logger) SetReportCaller(reportCaller bool) {
|
||||
logger.mu.Lock()
|
||||
defer logger.mu.Unlock()
|
||||
logger.ReportCaller = reportCaller
|
||||
}
|
||||
|
||||
// ReplaceHooks replaces the logger hooks and returns the old ones
|
||||
func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks {
|
||||
logger.mu.Lock()
|
||||
oldHooks := logger.Hooks
|
||||
logger.Hooks = hooks
|
||||
logger.mu.Unlock()
|
||||
return oldHooks
|
||||
}
|
||||
186
vendor/github.com/sirupsen/logrus/logrus.go
generated
vendored
Normal file
186
vendor/github.com/sirupsen/logrus/logrus.go
generated
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Fields type, used to pass to `WithFields`.
|
||||
type Fields map[string]interface{}
|
||||
|
||||
// Level type
|
||||
type Level uint32
|
||||
|
||||
// Convert the Level to a string. E.g. PanicLevel becomes "panic".
|
||||
func (level Level) String() string {
|
||||
if b, err := level.MarshalText(); err == nil {
|
||||
return string(b)
|
||||
} else {
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// ParseLevel takes a string level and returns the Logrus log level constant.
|
||||
func ParseLevel(lvl string) (Level, error) {
|
||||
switch strings.ToLower(lvl) {
|
||||
case "panic":
|
||||
return PanicLevel, nil
|
||||
case "fatal":
|
||||
return FatalLevel, nil
|
||||
case "error":
|
||||
return ErrorLevel, nil
|
||||
case "warn", "warning":
|
||||
return WarnLevel, nil
|
||||
case "info":
|
||||
return InfoLevel, nil
|
||||
case "debug":
|
||||
return DebugLevel, nil
|
||||
case "trace":
|
||||
return TraceLevel, nil
|
||||
}
|
||||
|
||||
var l Level
|
||||
return l, fmt.Errorf("not a valid logrus Level: %q", lvl)
|
||||
}
|
||||
|
||||
// UnmarshalText implements encoding.TextUnmarshaler.
|
||||
func (level *Level) UnmarshalText(text []byte) error {
|
||||
l, err := ParseLevel(string(text))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*level = l
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (level Level) MarshalText() ([]byte, error) {
|
||||
switch level {
|
||||
case TraceLevel:
|
||||
return []byte("trace"), nil
|
||||
case DebugLevel:
|
||||
return []byte("debug"), nil
|
||||
case InfoLevel:
|
||||
return []byte("info"), nil
|
||||
case WarnLevel:
|
||||
return []byte("warning"), nil
|
||||
case ErrorLevel:
|
||||
return []byte("error"), nil
|
||||
case FatalLevel:
|
||||
return []byte("fatal"), nil
|
||||
case PanicLevel:
|
||||
return []byte("panic"), nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("not a valid logrus level %d", level)
|
||||
}
|
||||
|
||||
// A constant exposing all logging levels
|
||||
var AllLevels = []Level{
|
||||
PanicLevel,
|
||||
FatalLevel,
|
||||
ErrorLevel,
|
||||
WarnLevel,
|
||||
InfoLevel,
|
||||
DebugLevel,
|
||||
TraceLevel,
|
||||
}
|
||||
|
||||
// These are the different logging levels. You can set the logging level to log
|
||||
// on your instance of logger, obtained with `logrus.New()`.
|
||||
const (
|
||||
// PanicLevel level, highest level of severity. Logs and then calls panic with the
|
||||
// message passed to Debug, Info, ...
|
||||
PanicLevel Level = iota
|
||||
// FatalLevel level. Logs and then calls `logger.Exit(1)`. It will exit even if the
|
||||
// logging level is set to Panic.
|
||||
FatalLevel
|
||||
// ErrorLevel level. Logs. Used for errors that should definitely be noted.
|
||||
// Commonly used for hooks to send errors to an error tracking service.
|
||||
ErrorLevel
|
||||
// WarnLevel level. Non-critical entries that deserve eyes.
|
||||
WarnLevel
|
||||
// InfoLevel level. General operational entries about what's going on inside the
|
||||
// application.
|
||||
InfoLevel
|
||||
// DebugLevel level. Usually only enabled when debugging. Very verbose logging.
|
||||
DebugLevel
|
||||
// TraceLevel level. Designates finer-grained informational events than the Debug.
|
||||
TraceLevel
|
||||
)
|
||||
|
||||
// Won't compile if StdLogger can't be realized by a log.Logger
|
||||
var (
|
||||
_ StdLogger = &log.Logger{}
|
||||
_ StdLogger = &Entry{}
|
||||
_ StdLogger = &Logger{}
|
||||
)
|
||||
|
||||
// StdLogger is what your logrus-enabled library should take, that way
|
||||
// it'll accept a stdlib logger and a logrus logger. There's no standard
|
||||
// interface, this is the closest we get, unfortunately.
|
||||
type StdLogger interface {
|
||||
Print(...interface{})
|
||||
Printf(string, ...interface{})
|
||||
Println(...interface{})
|
||||
|
||||
Fatal(...interface{})
|
||||
Fatalf(string, ...interface{})
|
||||
Fatalln(...interface{})
|
||||
|
||||
Panic(...interface{})
|
||||
Panicf(string, ...interface{})
|
||||
Panicln(...interface{})
|
||||
}
|
||||
|
||||
// The FieldLogger interface generalizes the Entry and Logger types
|
||||
type FieldLogger interface {
|
||||
WithField(key string, value interface{}) *Entry
|
||||
WithFields(fields Fields) *Entry
|
||||
WithError(err error) *Entry
|
||||
|
||||
Debugf(format string, args ...interface{})
|
||||
Infof(format string, args ...interface{})
|
||||
Printf(format string, args ...interface{})
|
||||
Warnf(format string, args ...interface{})
|
||||
Warningf(format string, args ...interface{})
|
||||
Errorf(format string, args ...interface{})
|
||||
Fatalf(format string, args ...interface{})
|
||||
Panicf(format string, args ...interface{})
|
||||
|
||||
Debug(args ...interface{})
|
||||
Info(args ...interface{})
|
||||
Print(args ...interface{})
|
||||
Warn(args ...interface{})
|
||||
Warning(args ...interface{})
|
||||
Error(args ...interface{})
|
||||
Fatal(args ...interface{})
|
||||
Panic(args ...interface{})
|
||||
|
||||
Debugln(args ...interface{})
|
||||
Infoln(args ...interface{})
|
||||
Println(args ...interface{})
|
||||
Warnln(args ...interface{})
|
||||
Warningln(args ...interface{})
|
||||
Errorln(args ...interface{})
|
||||
Fatalln(args ...interface{})
|
||||
Panicln(args ...interface{})
|
||||
|
||||
// IsDebugEnabled() bool
|
||||
// IsInfoEnabled() bool
|
||||
// IsWarnEnabled() bool
|
||||
// IsErrorEnabled() bool
|
||||
// IsFatalEnabled() bool
|
||||
// IsPanicEnabled() bool
|
||||
}
|
||||
|
||||
// Ext1FieldLogger (the first extension to FieldLogger) is superfluous, it is
|
||||
// here for consistancy. Do not use. Use Logger or Entry instead.
|
||||
type Ext1FieldLogger interface {
|
||||
FieldLogger
|
||||
Tracef(format string, args ...interface{})
|
||||
Trace(args ...interface{})
|
||||
Traceln(args ...interface{})
|
||||
}
|
||||
11
vendor/github.com/sirupsen/logrus/terminal_check_appengine.go
generated
vendored
Normal file
11
vendor/github.com/sirupsen/logrus/terminal_check_appengine.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build appengine
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
func checkIfTerminal(w io.Writer) bool {
|
||||
return true
|
||||
}
|
||||
13
vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
generated
vendored
Normal file
13
vendor/github.com/sirupsen/logrus/terminal_check_bsd.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// +build darwin dragonfly freebsd netbsd openbsd
|
||||
// +build !js
|
||||
|
||||
package logrus
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
const ioctlReadTermios = unix.TIOCGETA
|
||||
|
||||
func isTerminal(fd int) bool {
|
||||
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
||||
return err == nil
|
||||
}
|
||||
7
vendor/github.com/sirupsen/logrus/terminal_check_js.go
generated
vendored
Normal file
7
vendor/github.com/sirupsen/logrus/terminal_check_js.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
// +build js
|
||||
|
||||
package logrus
|
||||
|
||||
func isTerminal(fd int) bool {
|
||||
return false
|
||||
}
|
||||
11
vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go
generated
vendored
Normal file
11
vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build js nacl plan9
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
func checkIfTerminal(w io.Writer) bool {
|
||||
return false
|
||||
}
|
||||
17
vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
generated
vendored
Normal file
17
vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// +build !appengine,!js,!windows,!nacl,!plan9
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func checkIfTerminal(w io.Writer) bool {
|
||||
switch v := w.(type) {
|
||||
case *os.File:
|
||||
return isTerminal(int(v.Fd()))
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
11
vendor/github.com/sirupsen/logrus/terminal_check_solaris.go
generated
vendored
Normal file
11
vendor/github.com/sirupsen/logrus/terminal_check_solaris.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||
func isTerminal(fd int) bool {
|
||||
_, err := unix.IoctlGetTermio(fd, unix.TCGETA)
|
||||
return err == nil
|
||||
}
|
||||
13
vendor/github.com/sirupsen/logrus/terminal_check_unix.go
generated
vendored
Normal file
13
vendor/github.com/sirupsen/logrus/terminal_check_unix.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// +build linux aix zos
|
||||
// +build !js
|
||||
|
||||
package logrus
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
|
||||
const ioctlReadTermios = unix.TCGETS
|
||||
|
||||
func isTerminal(fd int) bool {
|
||||
_, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
||||
return err == nil
|
||||
}
|
||||
27
vendor/github.com/sirupsen/logrus/terminal_check_windows.go
generated
vendored
Normal file
27
vendor/github.com/sirupsen/logrus/terminal_check_windows.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// +build !appengine,!js,windows
|
||||
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func checkIfTerminal(w io.Writer) bool {
|
||||
switch v := w.(type) {
|
||||
case *os.File:
|
||||
handle := windows.Handle(v.Fd())
|
||||
var mode uint32
|
||||
if err := windows.GetConsoleMode(handle, &mode); err != nil {
|
||||
return false
|
||||
}
|
||||
mode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
|
||||
if err := windows.SetConsoleMode(handle, mode); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
339
vendor/github.com/sirupsen/logrus/text_formatter.go
generated
vendored
Normal file
339
vendor/github.com/sirupsen/logrus/text_formatter.go
generated
vendored
Normal file
@@ -0,0 +1,339 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
const (
|
||||
red = 31
|
||||
yellow = 33
|
||||
blue = 36
|
||||
gray = 37
|
||||
)
|
||||
|
||||
var baseTimestamp time.Time
|
||||
|
||||
func init() {
|
||||
baseTimestamp = time.Now()
|
||||
}
|
||||
|
||||
// TextFormatter formats logs into text
|
||||
type TextFormatter struct {
|
||||
// Set to true to bypass checking for a TTY before outputting colors.
|
||||
ForceColors bool
|
||||
|
||||
// Force disabling colors.
|
||||
DisableColors bool
|
||||
|
||||
// Force quoting of all values
|
||||
ForceQuote bool
|
||||
|
||||
// DisableQuote disables quoting for all values.
|
||||
// DisableQuote will have a lower priority than ForceQuote.
|
||||
// If both of them are set to true, quote will be forced on all values.
|
||||
DisableQuote bool
|
||||
|
||||
// Override coloring based on CLICOLOR and CLICOLOR_FORCE. - https://bixense.com/clicolors/
|
||||
EnvironmentOverrideColors bool
|
||||
|
||||
// Disable timestamp logging. useful when output is redirected to logging
|
||||
// system that already adds timestamps.
|
||||
DisableTimestamp bool
|
||||
|
||||
// Enable logging the full timestamp when a TTY is attached instead of just
|
||||
// the time passed since beginning of execution.
|
||||
FullTimestamp bool
|
||||
|
||||
// TimestampFormat to use for display when a full timestamp is printed.
|
||||
// The format to use is the same than for time.Format or time.Parse from the standard
|
||||
// library.
|
||||
// The standard Library already provides a set of predefined format.
|
||||
TimestampFormat string
|
||||
|
||||
// The fields are sorted by default for a consistent output. For applications
|
||||
// that log extremely frequently and don't use the JSON formatter this may not
|
||||
// be desired.
|
||||
DisableSorting bool
|
||||
|
||||
// The keys sorting function, when uninitialized it uses sort.Strings.
|
||||
SortingFunc func([]string)
|
||||
|
||||
// Disables the truncation of the level text to 4 characters.
|
||||
DisableLevelTruncation bool
|
||||
|
||||
// PadLevelText Adds padding the level text so that all the levels output at the same length
|
||||
// PadLevelText is a superset of the DisableLevelTruncation option
|
||||
PadLevelText bool
|
||||
|
||||
// QuoteEmptyFields will wrap empty fields in quotes if true
|
||||
QuoteEmptyFields bool
|
||||
|
||||
// Whether the logger's out is to a terminal
|
||||
isTerminal bool
|
||||
|
||||
// FieldMap allows users to customize the names of keys for default fields.
|
||||
// As an example:
|
||||
// formatter := &TextFormatter{
|
||||
// FieldMap: FieldMap{
|
||||
// FieldKeyTime: "@timestamp",
|
||||
// FieldKeyLevel: "@level",
|
||||
// FieldKeyMsg: "@message"}}
|
||||
FieldMap FieldMap
|
||||
|
||||
// CallerPrettyfier can be set by the user to modify the content
|
||||
// of the function and file keys in the data when ReportCaller is
|
||||
// activated. If any of the returned value is the empty string the
|
||||
// corresponding key will be removed from fields.
|
||||
CallerPrettyfier func(*runtime.Frame) (function string, file string)
|
||||
|
||||
terminalInitOnce sync.Once
|
||||
|
||||
// The max length of the level text, generated dynamically on init
|
||||
levelTextMaxLength int
|
||||
}
|
||||
|
||||
func (f *TextFormatter) init(entry *Entry) {
|
||||
if entry.Logger != nil {
|
||||
f.isTerminal = checkIfTerminal(entry.Logger.Out)
|
||||
}
|
||||
// Get the max length of the level text
|
||||
for _, level := range AllLevels {
|
||||
levelTextLength := utf8.RuneCount([]byte(level.String()))
|
||||
if levelTextLength > f.levelTextMaxLength {
|
||||
f.levelTextMaxLength = levelTextLength
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (f *TextFormatter) isColored() bool {
|
||||
isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != "windows"))
|
||||
|
||||
if f.EnvironmentOverrideColors {
|
||||
switch force, ok := os.LookupEnv("CLICOLOR_FORCE"); {
|
||||
case ok && force != "0":
|
||||
isColored = true
|
||||
case ok && force == "0", os.Getenv("CLICOLOR") == "0":
|
||||
isColored = false
|
||||
}
|
||||
}
|
||||
|
||||
return isColored && !f.DisableColors
|
||||
}
|
||||
|
||||
// Format renders a single log entry
|
||||
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||
data := make(Fields)
|
||||
for k, v := range entry.Data {
|
||||
data[k] = v
|
||||
}
|
||||
prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
|
||||
keys := make([]string, 0, len(data))
|
||||
for k := range data {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
var funcVal, fileVal string
|
||||
|
||||
fixedKeys := make([]string, 0, 4+len(data))
|
||||
if !f.DisableTimestamp {
|
||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyTime))
|
||||
}
|
||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLevel))
|
||||
if entry.Message != "" {
|
||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyMsg))
|
||||
}
|
||||
if entry.err != "" {
|
||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyLogrusError))
|
||||
}
|
||||
if entry.HasCaller() {
|
||||
if f.CallerPrettyfier != nil {
|
||||
funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
|
||||
} else {
|
||||
funcVal = entry.Caller.Function
|
||||
fileVal = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
|
||||
}
|
||||
|
||||
if funcVal != "" {
|
||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyFunc))
|
||||
}
|
||||
if fileVal != "" {
|
||||
fixedKeys = append(fixedKeys, f.FieldMap.resolve(FieldKeyFile))
|
||||
}
|
||||
}
|
||||
|
||||
if !f.DisableSorting {
|
||||
if f.SortingFunc == nil {
|
||||
sort.Strings(keys)
|
||||
fixedKeys = append(fixedKeys, keys...)
|
||||
} else {
|
||||
if !f.isColored() {
|
||||
fixedKeys = append(fixedKeys, keys...)
|
||||
f.SortingFunc(fixedKeys)
|
||||
} else {
|
||||
f.SortingFunc(keys)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fixedKeys = append(fixedKeys, keys...)
|
||||
}
|
||||
|
||||
var b *bytes.Buffer
|
||||
if entry.Buffer != nil {
|
||||
b = entry.Buffer
|
||||
} else {
|
||||
b = &bytes.Buffer{}
|
||||
}
|
||||
|
||||
f.terminalInitOnce.Do(func() { f.init(entry) })
|
||||
|
||||
timestampFormat := f.TimestampFormat
|
||||
if timestampFormat == "" {
|
||||
timestampFormat = defaultTimestampFormat
|
||||
}
|
||||
if f.isColored() {
|
||||
f.printColored(b, entry, keys, data, timestampFormat)
|
||||
} else {
|
||||
|
||||
for _, key := range fixedKeys {
|
||||
var value interface{}
|
||||
switch {
|
||||
case key == f.FieldMap.resolve(FieldKeyTime):
|
||||
value = entry.Time.Format(timestampFormat)
|
||||
case key == f.FieldMap.resolve(FieldKeyLevel):
|
||||
value = entry.Level.String()
|
||||
case key == f.FieldMap.resolve(FieldKeyMsg):
|
||||
value = entry.Message
|
||||
case key == f.FieldMap.resolve(FieldKeyLogrusError):
|
||||
value = entry.err
|
||||
case key == f.FieldMap.resolve(FieldKeyFunc) && entry.HasCaller():
|
||||
value = funcVal
|
||||
case key == f.FieldMap.resolve(FieldKeyFile) && entry.HasCaller():
|
||||
value = fileVal
|
||||
default:
|
||||
value = data[key]
|
||||
}
|
||||
f.appendKeyValue(b, key, value)
|
||||
}
|
||||
}
|
||||
|
||||
b.WriteByte('\n')
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []string, data Fields, timestampFormat string) {
|
||||
var levelColor int
|
||||
switch entry.Level {
|
||||
case DebugLevel, TraceLevel:
|
||||
levelColor = gray
|
||||
case WarnLevel:
|
||||
levelColor = yellow
|
||||
case ErrorLevel, FatalLevel, PanicLevel:
|
||||
levelColor = red
|
||||
case InfoLevel:
|
||||
levelColor = blue
|
||||
default:
|
||||
levelColor = blue
|
||||
}
|
||||
|
||||
levelText := strings.ToUpper(entry.Level.String())
|
||||
if !f.DisableLevelTruncation && !f.PadLevelText {
|
||||
levelText = levelText[0:4]
|
||||
}
|
||||
if f.PadLevelText {
|
||||
// Generates the format string used in the next line, for example "%-6s" or "%-7s".
|
||||
// Based on the max level text length.
|
||||
formatString := "%-" + strconv.Itoa(f.levelTextMaxLength) + "s"
|
||||
// Formats the level text by appending spaces up to the max length, for example:
|
||||
// - "INFO "
|
||||
// - "WARNING"
|
||||
levelText = fmt.Sprintf(formatString, levelText)
|
||||
}
|
||||
|
||||
// Remove a single newline if it already exists in the message to keep
|
||||
// the behavior of logrus text_formatter the same as the stdlib log package
|
||||
entry.Message = strings.TrimSuffix(entry.Message, "\n")
|
||||
|
||||
caller := ""
|
||||
if entry.HasCaller() {
|
||||
funcVal := fmt.Sprintf("%s()", entry.Caller.Function)
|
||||
fileVal := fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
|
||||
|
||||
if f.CallerPrettyfier != nil {
|
||||
funcVal, fileVal = f.CallerPrettyfier(entry.Caller)
|
||||
}
|
||||
|
||||
if fileVal == "" {
|
||||
caller = funcVal
|
||||
} else if funcVal == "" {
|
||||
caller = fileVal
|
||||
} else {
|
||||
caller = fileVal + " " + funcVal
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case f.DisableTimestamp:
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m%s %-44s ", levelColor, levelText, caller, entry.Message)
|
||||
case !f.FullTimestamp:
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d]%s %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), caller, entry.Message)
|
||||
default:
|
||||
fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message)
|
||||
}
|
||||
for _, k := range keys {
|
||||
v := data[k]
|
||||
fmt.Fprintf(b, " \x1b[%dm%s\x1b[0m=", levelColor, k)
|
||||
f.appendValue(b, v)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *TextFormatter) needsQuoting(text string) bool {
|
||||
if f.ForceQuote {
|
||||
return true
|
||||
}
|
||||
if f.QuoteEmptyFields && len(text) == 0 {
|
||||
return true
|
||||
}
|
||||
if f.DisableQuote {
|
||||
return false
|
||||
}
|
||||
for _, ch := range text {
|
||||
if !((ch >= 'a' && ch <= 'z') ||
|
||||
(ch >= 'A' && ch <= 'Z') ||
|
||||
(ch >= '0' && ch <= '9') ||
|
||||
ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
||||
if b.Len() > 0 {
|
||||
b.WriteByte(' ')
|
||||
}
|
||||
b.WriteString(key)
|
||||
b.WriteByte('=')
|
||||
f.appendValue(b, value)
|
||||
}
|
||||
|
||||
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
||||
stringVal, ok := value.(string)
|
||||
if !ok {
|
||||
stringVal = fmt.Sprint(value)
|
||||
}
|
||||
|
||||
if !f.needsQuoting(stringVal) {
|
||||
b.WriteString(stringVal)
|
||||
} else {
|
||||
b.WriteString(fmt.Sprintf("%q", stringVal))
|
||||
}
|
||||
}
|
||||
70
vendor/github.com/sirupsen/logrus/writer.go
generated
vendored
Normal file
70
vendor/github.com/sirupsen/logrus/writer.go
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
package logrus
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Writer at INFO level. See WriterLevel for details.
|
||||
func (logger *Logger) Writer() *io.PipeWriter {
|
||||
return logger.WriterLevel(InfoLevel)
|
||||
}
|
||||
|
||||
// WriterLevel returns an io.Writer that can be used to write arbitrary text to
|
||||
// the logger at the given log level. Each line written to the writer will be
|
||||
// printed in the usual way using formatters and hooks. The writer is part of an
|
||||
// io.Pipe and it is the callers responsibility to close the writer when done.
|
||||
// This can be used to override the standard library logger easily.
|
||||
func (logger *Logger) WriterLevel(level Level) *io.PipeWriter {
|
||||
return NewEntry(logger).WriterLevel(level)
|
||||
}
|
||||
|
||||
func (entry *Entry) Writer() *io.PipeWriter {
|
||||
return entry.WriterLevel(InfoLevel)
|
||||
}
|
||||
|
||||
func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
|
||||
reader, writer := io.Pipe()
|
||||
|
||||
var printFunc func(args ...interface{})
|
||||
|
||||
switch level {
|
||||
case TraceLevel:
|
||||
printFunc = entry.Trace
|
||||
case DebugLevel:
|
||||
printFunc = entry.Debug
|
||||
case InfoLevel:
|
||||
printFunc = entry.Info
|
||||
case WarnLevel:
|
||||
printFunc = entry.Warn
|
||||
case ErrorLevel:
|
||||
printFunc = entry.Error
|
||||
case FatalLevel:
|
||||
printFunc = entry.Fatal
|
||||
case PanicLevel:
|
||||
printFunc = entry.Panic
|
||||
default:
|
||||
printFunc = entry.Print
|
||||
}
|
||||
|
||||
go entry.writerScanner(reader, printFunc)
|
||||
runtime.SetFinalizer(writer, writerFinalizer)
|
||||
|
||||
return writer
|
||||
}
|
||||
|
||||
func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) {
|
||||
scanner := bufio.NewScanner(reader)
|
||||
for scanner.Scan() {
|
||||
printFunc(scanner.Text())
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
entry.Errorf("Error while reading from Writer: %s", err)
|
||||
}
|
||||
reader.Close()
|
||||
}
|
||||
|
||||
func writerFinalizer(writer *io.PipeWriter) {
|
||||
writer.Close()
|
||||
}
|
||||
3
vendor/golang.org/x/sys/AUTHORS
generated
vendored
Normal file
3
vendor/golang.org/x/sys/AUTHORS
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# This source code refers to The Go Authors for copyright purposes.
|
||||
# The master list of authors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/AUTHORS.
|
||||
3
vendor/golang.org/x/sys/CONTRIBUTORS
generated
vendored
Normal file
3
vendor/golang.org/x/sys/CONTRIBUTORS
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# This source code was written by the Go contributors.
|
||||
# The master list of contributors is in the main Go distribution,
|
||||
# visible at http://tip.golang.org/CONTRIBUTORS.
|
||||
27
vendor/golang.org/x/sys/LICENSE
generated
vendored
Normal file
27
vendor/golang.org/x/sys/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
22
vendor/golang.org/x/sys/PATENTS
generated
vendored
Normal file
22
vendor/golang.org/x/sys/PATENTS
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Additional IP Rights Grant (Patents)
|
||||
|
||||
"This implementation" means the copyrightable works distributed by
|
||||
Google as part of the Go project.
|
||||
|
||||
Google hereby grants to You a perpetual, worldwide, non-exclusive,
|
||||
no-charge, royalty-free, irrevocable (except as stated in this section)
|
||||
patent license to make, have made, use, offer to sell, sell, import,
|
||||
transfer and otherwise run, modify and propagate the contents of this
|
||||
implementation of Go, where such license applies only to those patent
|
||||
claims, both currently owned or controlled by Google and acquired in
|
||||
the future, licensable by Google that are necessarily infringed by this
|
||||
implementation of Go. This grant does not include claims that would be
|
||||
infringed only as a consequence of further modification of this
|
||||
implementation. If you or your agent or exclusive licensee institute or
|
||||
order or agree to the institution of patent litigation against any
|
||||
entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that this implementation of Go or any code incorporated within this
|
||||
implementation of Go constitutes direct or contributory patent
|
||||
infringement, or inducement of patent infringement, then any patent
|
||||
rights granted to you under this License for this implementation of Go
|
||||
shall terminate as of the date such litigation is filed.
|
||||
2
vendor/golang.org/x/sys/unix/.gitignore
generated
vendored
Normal file
2
vendor/golang.org/x/sys/unix/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
_obj/
|
||||
unix.test
|
||||
173
vendor/golang.org/x/sys/unix/README.md
generated
vendored
Normal file
173
vendor/golang.org/x/sys/unix/README.md
generated
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
# Building `sys/unix`
|
||||
|
||||
The sys/unix package provides access to the raw system call interface of the
|
||||
underlying operating system. See: https://godoc.org/golang.org/x/sys/unix
|
||||
|
||||
Porting Go to a new architecture/OS combination or adding syscalls, types, or
|
||||
constants to an existing architecture/OS pair requires some manual effort;
|
||||
however, there are tools that automate much of the process.
|
||||
|
||||
## Build Systems
|
||||
|
||||
There are currently two ways we generate the necessary files. We are currently
|
||||
migrating the build system to use containers so the builds are reproducible.
|
||||
This is being done on an OS-by-OS basis. Please update this documentation as
|
||||
components of the build system change.
|
||||
|
||||
### Old Build System (currently for `GOOS != "linux"`)
|
||||
|
||||
The old build system generates the Go files based on the C header files
|
||||
present on your system. This means that files
|
||||
for a given GOOS/GOARCH pair must be generated on a system with that OS and
|
||||
architecture. This also means that the generated code can differ from system
|
||||
to system, based on differences in the header files.
|
||||
|
||||
To avoid this, if you are using the old build system, only generate the Go
|
||||
files on an installation with unmodified header files. It is also important to
|
||||
keep track of which version of the OS the files were generated from (ex.
|
||||
Darwin 14 vs Darwin 15). This makes it easier to track the progress of changes
|
||||
and have each OS upgrade correspond to a single change.
|
||||
|
||||
To build the files for your current OS and architecture, make sure GOOS and
|
||||
GOARCH are set correctly and run `mkall.sh`. This will generate the files for
|
||||
your specific system. Running `mkall.sh -n` shows the commands that will be run.
|
||||
|
||||
Requirements: bash, go
|
||||
|
||||
### New Build System (currently for `GOOS == "linux"`)
|
||||
|
||||
The new build system uses a Docker container to generate the go files directly
|
||||
from source checkouts of the kernel and various system libraries. This means
|
||||
that on any platform that supports Docker, all the files using the new build
|
||||
system can be generated at once, and generated files will not change based on
|
||||
what the person running the scripts has installed on their computer.
|
||||
|
||||
The OS specific files for the new build system are located in the `${GOOS}`
|
||||
directory, and the build is coordinated by the `${GOOS}/mkall.go` program. When
|
||||
the kernel or system library updates, modify the Dockerfile at
|
||||
`${GOOS}/Dockerfile` to checkout the new release of the source.
|
||||
|
||||
To build all the files under the new build system, you must be on an amd64/Linux
|
||||
system and have your GOOS and GOARCH set accordingly. Running `mkall.sh` will
|
||||
then generate all of the files for all of the GOOS/GOARCH pairs in the new build
|
||||
system. Running `mkall.sh -n` shows the commands that will be run.
|
||||
|
||||
Requirements: bash, go, docker
|
||||
|
||||
## Component files
|
||||
|
||||
This section describes the various files used in the code generation process.
|
||||
It also contains instructions on how to modify these files to add a new
|
||||
architecture/OS or to add additional syscalls, types, or constants. Note that
|
||||
if you are using the new build system, the scripts/programs cannot be called normally.
|
||||
They must be called from within the docker container.
|
||||
|
||||
### asm files
|
||||
|
||||
The hand-written assembly file at `asm_${GOOS}_${GOARCH}.s` implements system
|
||||
call dispatch. There are three entry points:
|
||||
```
|
||||
func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
||||
func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
|
||||
func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
|
||||
```
|
||||
The first and second are the standard ones; they differ only in how many
|
||||
arguments can be passed to the kernel. The third is for low-level use by the
|
||||
ForkExec wrapper. Unlike the first two, it does not call into the scheduler to
|
||||
let it know that a system call is running.
|
||||
|
||||
When porting Go to an new architecture/OS, this file must be implemented for
|
||||
each GOOS/GOARCH pair.
|
||||
|
||||
### mksysnum
|
||||
|
||||
Mksysnum is a Go program located at `${GOOS}/mksysnum.go` (or `mksysnum_${GOOS}.go`
|
||||
for the old system). This program takes in a list of header files containing the
|
||||
syscall number declarations and parses them to produce the corresponding list of
|
||||
Go numeric constants. See `zsysnum_${GOOS}_${GOARCH}.go` for the generated
|
||||
constants.
|
||||
|
||||
Adding new syscall numbers is mostly done by running the build on a sufficiently
|
||||
new installation of the target OS (or updating the source checkouts for the
|
||||
new build system). However, depending on the OS, you make need to update the
|
||||
parsing in mksysnum.
|
||||
|
||||
### mksyscall.go
|
||||
|
||||
The `syscall.go`, `syscall_${GOOS}.go`, `syscall_${GOOS}_${GOARCH}.go` are
|
||||
hand-written Go files which implement system calls (for unix, the specific OS,
|
||||
or the specific OS/Architecture pair respectively) that need special handling
|
||||
and list `//sys` comments giving prototypes for ones that can be generated.
|
||||
|
||||
The mksyscall.go program takes the `//sys` and `//sysnb` comments and converts
|
||||
them into syscalls. This requires the name of the prototype in the comment to
|
||||
match a syscall number in the `zsysnum_${GOOS}_${GOARCH}.go` file. The function
|
||||
prototype can be exported (capitalized) or not.
|
||||
|
||||
Adding a new syscall often just requires adding a new `//sys` function prototype
|
||||
with the desired arguments and a capitalized name so it is exported. However, if
|
||||
you want the interface to the syscall to be different, often one will make an
|
||||
unexported `//sys` prototype, an then write a custom wrapper in
|
||||
`syscall_${GOOS}.go`.
|
||||
|
||||
### types files
|
||||
|
||||
For each OS, there is a hand-written Go file at `${GOOS}/types.go` (or
|
||||
`types_${GOOS}.go` on the old system). This file includes standard C headers and
|
||||
creates Go type aliases to the corresponding C types. The file is then fed
|
||||
through godef to get the Go compatible definitions. Finally, the generated code
|
||||
is fed though mkpost.go to format the code correctly and remove any hidden or
|
||||
private identifiers. This cleaned-up code is written to
|
||||
`ztypes_${GOOS}_${GOARCH}.go`.
|
||||
|
||||
The hardest part about preparing this file is figuring out which headers to
|
||||
include and which symbols need to be `#define`d to get the actual data
|
||||
structures that pass through to the kernel system calls. Some C libraries
|
||||
preset alternate versions for binary compatibility and translate them on the
|
||||
way in and out of system calls, but there is almost always a `#define` that can
|
||||
get the real ones.
|
||||
See `types_darwin.go` and `linux/types.go` for examples.
|
||||
|
||||
To add a new type, add in the necessary include statement at the top of the
|
||||
file (if it is not already there) and add in a type alias line. Note that if
|
||||
your type is significantly different on different architectures, you may need
|
||||
some `#if/#elif` macros in your include statements.
|
||||
|
||||
### mkerrors.sh
|
||||
|
||||
This script is used to generate the system's various constants. This doesn't
|
||||
just include the error numbers and error strings, but also the signal numbers
|
||||
an a wide variety of miscellaneous constants. The constants come from the list
|
||||
of include files in the `includes_${uname}` variable. A regex then picks out
|
||||
the desired `#define` statements, and generates the corresponding Go constants.
|
||||
The error numbers and strings are generated from `#include <errno.h>`, and the
|
||||
signal numbers and strings are generated from `#include <signal.h>`. All of
|
||||
these constants are written to `zerrors_${GOOS}_${GOARCH}.go` via a C program,
|
||||
`_errors.c`, which prints out all the constants.
|
||||
|
||||
To add a constant, add the header that includes it to the appropriate variable.
|
||||
Then, edit the regex (if necessary) to match the desired constant. Avoid making
|
||||
the regex too broad to avoid matching unintended constants.
|
||||
|
||||
|
||||
## Generated files
|
||||
|
||||
### `zerror_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A file containing all of the system's generated error numbers, error strings,
|
||||
signal numbers, and constants. Generated by `mkerrors.sh` (see above).
|
||||
|
||||
### `zsyscall_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A file containing all the generated syscalls for a specific GOOS and GOARCH.
|
||||
Generated by `mksyscall.go` (see above).
|
||||
|
||||
### `zsysnum_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A list of numeric constants for all the syscall number of the specific GOOS
|
||||
and GOARCH. Generated by mksysnum (see above).
|
||||
|
||||
### `ztypes_${GOOS}_${GOARCH}.go`
|
||||
|
||||
A file containing Go types for passing into (or returning from) syscalls.
|
||||
Generated by godefs and the types file (see above).
|
||||
86
vendor/golang.org/x/sys/unix/affinity_linux.go
generated
vendored
Normal file
86
vendor/golang.org/x/sys/unix/affinity_linux.go
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// CPU affinity functions
|
||||
|
||||
package unix
|
||||
|
||||
import (
|
||||
"math/bits"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const cpuSetSize = _CPU_SETSIZE / _NCPUBITS
|
||||
|
||||
// CPUSet represents a CPU affinity mask.
|
||||
type CPUSet [cpuSetSize]cpuMask
|
||||
|
||||
func schedAffinity(trap uintptr, pid int, set *CPUSet) error {
|
||||
_, _, e := RawSyscall(trap, uintptr(pid), uintptr(unsafe.Sizeof(*set)), uintptr(unsafe.Pointer(set)))
|
||||
if e != 0 {
|
||||
return errnoErr(e)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SchedGetaffinity gets the CPU affinity mask of the thread specified by pid.
|
||||
// If pid is 0 the calling thread is used.
|
||||
func SchedGetaffinity(pid int, set *CPUSet) error {
|
||||
return schedAffinity(SYS_SCHED_GETAFFINITY, pid, set)
|
||||
}
|
||||
|
||||
// SchedSetaffinity sets the CPU affinity mask of the thread specified by pid.
|
||||
// If pid is 0 the calling thread is used.
|
||||
func SchedSetaffinity(pid int, set *CPUSet) error {
|
||||
return schedAffinity(SYS_SCHED_SETAFFINITY, pid, set)
|
||||
}
|
||||
|
||||
// Zero clears the set s, so that it contains no CPUs.
|
||||
func (s *CPUSet) Zero() {
|
||||
for i := range s {
|
||||
s[i] = 0
|
||||
}
|
||||
}
|
||||
|
||||
func cpuBitsIndex(cpu int) int {
|
||||
return cpu / _NCPUBITS
|
||||
}
|
||||
|
||||
func cpuBitsMask(cpu int) cpuMask {
|
||||
return cpuMask(1 << (uint(cpu) % _NCPUBITS))
|
||||
}
|
||||
|
||||
// Set adds cpu to the set s.
|
||||
func (s *CPUSet) Set(cpu int) {
|
||||
i := cpuBitsIndex(cpu)
|
||||
if i < len(s) {
|
||||
s[i] |= cpuBitsMask(cpu)
|
||||
}
|
||||
}
|
||||
|
||||
// Clear removes cpu from the set s.
|
||||
func (s *CPUSet) Clear(cpu int) {
|
||||
i := cpuBitsIndex(cpu)
|
||||
if i < len(s) {
|
||||
s[i] &^= cpuBitsMask(cpu)
|
||||
}
|
||||
}
|
||||
|
||||
// IsSet reports whether cpu is in the set s.
|
||||
func (s *CPUSet) IsSet(cpu int) bool {
|
||||
i := cpuBitsIndex(cpu)
|
||||
if i < len(s) {
|
||||
return s[i]&cpuBitsMask(cpu) != 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Count returns the number of CPUs in the set s.
|
||||
func (s *CPUSet) Count() int {
|
||||
c := 0
|
||||
for _, b := range s {
|
||||
c += bits.OnesCount64(uint64(b))
|
||||
}
|
||||
return c
|
||||
}
|
||||
14
vendor/golang.org/x/sys/unix/aliases.go
generated
vendored
Normal file
14
vendor/golang.org/x/sys/unix/aliases.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
|
||||
// +build go1.9
|
||||
|
||||
package unix
|
||||
|
||||
import "syscall"
|
||||
|
||||
type Signal = syscall.Signal
|
||||
type Errno = syscall.Errno
|
||||
type SysProcAttr = syscall.SysProcAttr
|
||||
17
vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
generated
vendored
Normal file
17
vendor/golang.org/x/sys/unix/asm_aix_ppc64.s
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System calls for ppc64, AIX are implemented in runtime/syscall_aix.go
|
||||
//
|
||||
|
||||
TEXT ·syscall6(SB),NOSPLIT,$0-88
|
||||
JMP syscall·syscall6(SB)
|
||||
|
||||
TEXT ·rawSyscall6(SB),NOSPLIT,$0-88
|
||||
JMP syscall·rawSyscall6(SB)
|
||||
29
vendor/golang.org/x/sys/unix/asm_darwin_386.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_darwin_386.s
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for 386, Darwin
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
29
vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
generated
vendored
Normal file
29
vendor/golang.org/x/sys/unix/asm_darwin_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for AMD64, Darwin
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-104
|
||||
JMP syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-56
|
||||
JMP syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
|
||||
JMP syscall·RawSyscall6(SB)
|
||||
30
vendor/golang.org/x/sys/unix/asm_darwin_arm.s
generated
vendored
Normal file
30
vendor/golang.org/x/sys/unix/asm_darwin_arm.s
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !gccgo
|
||||
// +build arm,darwin
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
//
|
||||
// System call support for ARM, Darwin
|
||||
//
|
||||
|
||||
// Just jump to package syscall's implementation for all these functions.
|
||||
// The runtime may know about them.
|
||||
|
||||
TEXT ·Syscall(SB),NOSPLIT,$0-28
|
||||
B syscall·Syscall(SB)
|
||||
|
||||
TEXT ·Syscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·Syscall6(SB)
|
||||
|
||||
TEXT ·Syscall9(SB),NOSPLIT,$0-52
|
||||
B syscall·Syscall9(SB)
|
||||
|
||||
TEXT ·RawSyscall(SB),NOSPLIT,$0-28
|
||||
B syscall·RawSyscall(SB)
|
||||
|
||||
TEXT ·RawSyscall6(SB),NOSPLIT,$0-40
|
||||
B syscall·RawSyscall6(SB)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user