diff options
Diffstat (limited to 'vendor/github.com')
98 files changed, 981 insertions, 3712 deletions
diff --git a/vendor/github.com/Microsoft/go-winio/README.md b/vendor/github.com/Microsoft/go-winio/README.md index 60c93fe50..683be1dcf 100644 --- a/vendor/github.com/Microsoft/go-winio/README.md +++ b/vendor/github.com/Microsoft/go-winio/README.md @@ -11,12 +11,27 @@ package. Please see the LICENSE file for licensing information. -This project has adopted the [Microsoft Open Source Code of -Conduct](https://opensource.microsoft.com/codeofconduct/). For more information -see the [Code of Conduct -FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact -[opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional -questions or comments. +## Contributing +This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) +declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com. + +When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR +appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA. + +We also require that contributors sign their commits using git commit -s or git commit --signoff to certify they either authored the work themselves +or otherwise have permission to use it in this project. Please see https://developercertificate.org/ for more info, as well as to make sure that you can +attest to the rules listed. Our CI uses the DCO Github app to ensure that all commits in a given PR are signed-off. + + +## Code of Conduct + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). +For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or +contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + + + +## Special Thanks Thanks to natefinch for the inspiration for this library. See https://github.com/natefinch/npipe for another named pipe implementation. diff --git a/vendor/github.com/Microsoft/go-winio/backuptar/tar.go b/vendor/github.com/Microsoft/go-winio/backuptar/tar.go index cb461ca31..689e4da6b 100644 --- a/vendor/github.com/Microsoft/go-winio/backuptar/tar.go +++ b/vendor/github.com/Microsoft/go-winio/backuptar/tar.go @@ -5,7 +5,6 @@ package backuptar import ( "archive/tar" "encoding/base64" - "errors" "fmt" "io" "io/ioutil" @@ -42,19 +41,14 @@ const ( hdrCreationTime = "LIBARCHIVE.creationtime" ) -func writeZeroes(w io.Writer, count int64) error { - buf := make([]byte, 8192) - c := len(buf) - for i := int64(0); i < count; i += int64(c) { - if int64(c) > count-i { - c = int(count - i) - } - _, err := w.Write(buf[:c]) - if err != nil { - return err - } +// zeroReader is an io.Reader that always returns 0s. +type zeroReader struct{} + +func (zr zeroReader) Read(b []byte) (int, error) { + for i := range b { + b[i] = 0 } - return nil + return len(b), nil } func copySparse(t *tar.Writer, br *winio.BackupStreamReader) error { @@ -71,16 +65,26 @@ func copySparse(t *tar.Writer, br *winio.BackupStreamReader) error { return fmt.Errorf("unexpected stream %d", bhdr.Id) } + // We can't seek backwards, since we have already written that data to the tar.Writer. + if bhdr.Offset < curOffset { + return fmt.Errorf("cannot seek back from %d to %d", curOffset, bhdr.Offset) + } // archive/tar does not support writing sparse files // so just write zeroes to catch up to the current offset. - err = writeZeroes(t, bhdr.Offset-curOffset) + if _, err := io.CopyN(t, zeroReader{}, bhdr.Offset-curOffset); err != nil { + return fmt.Errorf("seek to offset %d: %s", bhdr.Offset, err) + } if bhdr.Size == 0 { + // A sparse block with size = 0 is used to mark the end of the sparse blocks. break } n, err := io.Copy(t, br) if err != nil { return err } + if n != bhdr.Size { + return fmt.Errorf("copied %d bytes instead of %d at offset %d", n, bhdr.Size, bhdr.Offset) + } curOffset = bhdr.Offset + n } return nil @@ -221,20 +225,44 @@ func WriteTarFileFromBackupStream(t *tar.Writer, r io.Reader, name string, size } } + // The logic for copying file contents is fairly complicated due to the need for handling sparse files, + // and the weird ways they are represented by BackupRead. A normal file will always either have a data stream + // with size and content, or no data stream at all (if empty). However, for a sparse file, the content can also + // be represented using a series of sparse block streams following the data stream. Additionally, the way sparse + // files are handled by BackupRead has changed in the OS recently. The specifics of the representation are described + // in the list at the bottom of this block comment. + // + // Sparse files can be represented in four different ways, based on the specifics of the file. + // - Size = 0: + // Previously: BackupRead yields no data stream and no sparse block streams. + // Recently: BackupRead yields a data stream with size = 0. There are no following sparse block streams. + // - Size > 0, no allocated ranges: + // BackupRead yields a data stream with size = 0. Following is a single sparse block stream with + // size = 0 and offset = <file size>. + // - Size > 0, one allocated range: + // BackupRead yields a data stream with size = <file size> containing the file contents. There are no + // sparse block streams. This is the case if you take a normal file with contents and simply set the + // sparse flag on it. + // - Size > 0, multiple allocated ranges: + // BackupRead yields a data stream with size = 0. Following are sparse block streams for each allocated + // range of the file containing the range contents. Finally there is a sparse block stream with + // size = 0 and offset = <file size>. + if dataHdr != nil { // A data stream was found. Copy the data. - if (dataHdr.Attributes & winio.StreamSparseAttributes) == 0 { + // We assume that we will either have a data stream size > 0 XOR have sparse block streams. + if dataHdr.Size > 0 || (dataHdr.Attributes&winio.StreamSparseAttributes) == 0 { if size != dataHdr.Size { return fmt.Errorf("%s: mismatch between file size %d and header size %d", name, size, dataHdr.Size) } - _, err = io.Copy(t, br) - if err != nil { - return err + if _, err = io.Copy(t, br); err != nil { + return fmt.Errorf("%s: copying contents from data stream: %s", name, err) } - } else { - err = copySparse(t, br) - if err != nil { - return err + } else if size > 0 { + // As of a recent OS change, BackupRead now returns a data stream for empty sparse files. + // These files have no sparse block streams, so skip the copySparse call if file size = 0. + if err = copySparse(t, br); err != nil { + return fmt.Errorf("%s: copying contents from sparse block stream: %s", name, err) } } } @@ -279,7 +307,7 @@ func WriteTarFileFromBackupStream(t *tar.Writer, r io.Reader, name string, size } else { // Unsupported for now, since the size of the alternate stream is not present // in the backup stream until after the data has been read. - return errors.New("tar of sparse alternate data streams is unsupported") + return fmt.Errorf("%s: tar of sparse alternate data streams is unsupported", name) } case winio.BackupEaData, winio.BackupLink, winio.BackupPropertyData, winio.BackupObjectId, winio.BackupTxfsData: // ignore these streams diff --git a/vendor/github.com/Microsoft/go-winio/pkg/security/syscall_windows.go b/vendor/github.com/Microsoft/go-winio/pkg/security/syscall_windows.go index c40c2739b..d7096716c 100644 --- a/vendor/github.com/Microsoft/go-winio/pkg/security/syscall_windows.go +++ b/vendor/github.com/Microsoft/go-winio/pkg/security/syscall_windows.go @@ -2,6 +2,6 @@ package security //go:generate go run mksyscall_windows.go -output zsyscall_windows.go syscall_windows.go -//sys getSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, ppsidOwner **uintptr, ppsidGroup **uintptr, ppDacl *uintptr, ppSacl *uintptr, ppSecurityDescriptor *uintptr) (err error) [failretval!=0] = advapi32.GetSecurityInfo -//sys setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOwner uintptr, psidGroup uintptr, pDacl uintptr, pSacl uintptr) (err error) [failretval!=0] = advapi32.SetSecurityInfo -//sys setEntriesInAcl(count uintptr, pListOfEEs uintptr, oldAcl uintptr, newAcl *uintptr) (err error) [failretval!=0] = advapi32.SetEntriesInAclW +//sys getSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, ppsidOwner **uintptr, ppsidGroup **uintptr, ppDacl *uintptr, ppSacl *uintptr, ppSecurityDescriptor *uintptr) (win32err error) = advapi32.GetSecurityInfo +//sys setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOwner uintptr, psidGroup uintptr, pDacl uintptr, pSacl uintptr) (win32err error) = advapi32.SetSecurityInfo +//sys setEntriesInAcl(count uintptr, pListOfEEs uintptr, oldAcl uintptr, newAcl *uintptr) (win32err error) = advapi32.SetEntriesInAclW diff --git a/vendor/github.com/Microsoft/go-winio/pkg/security/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/pkg/security/zsyscall_windows.go index 4a90cb3cc..4084680e0 100644 --- a/vendor/github.com/Microsoft/go-winio/pkg/security/zsyscall_windows.go +++ b/vendor/github.com/Microsoft/go-winio/pkg/security/zsyscall_windows.go @@ -45,26 +45,26 @@ var ( procSetSecurityInfo = modadvapi32.NewProc("SetSecurityInfo") ) -func getSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, ppsidOwner **uintptr, ppsidGroup **uintptr, ppDacl *uintptr, ppSacl *uintptr, ppSecurityDescriptor *uintptr) (err error) { - r1, _, e1 := syscall.Syscall9(procGetSecurityInfo.Addr(), 8, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(unsafe.Pointer(ppsidOwner)), uintptr(unsafe.Pointer(ppsidGroup)), uintptr(unsafe.Pointer(ppDacl)), uintptr(unsafe.Pointer(ppSacl)), uintptr(unsafe.Pointer(ppSecurityDescriptor)), 0) - if r1 != 0 { - err = errnoErr(e1) +func getSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, ppsidOwner **uintptr, ppsidGroup **uintptr, ppDacl *uintptr, ppSacl *uintptr, ppSecurityDescriptor *uintptr) (win32err error) { + r0, _, _ := syscall.Syscall9(procGetSecurityInfo.Addr(), 8, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(unsafe.Pointer(ppsidOwner)), uintptr(unsafe.Pointer(ppsidGroup)), uintptr(unsafe.Pointer(ppDacl)), uintptr(unsafe.Pointer(ppSacl)), uintptr(unsafe.Pointer(ppSecurityDescriptor)), 0) + if r0 != 0 { + win32err = syscall.Errno(r0) } return } -func setEntriesInAcl(count uintptr, pListOfEEs uintptr, oldAcl uintptr, newAcl *uintptr) (err error) { - r1, _, e1 := syscall.Syscall6(procSetEntriesInAclW.Addr(), 4, uintptr(count), uintptr(pListOfEEs), uintptr(oldAcl), uintptr(unsafe.Pointer(newAcl)), 0, 0) - if r1 != 0 { - err = errnoErr(e1) +func setEntriesInAcl(count uintptr, pListOfEEs uintptr, oldAcl uintptr, newAcl *uintptr) (win32err error) { + r0, _, _ := syscall.Syscall6(procSetEntriesInAclW.Addr(), 4, uintptr(count), uintptr(pListOfEEs), uintptr(oldAcl), uintptr(unsafe.Pointer(newAcl)), 0, 0) + if r0 != 0 { + win32err = syscall.Errno(r0) } return } -func setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOwner uintptr, psidGroup uintptr, pDacl uintptr, pSacl uintptr) (err error) { - r1, _, e1 := syscall.Syscall9(procSetSecurityInfo.Addr(), 7, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(psidOwner), uintptr(psidGroup), uintptr(pDacl), uintptr(pSacl), 0, 0) - if r1 != 0 { - err = errnoErr(e1) +func setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOwner uintptr, psidGroup uintptr, pDacl uintptr, pSacl uintptr) (win32err error) { + r0, _, _ := syscall.Syscall9(procSetSecurityInfo.Addr(), 7, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(psidOwner), uintptr(psidGroup), uintptr(pDacl), uintptr(pSacl), 0, 0) + if r0 != 0 { + win32err = syscall.Errno(r0) } return } diff --git a/vendor/github.com/Microsoft/go-winio/vhd/vhd.go b/vendor/github.com/Microsoft/go-winio/vhd/vhd.go index b03b789e6..a33a36c0f 100644 --- a/vendor/github.com/Microsoft/go-winio/vhd/vhd.go +++ b/vendor/github.com/Microsoft/go-winio/vhd/vhd.go @@ -13,11 +13,11 @@ import ( //go:generate go run mksyscall_windows.go -output zvhd_windows.go vhd.go -//sys createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (err error) [failretval != 0] = virtdisk.CreateVirtualDisk -//sys openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (err error) [failretval != 0] = virtdisk.OpenVirtualDisk -//sys attachVirtualDisk(handle syscall.Handle, securityDescriptor *uintptr, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (err error) [failretval != 0] = virtdisk.AttachVirtualDisk -//sys detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, providerSpecificFlags uint32) (err error) [failretval != 0] = virtdisk.DetachVirtualDisk -//sys getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint32, buffer *uint16) (err error) [failretval != 0] = virtdisk.GetVirtualDiskPhysicalPath +//sys createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (win32err error) = virtdisk.CreateVirtualDisk +//sys openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (win32err error) = virtdisk.OpenVirtualDisk +//sys attachVirtualDisk(handle syscall.Handle, securityDescriptor *uintptr, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (win32err error) = virtdisk.AttachVirtualDisk +//sys detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, providerSpecificFlags uint32) (win32err error) = virtdisk.DetachVirtualDisk +//sys getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint32, buffer *uint16) (win32err error) = virtdisk.GetVirtualDiskPhysicalPath type ( CreateVirtualDiskFlag uint32 diff --git a/vendor/github.com/Microsoft/go-winio/vhd/zvhd_windows.go b/vendor/github.com/Microsoft/go-winio/vhd/zvhd_windows.go index 572f7b42f..7fb5f3651 100644 --- a/vendor/github.com/Microsoft/go-winio/vhd/zvhd_windows.go +++ b/vendor/github.com/Microsoft/go-winio/vhd/zvhd_windows.go @@ -47,60 +47,60 @@ var ( procOpenVirtualDisk = modvirtdisk.NewProc("OpenVirtualDisk") ) -func attachVirtualDisk(handle syscall.Handle, securityDescriptor *uintptr, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (err error) { - r1, _, e1 := syscall.Syscall6(procAttachVirtualDisk.Addr(), 6, uintptr(handle), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(attachVirtualDiskFlag), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped))) - if r1 != 0 { - err = errnoErr(e1) +func attachVirtualDisk(handle syscall.Handle, securityDescriptor *uintptr, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (win32err error) { + r0, _, _ := syscall.Syscall6(procAttachVirtualDisk.Addr(), 6, uintptr(handle), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(attachVirtualDiskFlag), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped))) + if r0 != 0 { + win32err = syscall.Errno(r0) } return } -func createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (err error) { +func createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (win32err error) { var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(path) - if err != nil { + _p0, win32err = syscall.UTF16PtrFromString(path) + if win32err != nil { return } return _createVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, securityDescriptor, createVirtualDiskFlags, providerSpecificFlags, parameters, overlapped, handle) } -func _createVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (err error) { - r1, _, e1 := syscall.Syscall9(procCreateVirtualDisk.Addr(), 9, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(createVirtualDiskFlags), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(handle))) - if r1 != 0 { - err = errnoErr(e1) +func _createVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (win32err error) { + r0, _, _ := syscall.Syscall9(procCreateVirtualDisk.Addr(), 9, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(createVirtualDiskFlags), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(handle))) + if r0 != 0 { + win32err = syscall.Errno(r0) } return } -func detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, providerSpecificFlags uint32) (err error) { - r1, _, e1 := syscall.Syscall(procDetachVirtualDisk.Addr(), 3, uintptr(handle), uintptr(detachVirtualDiskFlags), uintptr(providerSpecificFlags)) - if r1 != 0 { - err = errnoErr(e1) +func detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, providerSpecificFlags uint32) (win32err error) { + r0, _, _ := syscall.Syscall(procDetachVirtualDisk.Addr(), 3, uintptr(handle), uintptr(detachVirtualDiskFlags), uintptr(providerSpecificFlags)) + if r0 != 0 { + win32err = syscall.Errno(r0) } return } -func getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint32, buffer *uint16) (err error) { - r1, _, e1 := syscall.Syscall(procGetVirtualDiskPhysicalPath.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(diskPathSizeInBytes)), uintptr(unsafe.Pointer(buffer))) - if r1 != 0 { - err = errnoErr(e1) +func getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint32, buffer *uint16) (win32err error) { + r0, _, _ := syscall.Syscall(procGetVirtualDiskPhysicalPath.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(diskPathSizeInBytes)), uintptr(unsafe.Pointer(buffer))) + if r0 != 0 { + win32err = syscall.Errno(r0) } return } -func openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (err error) { +func openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (win32err error) { var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(path) - if err != nil { + _p0, win32err = syscall.UTF16PtrFromString(path) + if win32err != nil { return } return _openVirtualDisk(virtualStorageType, _p0, virtualDiskAccessMask, openVirtualDiskFlags, parameters, handle) } -func _openVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (err error) { - r1, _, e1 := syscall.Syscall6(procOpenVirtualDisk.Addr(), 6, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(openVirtualDiskFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(handle))) - if r1 != 0 { - err = errnoErr(e1) +func _openVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *OpenVirtualDiskParameters, handle *syscall.Handle) (win32err error) { + r0, _, _ := syscall.Syscall6(procOpenVirtualDisk.Addr(), 6, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(openVirtualDiskFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(handle))) + if r0 != 0 { + win32err = syscall.Errno(r0) } return } diff --git a/vendor/github.com/Microsoft/hcsshim/go.mod b/vendor/github.com/Microsoft/hcsshim/go.mod index 4d26c7c36..7c9747667 100644 --- a/vendor/github.com/Microsoft/hcsshim/go.mod +++ b/vendor/github.com/Microsoft/hcsshim/go.mod @@ -5,11 +5,12 @@ go 1.13 require ( github.com/BurntSushi/toml v0.3.1 github.com/Microsoft/go-winio v0.4.17 + github.com/cenkalti/backoff/v4 v4.1.1 github.com/containerd/cgroups v1.0.1 github.com/containerd/console v1.0.2 github.com/containerd/containerd v1.5.7 github.com/containerd/go-runc v1.0.0 - github.com/containerd/ttrpc v1.0.2 + github.com/containerd/ttrpc v1.1.0 github.com/containerd/typeurl v1.0.2 github.com/gogo/protobuf v1.3.2 github.com/golang/mock v1.6.0 diff --git a/vendor/github.com/Microsoft/hcsshim/go.sum b/vendor/github.com/Microsoft/hcsshim/go.sum index 572931b3b..7c383806d 100644 --- a/vendor/github.com/Microsoft/hcsshim/go.sum +++ b/vendor/github.com/Microsoft/hcsshim/go.sum @@ -86,6 +86,8 @@ github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7 github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -172,8 +174,9 @@ github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDG github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= -github.com/containerd/ttrpc v1.0.2 h1:2/O3oTZN36q2xRolk0a2WWGgh7/Vf/liElg5hFYLX9U= github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= +github.com/containerd/ttrpc v1.1.0 h1:GbtyLRxb0gOLR0TYQWt3O6B0NvT8tMdorEHqIQo/lWI= +github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk= github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= @@ -904,8 +907,9 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go b/vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go index 3ef029116..e56319545 100644 --- a/vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go +++ b/vendor/github.com/containerd/stargz-snapshotter/estargz/estargz.go @@ -118,7 +118,7 @@ func Open(sr *io.SectionReader, opt ...OpenOption) (*Reader, error) { } } - gzipCompressors := []Decompressor{new(GzipDecompressor), new(legacyGzipDecompressor)} + gzipCompressors := []Decompressor{new(GzipDecompressor), new(LegacyGzipDecompressor)} decompressors := append(gzipCompressors, opts.decompressors...) // Determine the size to fetch. Try to fetch as many bytes as possible. @@ -184,7 +184,7 @@ func OpenFooter(sr *io.SectionReader) (tocOffset int64, footerSize int64, rErr e return 0, 0, fmt.Errorf("error reading footer: %v", err) } var allErr []error - for _, d := range []Decompressor{new(GzipDecompressor), new(legacyGzipDecompressor)} { + for _, d := range []Decompressor{new(GzipDecompressor), new(LegacyGzipDecompressor)} { fSize := d.FooterSize() fOffset := positive(int64(len(footer)) - fSize) _, tocOffset, _, err := d.ParseFooter(footer[fOffset:]) @@ -279,12 +279,12 @@ func (r *Reader) initFields() error { pdir := r.getOrCreateDir(pdirName) ent.NumLink++ // at least one name(ent.Name) references this entry. if ent.Type == "hardlink" { - if org, ok := r.m[cleanEntryName(ent.LinkName)]; ok { - org.NumLink++ // original entry is referenced by this ent.Name. - ent = org - } else { - return fmt.Errorf("%q is a hardlink but the linkname %q isn't found", ent.Name, ent.LinkName) + org, err := r.getSource(ent) + if err != nil { + return err } + org.NumLink++ // original entry is referenced by this ent.Name. + ent = org } pdir.addChild(path.Base(name), ent) } @@ -303,6 +303,20 @@ func (r *Reader) initFields() error { return nil } +func (r *Reader) getSource(ent *TOCEntry) (_ *TOCEntry, err error) { + if ent.Type == "hardlink" { + org, ok := r.m[cleanEntryName(ent.LinkName)] + if !ok { + return nil, fmt.Errorf("%q is a hardlink but the linkname %q isn't found", ent.Name, ent.LinkName) + } + ent, err = r.getSource(org) + if err != nil { + return nil, err + } + } + return ent, nil +} + func parentDir(p string) string { dir, _ := path.Split(p) return strings.TrimSuffix(dir, "/") @@ -464,7 +478,11 @@ func (r *Reader) Lookup(path string) (e *TOCEntry, ok bool) { } e, ok = r.m[path] if ok && e.Type == "hardlink" { - e, ok = r.m[e.LinkName] + var err error + e, err = r.getSource(e) + if err != nil { + return nil, false + } } return } diff --git a/vendor/github.com/containerd/stargz-snapshotter/estargz/gzip.go b/vendor/github.com/containerd/stargz-snapshotter/estargz/gzip.go index 88e1283d8..7330849cb 100644 --- a/vendor/github.com/containerd/stargz-snapshotter/estargz/gzip.go +++ b/vendor/github.com/containerd/stargz-snapshotter/estargz/gzip.go @@ -38,30 +38,34 @@ import ( ) type gzipCompression struct { - *gzipCompressor + *GzipCompressor *GzipDecompressor } func newGzipCompressionWithLevel(level int) Compression { return &gzipCompression{ - &gzipCompressor{level}, + &GzipCompressor{level}, &GzipDecompressor{}, } } -func NewGzipCompressorWithLevel(level int) Compressor { - return &gzipCompressor{level} +func NewGzipCompressor() *GzipCompressor { + return &GzipCompressor{gzip.BestCompression} } -type gzipCompressor struct { +func NewGzipCompressorWithLevel(level int) *GzipCompressor { + return &GzipCompressor{level} +} + +type GzipCompressor struct { compressionLevel int } -func (gc *gzipCompressor) Writer(w io.Writer) (io.WriteCloser, error) { +func (gc *GzipCompressor) Writer(w io.Writer) (io.WriteCloser, error) { return gzip.NewWriterLevel(w, gc.compressionLevel) } -func (gc *gzipCompressor) WriteTOCAndFooter(w io.Writer, off int64, toc *JTOC, diffHash hash.Hash) (digest.Digest, error) { +func (gc *GzipCompressor) WriteTOCAndFooter(w io.Writer, off int64, toc *JTOC, diffHash hash.Hash) (digest.Digest, error) { tocJSON, err := json.MarshalIndent(toc, "", "\t") if err != nil { return "", err @@ -155,17 +159,21 @@ func (gz *GzipDecompressor) FooterSize() int64 { return FooterSize } -type legacyGzipDecompressor struct{} +func (gz *GzipDecompressor) DecompressTOC(r io.Reader) (tocJSON io.ReadCloser, err error) { + return decompressTOCEStargz(r) +} + +type LegacyGzipDecompressor struct{} -func (gz *legacyGzipDecompressor) Reader(r io.Reader) (io.ReadCloser, error) { +func (gz *LegacyGzipDecompressor) Reader(r io.Reader) (io.ReadCloser, error) { return gzip.NewReader(r) } -func (gz *legacyGzipDecompressor) ParseTOC(r io.Reader) (toc *JTOC, tocDgst digest.Digest, err error) { +func (gz *LegacyGzipDecompressor) ParseTOC(r io.Reader) (toc *JTOC, tocDgst digest.Digest, err error) { return parseTOCEStargz(r) } -func (gz *legacyGzipDecompressor) ParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error) { +func (gz *LegacyGzipDecompressor) ParseFooter(p []byte) (blobPayloadSize, tocOffset, tocSize int64, err error) { if len(p) != legacyFooterSize { return 0, 0, 0, fmt.Errorf("legacy: invalid length %d cannot be parsed", len(p)) } @@ -188,29 +196,43 @@ func (gz *legacyGzipDecompressor) ParseFooter(p []byte) (blobPayloadSize, tocOff return tocOffset, tocOffset, 0, nil } -func (gz *legacyGzipDecompressor) FooterSize() int64 { +func (gz *LegacyGzipDecompressor) FooterSize() int64 { return legacyFooterSize } +func (gz *LegacyGzipDecompressor) DecompressTOC(r io.Reader) (tocJSON io.ReadCloser, err error) { + return decompressTOCEStargz(r) +} + func parseTOCEStargz(r io.Reader) (toc *JTOC, tocDgst digest.Digest, err error) { + tr, err := decompressTOCEStargz(r) + if err != nil { + return nil, "", err + } + dgstr := digest.Canonical.Digester() + toc = new(JTOC) + if err := json.NewDecoder(io.TeeReader(tr, dgstr.Hash())).Decode(&toc); err != nil { + return nil, "", fmt.Errorf("error decoding TOC JSON: %v", err) + } + if err := tr.Close(); err != nil { + return nil, "", err + } + return toc, dgstr.Digest(), nil +} + +func decompressTOCEStargz(r io.Reader) (tocJSON io.ReadCloser, err error) { zr, err := gzip.NewReader(r) if err != nil { - return nil, "", fmt.Errorf("malformed TOC gzip header: %v", err) + return nil, fmt.Errorf("malformed TOC gzip header: %v", err) } - defer zr.Close() zr.Multistream(false) tr := tar.NewReader(zr) h, err := tr.Next() if err != nil { - return nil, "", fmt.Errorf("failed to find tar header in TOC gzip stream: %v", err) + return nil, fmt.Errorf("failed to find tar header in TOC gzip stream: %v", err) } if h.Name != TOCTarName { - return nil, "", fmt.Errorf("TOC tar entry had name %q; expected %q", h.Name, TOCTarName) + return nil, fmt.Errorf("TOC tar entry had name %q; expected %q", h.Name, TOCTarName) } - dgstr := digest.Canonical.Digester() - toc = new(JTOC) - if err := json.NewDecoder(io.TeeReader(tr, dgstr.Hash())).Decode(&toc); err != nil { - return nil, "", fmt.Errorf("error decoding TOC JSON: %v", err) - } - return toc, dgstr.Digest(), nil + return readCloser{tr, zr.Close}, nil } diff --git a/vendor/github.com/containers/common/libimage/image.go b/vendor/github.com/containers/common/libimage/image.go index bf3310da2..50dbc9725 100644 --- a/vendor/github.com/containers/common/libimage/image.go +++ b/vendor/github.com/containers/common/libimage/image.go @@ -624,8 +624,7 @@ func (i *Image) NamedRepoTags() ([]reference.Named, error) { } // inRepoTags looks for the specified name/tag pair in the image's repo tags. -// Note that tag may be empty. -func (i *Image) inRepoTags(name, tag string) (reference.Named, error) { +func (i *Image) inRepoTags(namedTagged reference.NamedTagged) (reference.Named, error) { repoTags, err := i.NamedRepoTags() if err != nil { return nil, err @@ -636,8 +635,10 @@ func (i *Image) inRepoTags(name, tag string) (reference.Named, error) { return nil, err } + name := namedTagged.Name() + tag := namedTagged.Tag() for _, pair := range pairs { - if tag != "" && tag != pair.Tag { + if tag != pair.Tag { continue } if !strings.HasSuffix(pair.Name, name) { diff --git a/vendor/github.com/containers/common/libimage/runtime.go b/vendor/github.com/containers/common/libimage/runtime.go index d1b6e6cfb..c0eee4212 100644 --- a/vendor/github.com/containers/common/libimage/runtime.go +++ b/vendor/github.com/containers/common/libimage/runtime.go @@ -389,16 +389,17 @@ func (r *Runtime) lookupImageInDigestsAndRepoTags(name string, options *LookupIm return nil, "", err } - if !shortnames.IsShortName(name) { - named, err := reference.ParseNormalizedNamed(name) - if err != nil { - return nil, "", err - } - digested, hasDigest := named.(reference.Digested) - if !hasDigest { - return nil, "", errors.Wrap(storage.ErrImageUnknown, name) - } + ref, err := reference.Parse(name) // Warning! This is not ParseNormalizedNamed + if err != nil { + return nil, "", err + } + named, isNamed := ref.(reference.Named) + if !isNamed { + return nil, "", errors.Wrap(storage.ErrImageUnknown, name) + } + digested, isDigested := named.(reference.Digested) + if isDigested { logrus.Debug("Looking for image with matching recorded digests") digest := digested.Digest() for _, image := range allImages { @@ -408,22 +409,23 @@ func (r *Runtime) lookupImageInDigestsAndRepoTags(name string, options *LookupIm } } } + return nil, "", errors.Wrap(storage.ErrImageUnknown, name) + } + if !shortnames.IsShortName(name) { return nil, "", errors.Wrap(storage.ErrImageUnknown, name) } - // Podman compat: if we're looking for a short name but couldn't - // resolve it via the registries.conf dance, we need to look at *all* - // images and check if the name we're looking for matches a repo tag. - // Split the name into a repo/tag pair - split := strings.SplitN(name, ":", 2) - repo := split[0] - tag := "" - if len(split) == 2 { - tag = split[1] + named = reference.TagNameOnly(named) // Make sure to add ":latest" if needed + namedTagged, isNammedTagged := named.(reference.NamedTagged) + if !isNammedTagged { + // NOTE: this should never happen since we already know it's + // not a digested reference. + return nil, "", fmt.Errorf("%s: %w (could not cast to tagged)", name, storage.ErrImageUnknown) } + for _, image := range allImages { - named, err := image.inRepoTags(repo, tag) + named, err := image.inRepoTags(namedTagged) if err != nil { return nil, "", err } diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go index 1a5370a39..7ce0e5022 100644 --- a/vendor/github.com/containers/common/pkg/config/config.go +++ b/vendor/github.com/containers/common/pkg/config/config.go @@ -215,6 +215,12 @@ type EngineConfig struct { // The first path pointing to a valid file will be used. ConmonPath []string `toml:"conmon_path,omitempty"` + // CompatAPIEnforceDockerHub enforces using docker.io for completing + // short names in Podman's compatibility REST API. Note that this will + // ignore unqualified-search-registries and short-name aliases defined + // in containers-registries.conf(5). + CompatAPIEnforceDockerHub bool `toml:"compat_api_enforce_docker_hub,omitempty"` + // DetachKeys is the sequence of keys used to detach a container. DetachKeys string `toml:"detach_keys,omitempty"` diff --git a/vendor/github.com/containers/common/pkg/config/containers.conf b/vendor/github.com/containers/common/pkg/config/containers.conf index 0c3ea8054..8e305b57e 100644 --- a/vendor/github.com/containers/common/pkg/config/containers.conf +++ b/vendor/github.com/containers/common/pkg/config/containers.conf @@ -317,6 +317,11 @@ default_sysctls = [ # "/usr/local/sbin/conmon" #] +# Enforces using docker.io for completing short names in Podman's compatibility +# REST API. Note that this will ignore unqualified-search-registries and +# short-name aliases defined in containers-registries.conf(5). +#compat_api_enforce_docker_hub = true + # Specify the keys sequence used to detach a container. # Format is a single character [a-Z] or a comma separated sequence of # `ctrl-<value>`, where `<value>` is one of: diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go index 515c46e8b..8821aa91e 100644 --- a/vendor/github.com/containers/common/pkg/config/default.go +++ b/vendor/github.com/containers/common/pkg/config/default.go @@ -190,6 +190,7 @@ func DefaultConfig() (*Config, error) { IPCNS: "private", LogDriver: defaultLogDriver(), LogSizeMax: DefaultLogSizeMax, + NetNS: "private", NoHosts: false, PidsLimit: DefaultPidsLimit, PidNS: "private", @@ -225,7 +226,7 @@ func defaultSecretConfig() SecretConfig { func defaultMachineConfig() MachineConfig { return MachineConfig{ CPUs: 1, - DiskSize: 10, + DiskSize: 100, Image: "testing", Memory: 2048, } @@ -243,6 +244,8 @@ func defaultConfigFromMemory() (*EngineConfig, error) { c.EventsLogFilePath = filepath.Join(c.TmpDir, "events", "events.log") + c.CompatAPIEnforceDockerHub = true + if path, ok := os.LookupEnv("CONTAINERS_STORAGE_CONF"); ok { types.SetDefaultConfigFilePath(path) } diff --git a/vendor/github.com/containers/common/pkg/report/doc.go b/vendor/github.com/containers/common/pkg/report/doc.go index 326b315f2..088568173 100644 --- a/vendor/github.com/containers/common/pkg/report/doc.go +++ b/vendor/github.com/containers/common/pkg/report/doc.go @@ -3,34 +3,44 @@ Package report provides helper structs/methods/funcs for formatting output To format output for an array of structs: - w := report.NewWriterDefault(os.Stdout) - defer w.Flush() - +ExamplePodman: headers := report.Headers(struct { ID string }{}, nil) - t, _ := report.NewTemplate("command name").Parse("{{range .}}{{.ID}}{{end}}") - t.Execute(t, headers) - t.Execute(t, map[string]string{ + + f := report.New(os.Stdout, "Command Name") + f, _ := f.Parse(report.OriginPodman, "{{range .}}{{.ID}}{{end}}") + defer f.Flush() + + if f.RenderHeaders { + f.Execute(headers) + } + f.Execute( map[string]string{ "ID":"fa85da03b40141899f3af3de6d27852b", }) - // t.IsTable() == false - -or - w := report.NewWriterDefault(os.Stdout) - defer w.Flush() + // Output: + // ID + // fa85da03b40141899f3af3de6d27852b +ExampleUser: headers := report.Headers(struct { CID string - }{}, map[string]string{ - "CID":"ID"}) - t, _ := report.NewTemplate("command name").Parse("table {{.CID}}") - t.Execute(t, headers) + }{}, map[string]string{"CID":"ID"}) + + f, _ := report.New(os.Stdout, "Command Name").Parse(report.OriginUser, "table {{.CID}}") + defer f.Flush() + + if f.RenderHeaders { + t.Execute(t, headers) + } t.Execute(t,map[string]string{ "CID":"fa85da03b40141899f3af3de6d27852b", }) - // t.IsTable() == true + + // Output: + // ID + // fa85da03b40141899f3af3de6d27852b Helpers: @@ -38,13 +48,20 @@ Helpers: ... process JSON and output } + if report.HasTable(cmd.Flag("format").Value.String()) { + ... "table" keyword prefix in format text + } + Template Functions: The following template functions are added to the template when parsed: - join strings.Join, {{join .Field separator}} + - json encode field as JSON {{ json .Field }} - lower strings.ToLower {{ .Field | lower }} + - pad add spaces as prefix and suffix {{ pad . 2 2 }} - split strings.Split {{ .Field | split }} - title strings.Title {{ .Field | title }} + - truncate limit field length {{ truncate . 10 }} - upper strings.ToUpper {{ .Field | upper }} report.Funcs() may be used to add additional template functions. diff --git a/vendor/github.com/containers/common/pkg/report/formatter.go b/vendor/github.com/containers/common/pkg/report/formatter.go new file mode 100644 index 000000000..1772f8765 --- /dev/null +++ b/vendor/github.com/containers/common/pkg/report/formatter.go @@ -0,0 +1,151 @@ +package report + +import ( + "io" + "strings" + "text/tabwriter" + "text/template" +) + +// Flusher is the interface that wraps the Flush method. +type Flusher interface { + Flush() error +} + +// NopFlusher represents a type which flush operation is nop. +type NopFlusher struct{} + +// Flush is a nop operation. +func (f *NopFlusher) Flush() (err error) { return } + +type Origin int + +const ( + OriginUnknown Origin = iota + OriginPodman + OriginUser +) + +func (o Origin) String() string { + switch o { + case OriginPodman: + return "OriginPodman" + case OriginUser: + return "OriginUser" + default: + return "OriginUnknown" + } +} + +// Formatter holds the configured Writer and parsed Template, additional state fields are +// maintained to assist in the podman command report writing. +type Formatter struct { + Origin Origin // Source of go template. OriginUser or OriginPodman + RenderHeaders bool // Hint, default behavior for given template is to include headers + RenderTable bool // Does template have "table" keyword + flusher Flusher // Flush any buffered formatted output + template *template.Template // Go text/template for formatting output + text string // value of canonical template after processing + writer io.Writer // Destination for formatted output +} + +// Parse parses golang template returning a formatter +// +// - OriginPodman implies text is a template from podman code. Output will +// be filtered through a tabwriter. +// +// - OriginUser implies text is a template from a user. If template includes +// keyword "table" output will be filtered through a tabwriter. +func (f *Formatter) Parse(origin Origin, text string) (*Formatter, error) { + f.Origin = origin + + switch { + case strings.HasPrefix(text, "table "): + f.RenderTable = true + text = "{{range .}}" + NormalizeFormat(text) + "{{end -}}" + case OriginUser == origin: + text = EnforceRange(NormalizeFormat(text)) + default: + text = NormalizeFormat(text) + } + f.text = text + + if f.RenderTable || origin == OriginPodman { + tw := tabwriter.NewWriter(f.writer, 12, 2, 2, ' ', tabwriter.StripEscape) + f.writer = tw + f.flusher = tw + f.RenderHeaders = true + } + + tmpl, err := f.template.Funcs(template.FuncMap(DefaultFuncs)).Parse(text) + if err != nil { + return f, err + } + f.template = tmpl + return f, nil +} + +// Funcs adds the elements of the argument map to the template's function map. +// A default template function will be replaced if there is a key collision. +func (f *Formatter) Funcs(funcMap template.FuncMap) *Formatter { + m := make(template.FuncMap, len(DefaultFuncs)+len(funcMap)) + for k, v := range DefaultFuncs { + m[k] = v + } + for k, v := range funcMap { + m[k] = v + } + f.template = f.template.Funcs(funcMap) + return f +} + +// Init either resets the given tabwriter with new values or wraps w in tabwriter with given values +func (f *Formatter) Init(w io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *Formatter { + flags |= tabwriter.StripEscape + + if tw, ok := f.writer.(*tabwriter.Writer); ok { + tw = tw.Init(w, minwidth, tabwidth, padding, padchar, flags) + f.writer = tw + f.flusher = tw + } else { + tw = tabwriter.NewWriter(w, minwidth, tabwidth, padding, padchar, flags) + f.writer = tw + f.flusher = tw + } + return f +} + +// Execute applies a parsed template to the specified data object, +// and writes the output to Formatter.Writer. +func (f *Formatter) Execute(data interface{}) error { + return f.template.Execute(f.writer, data) +} + +// Flush should be called after the last call to Write to ensure +// that any data buffered in the Formatter is written to output. Any +// incomplete escape sequence at the end is considered +// complete for formatting purposes. +func (f *Formatter) Flush() error { + // Indirection is required here to prevent caller from having to know when + // value of Flusher may be changed. + return f.flusher.Flush() +} + +// Writer returns the embedded io.Writer from Formatter +func (f *Formatter) Writer() io.Writer { + return f.writer +} + +// New allocates a new, undefined Formatter with the given name and Writer +func New(output io.Writer, name string) *Formatter { + f := new(Formatter) + + f.flusher = new(NopFlusher) + if flusher, ok := output.(Flusher); ok { + f.flusher = flusher + } + + f.template = template.New(name) + f.writer = output + return f +} diff --git a/vendor/github.com/containers/common/pkg/report/template.go b/vendor/github.com/containers/common/pkg/report/template.go index f86b07034..95c04424d 100644 --- a/vendor/github.com/containers/common/pkg/report/template.go +++ b/vendor/github.com/containers/common/pkg/report/template.go @@ -25,17 +25,19 @@ var tableReplacer = strings.NewReplacer( "table ", "", `\t`, "\t", " ", "\t", + `\n`, "\n", ) // escapedReplacer will clean up escaped characters from CLI var escapedReplacer = strings.NewReplacer( `\t`, "\t", + `\n`, "\n", ) var DefaultFuncs = FuncMap{ "join": strings.Join, "json": func(v interface{}) string { - buf := &bytes.Buffer{} + buf := new(bytes.Buffer) enc := json.NewEncoder(buf) enc.SetEscapeHTML(false) enc.Encode(v) @@ -157,7 +159,7 @@ func (t *Template) IsTable() bool { return t.isTable } -var rangeRegex = regexp.MustCompile(`{{\s*range\s*\.\s*}}.*{{\s*end\s*-?\s*}}`) +var rangeRegex = regexp.MustCompile(`(?s){{\s*range\s*\.\s*}}.*{{\s*end\s*-?\s*}}`) // EnforceRange ensures that the format string contains a range func EnforceRange(format string) string { diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go index 7111c5612..56c39c141 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_image_dest.go +++ b/vendor/github.com/containers/image/v5/docker/docker_image_dest.go @@ -17,9 +17,9 @@ import ( "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/internal/blobinfocache" "github.com/containers/image/v5/internal/putblobdigest" + "github.com/containers/image/v5/internal/streamdigest" "github.com/containers/image/v5/internal/uploadreader" "github.com/containers/image/v5/manifest" - "github.com/containers/image/v5/pkg/blobinfocache/none" "github.com/containers/image/v5/types" "github.com/docker/distribution/registry/api/errcode" v2 "github.com/docker/distribution/registry/api/v2" @@ -131,11 +131,23 @@ func (d *dockerImageDestination) HasThreadSafePutBlob() bool { // to any other readers for download using the supplied digest. // If stream.Read() at any time, ESPECIALLY at end of input, returns an error, PutBlob MUST 1) fail, and 2) delete any data stored so far. func (d *dockerImageDestination) PutBlob(ctx context.Context, stream io.Reader, inputInfo types.BlobInfo, cache types.BlobInfoCache, isConfig bool) (types.BlobInfo, error) { + // If requested, precompute the blob digest to prevent uploading layers that already exist on the registry. + // This functionality is particularly useful when BlobInfoCache has not been populated with compressed digests, + // the source blob is uncompressed, and the destination blob is being compressed "on the fly". + if inputInfo.Digest == "" && d.c.sys.DockerRegistryPushPrecomputeDigests { + logrus.Debugf("Precomputing digest layer for %s", reference.Path(d.ref.ref)) + streamCopy, cleanup, err := streamdigest.ComputeBlobInfo(d.c.sys, stream, &inputInfo) + if err != nil { + return types.BlobInfo{}, err + } + defer cleanup() + stream = streamCopy + } + if inputInfo.Digest != "" { // This should not really be necessary, at least the copy code calls TryReusingBlob automatically. // Still, we need to check, if only because the "initiate upload" endpoint does not have a documented "blob already exists" return value. - // But we do that with NoCache, so that it _only_ checks the primary destination, instead of trying all mount candidates _again_. - haveBlob, reusedInfo, err := d.TryReusingBlob(ctx, inputInfo, none.NoCache, false) + haveBlob, reusedInfo, err := d.tryReusingExactBlob(ctx, inputInfo, cache) if err != nil { return types.BlobInfo{}, err } @@ -282,6 +294,21 @@ func (d *dockerImageDestination) mountBlob(ctx context.Context, srcRepo referenc } } +// tryReusingExactBlob is a subset of TryReusingBlob which _only_ looks for exactly the specified +// blob in the current repository, with no cross-repo reuse or mounting; cache may be updated, it is not read. +// The caller must ensure info.Digest is set. +func (d *dockerImageDestination) tryReusingExactBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (bool, types.BlobInfo, error) { + exists, size, err := d.blobExists(ctx, d.ref.ref, info.Digest, nil) + if err != nil { + return false, types.BlobInfo{}, err + } + if exists { + cache.RecordKnownLocation(d.ref.Transport(), bicTransportScope(d.ref), info.Digest, newBICLocationReference(d.ref)) + return true, types.BlobInfo{Digest: info.Digest, MediaType: info.MediaType, Size: size}, nil + } + return false, types.BlobInfo{}, nil +} + // TryReusingBlob checks whether the transport already contains, or can efficiently reuse, a blob, and if so, applies it to the current destination // (e.g. if the blob is a filesystem layer, this signifies that the changes it describes need to be applied again when composing a filesystem tree). // info.Digest must not be empty. @@ -297,13 +324,12 @@ func (d *dockerImageDestination) TryReusingBlob(ctx context.Context, info types. } // First, check whether the blob happens to already exist at the destination. - exists, size, err := d.blobExists(ctx, d.ref.ref, info.Digest, nil) + haveBlob, reusedInfo, err := d.tryReusingExactBlob(ctx, info, cache) if err != nil { return false, types.BlobInfo{}, err } - if exists { - cache.RecordKnownLocation(d.ref.Transport(), bicTransportScope(d.ref), info.Digest, newBICLocationReference(d.ref)) - return true, types.BlobInfo{Digest: info.Digest, MediaType: info.MediaType, Size: size}, nil + if haveBlob { + return true, reusedInfo, nil } // Then try reusing blobs from other locations. diff --git a/vendor/github.com/containers/image/v5/docker/docker_image_src.go b/vendor/github.com/containers/image/v5/docker/docker_image_src.go index f2e9eb17b..314e9b394 100644 --- a/vendor/github.com/containers/image/v5/docker/docker_image_src.go +++ b/vendor/github.com/containers/image/v5/docker/docker_image_src.go @@ -236,6 +236,9 @@ func (s *dockerImageSource) ensureManifestIsLoaded(ctx context.Context) error { return nil } +// getExternalBlob returns the reader of the first available blob URL from urls, which must not be empty. +// This function can return nil reader when no url is supported by this function. In this case, the caller +// should fallback to fetch the non-external blob (i.e. pull from the registry). func (s *dockerImageSource) getExternalBlob(ctx context.Context, urls []string) (io.ReadCloser, int64, error) { var ( resp *http.Response @@ -244,14 +247,17 @@ func (s *dockerImageSource) getExternalBlob(ctx context.Context, urls []string) if len(urls) == 0 { return nil, 0, errors.New("internal error: getExternalBlob called with no URLs") } - for _, url := range urls { + for _, u := range urls { + if u, err := url.Parse(u); err != nil || (u.Scheme != "http" && u.Scheme != "https") { + continue // unsupported url. skip this url. + } // NOTE: we must not authenticate on additional URLs as those // can be abused to leak credentials or tokens. Please // refer to CVE-2020-15157 for more information. - resp, err = s.c.makeRequestToResolvedURL(ctx, http.MethodGet, url, nil, nil, -1, noAuth, nil) + resp, err = s.c.makeRequestToResolvedURL(ctx, http.MethodGet, u, nil, nil, -1, noAuth, nil) if err == nil { if resp.StatusCode != http.StatusOK { - err = errors.Errorf("error fetching external blob from %q: %d (%s)", url, resp.StatusCode, http.StatusText(resp.StatusCode)) + err = errors.Errorf("error fetching external blob from %q: %d (%s)", u, resp.StatusCode, http.StatusText(resp.StatusCode)) logrus.Debug(err) resp.Body.Close() continue @@ -259,6 +265,9 @@ func (s *dockerImageSource) getExternalBlob(ctx context.Context, urls []string) break } } + if resp == nil && err == nil { + return nil, 0, nil // fallback to non-external blob + } if err != nil { return nil, 0, err } @@ -408,7 +417,12 @@ func (s *dockerImageSource) GetBlobAt(ctx context.Context, info types.BlobInfo, // May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location. func (s *dockerImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) { if len(info.URLs) != 0 { - return s.getExternalBlob(ctx, info.URLs) + r, s, err := s.getExternalBlob(ctx, info.URLs) + if err != nil { + return nil, 0, err + } else if r != nil { + return r, s, nil + } } path := fmt.Sprintf(blobsPath, reference.Path(s.physicalRef.ref), info.Digest.String()) diff --git a/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go b/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go index 44b0af110..7e1580990 100644 --- a/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go +++ b/vendor/github.com/containers/image/v5/docker/internal/tarfile/dest.go @@ -5,13 +5,10 @@ import ( "context" "encoding/json" "io" - "io/ioutil" - "os" "github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/internal/iolimits" - "github.com/containers/image/v5/internal/putblobdigest" - "github.com/containers/image/v5/internal/tmpdir" + "github.com/containers/image/v5/internal/streamdigest" "github.com/containers/image/v5/manifest" "github.com/containers/image/v5/types" "github.com/opencontainers/go-digest" @@ -98,25 +95,11 @@ func (d *Destination) PutBlob(ctx context.Context, stream io.Reader, inputInfo t // When the layer is decompressed, we also have to generate the digest on uncompressed data. if inputInfo.Size == -1 || inputInfo.Digest == "" { logrus.Debugf("docker tarfile: input with unknown size, streaming to disk first ...") - streamCopy, err := ioutil.TempFile(tmpdir.TemporaryDirectoryForBigFiles(d.sysCtx), "docker-tarfile-blob") + streamCopy, cleanup, err := streamdigest.ComputeBlobInfo(d.sysCtx, stream, &inputInfo) if err != nil { return types.BlobInfo{}, err } - defer os.Remove(streamCopy.Name()) - defer streamCopy.Close() - - digester, stream2 := putblobdigest.DigestIfUnknown(stream, inputInfo) - // TODO: This can take quite some time, and should ideally be cancellable using ctx.Done(). - size, err := io.Copy(streamCopy, stream2) - if err != nil { - return types.BlobInfo{}, err - } - _, err = streamCopy.Seek(0, io.SeekStart) - if err != nil { - return types.BlobInfo{}, err - } - inputInfo.Size = size // inputInfo is a struct, so we are only modifying our copy. - inputInfo.Digest = digester.Digest() + defer cleanup() stream = streamCopy logrus.Debugf("... streaming done") } diff --git a/vendor/github.com/containers/image/v5/internal/streamdigest/stream_digest.go b/vendor/github.com/containers/image/v5/internal/streamdigest/stream_digest.go new file mode 100644 index 000000000..306220585 --- /dev/null +++ b/vendor/github.com/containers/image/v5/internal/streamdigest/stream_digest.go @@ -0,0 +1,41 @@ +package streamdigest + +import ( + "fmt" + "io" + "io/ioutil" + "os" + + "github.com/containers/image/v5/internal/putblobdigest" + "github.com/containers/image/v5/internal/tmpdir" + "github.com/containers/image/v5/types" +) + +// ComputeBlobInfo streams a blob to a temporary file and populates Digest and Size in inputInfo. +// The temporary file is returned as an io.Reader along with a cleanup function. +// It is the caller's responsibility to call the cleanup function, which closes and removes the temporary file. +// If an error occurs, inputInfo is not modified. +func ComputeBlobInfo(sys *types.SystemContext, stream io.Reader, inputInfo *types.BlobInfo) (io.Reader, func(), error) { + diskBlob, err := ioutil.TempFile(tmpdir.TemporaryDirectoryForBigFiles(sys), "stream-blob") + if err != nil { + return nil, nil, fmt.Errorf("creating temporary on-disk layer: %w", err) + } + cleanup := func() { + diskBlob.Close() + os.Remove(diskBlob.Name()) + } + digester, stream := putblobdigest.DigestIfCanonicalUnknown(stream, *inputInfo) + written, err := io.Copy(diskBlob, stream) + if err != nil { + cleanup() + return nil, nil, fmt.Errorf("writing to temporary on-disk layer: %w", err) + } + _, err = diskBlob.Seek(0, io.SeekStart) + if err != nil { + cleanup() + return nil, nil, fmt.Errorf("rewinding temporary on-disk layer: %w", err) + } + inputInfo.Digest = digester.Digest() + inputInfo.Size = written + return diskBlob, cleanup, nil +} diff --git a/vendor/github.com/containers/image/v5/manifest/common.go b/vendor/github.com/containers/image/v5/manifest/common.go index 4692211c0..511cdcc37 100644 --- a/vendor/github.com/containers/image/v5/manifest/common.go +++ b/vendor/github.com/containers/image/v5/manifest/common.go @@ -1,6 +1,7 @@ package manifest import ( + "encoding/json" "fmt" compressiontypes "github.com/containers/image/v5/pkg/compression/types" @@ -32,6 +33,72 @@ func dupStringStringMap(m map[string]string) map[string]string { return result } +// allowedManifestFields is a bit mask of “essential” manifest fields that validateUnambiguousManifestFormat +// can expect to be present. +type allowedManifestFields int + +const ( + allowedFieldConfig allowedManifestFields = 1 << iota + allowedFieldFSLayers + allowedFieldHistory + allowedFieldLayers + allowedFieldManifests + allowedFieldFirstUnusedBit // Keep this at the end! +) + +// validateUnambiguousManifestFormat rejects manifests (incl. multi-arch) that look like more than +// one kind we currently recognize, i.e. if they contain any of the known “essential” format fields +// other than the ones the caller specifically allows. +// expectedMIMEType is used only for diagnostics. +// NOTE: The caller should do the non-heuristic validations (e.g. check for any specified format +// identification/version, or other “magic numbers”) before calling this, to cleanly reject unambigous +// data that just isn’t what was expected, as opposed to actually ambiguous data. +func validateUnambiguousManifestFormat(manifest []byte, expectedMIMEType string, + allowed allowedManifestFields) error { + if allowed >= allowedFieldFirstUnusedBit { + return fmt.Errorf("internal error: invalid allowedManifestFields value %#v", allowed) + } + // Use a private type to decode, not just a map[string]interface{}, because we want + // to also reject case-insensitive matches (which would be used by Go when really decoding + // the manifest). + // (It is expected that as manifest formats are added or extended over time, more fields will be added + // here.) + detectedFields := struct { + Config interface{} `json:"config"` + FSLayers interface{} `json:"fsLayers"` + History interface{} `json:"history"` + Layers interface{} `json:"layers"` + Manifests interface{} `json:"manifests"` + }{} + if err := json.Unmarshal(manifest, &detectedFields); err != nil { + // The caller was supposed to already validate version numbers, so this shold not happen; + // let’s not bother with making this error “nice”. + return err + } + unexpected := []string{} + // Sadly this isn’t easy to automate in Go, without reflection. So, copy&paste. + if detectedFields.Config != nil && (allowed&allowedFieldConfig) == 0 { + unexpected = append(unexpected, "config") + } + if detectedFields.FSLayers != nil && (allowed&allowedFieldFSLayers) == 0 { + unexpected = append(unexpected, "fsLayers") + } + if detectedFields.History != nil && (allowed&allowedFieldHistory) == 0 { + unexpected = append(unexpected, "history") + } + if detectedFields.Layers != nil && (allowed&allowedFieldLayers) == 0 { + unexpected = append(unexpected, "layers") + } + if detectedFields.Manifests != nil && (allowed&allowedFieldManifests) == 0 { + unexpected = append(unexpected, "manifests") + } + if len(unexpected) != 0 { + return fmt.Errorf(`rejecting ambiguous manifest, unexpected fields %#v in supposedly %s`, + unexpected, expectedMIMEType) + } + return nil +} + // layerInfosToStrings converts a list of layer infos, presumably obtained from a Manifest.LayerInfos() // method call, into a format suitable for inclusion in a types.ImageInspectInfo structure. func layerInfosToStrings(infos []LayerInfo) []string { diff --git a/vendor/github.com/containers/image/v5/manifest/docker_schema1.go b/vendor/github.com/containers/image/v5/manifest/docker_schema1.go index 8679cad11..6d12c4cec 100644 --- a/vendor/github.com/containers/image/v5/manifest/docker_schema1.go +++ b/vendor/github.com/containers/image/v5/manifest/docker_schema1.go @@ -60,6 +60,10 @@ func Schema1FromManifest(manifest []byte) (*Schema1, error) { if s1.SchemaVersion != 1 { return nil, errors.Errorf("unsupported schema version %d", s1.SchemaVersion) } + if err := validateUnambiguousManifestFormat(manifest, DockerV2Schema1SignedMediaType, + allowedFieldFSLayers|allowedFieldHistory); err != nil { + return nil, err + } if err := s1.initialize(); err != nil { return nil, err } diff --git a/vendor/github.com/containers/image/v5/manifest/docker_schema2.go b/vendor/github.com/containers/image/v5/manifest/docker_schema2.go index 2711ca5eb..1f4db54ee 100644 --- a/vendor/github.com/containers/image/v5/manifest/docker_schema2.go +++ b/vendor/github.com/containers/image/v5/manifest/docker_schema2.go @@ -165,6 +165,10 @@ func Schema2FromManifest(manifest []byte) (*Schema2, error) { if err := json.Unmarshal(manifest, &s2); err != nil { return nil, err } + if err := validateUnambiguousManifestFormat(manifest, DockerV2Schema2MediaType, + allowedFieldConfig|allowedFieldLayers); err != nil { + return nil, err + } // Check manifest's and layers' media types. if err := SupportedSchema2MediaType(s2.MediaType); err != nil { return nil, err diff --git a/vendor/github.com/containers/image/v5/manifest/docker_schema2_list.go b/vendor/github.com/containers/image/v5/manifest/docker_schema2_list.go index 9ebb8d6b9..e97dfbd88 100644 --- a/vendor/github.com/containers/image/v5/manifest/docker_schema2_list.go +++ b/vendor/github.com/containers/image/v5/manifest/docker_schema2_list.go @@ -192,6 +192,10 @@ func Schema2ListFromManifest(manifest []byte) (*Schema2List, error) { if err := json.Unmarshal(manifest, &list); err != nil { return nil, errors.Wrapf(err, "unmarshaling Schema2List %q", string(manifest)) } + if err := validateUnambiguousManifestFormat(manifest, DockerV2ListMediaType, + allowedFieldManifests); err != nil { + return nil, err + } return &list, nil } diff --git a/vendor/github.com/containers/image/v5/manifest/oci.go b/vendor/github.com/containers/image/v5/manifest/oci.go index 29a479c94..c4616b965 100644 --- a/vendor/github.com/containers/image/v5/manifest/oci.go +++ b/vendor/github.com/containers/image/v5/manifest/oci.go @@ -54,6 +54,10 @@ func OCI1FromManifest(manifest []byte) (*OCI1, error) { if err := json.Unmarshal(manifest, &oci1); err != nil { return nil, err } + if err := validateUnambiguousManifestFormat(manifest, imgspecv1.MediaTypeImageIndex, + allowedFieldConfig|allowedFieldLayers); err != nil { + return nil, err + } return &oci1, nil } diff --git a/vendor/github.com/containers/image/v5/manifest/oci_index.go b/vendor/github.com/containers/image/v5/manifest/oci_index.go index 5b4111e4e..5bec43ff9 100644 --- a/vendor/github.com/containers/image/v5/manifest/oci_index.go +++ b/vendor/github.com/containers/image/v5/manifest/oci_index.go @@ -202,6 +202,10 @@ func OCI1IndexFromManifest(manifest []byte) (*OCI1Index, error) { if err := json.Unmarshal(manifest, &index); err != nil { return nil, errors.Wrapf(err, "unmarshaling OCI1Index %q", string(manifest)) } + if err := validateUnambiguousManifestFormat(manifest, imgspecv1.MediaTypeImageIndex, + allowedFieldManifests); err != nil { + return nil, err + } return &index, nil } diff --git a/vendor/github.com/containers/image/v5/oci/layout/oci_src.go b/vendor/github.com/containers/image/v5/oci/layout/oci_src.go index 55d3f637a..9d8ab689b 100644 --- a/vendor/github.com/containers/image/v5/oci/layout/oci_src.go +++ b/vendor/github.com/containers/image/v5/oci/layout/oci_src.go @@ -5,6 +5,7 @@ import ( "io" "io/ioutil" "net/http" + "net/url" "os" "strconv" @@ -113,7 +114,12 @@ func (s *ociImageSource) HasThreadSafeGetBlob() bool { // May update BlobInfoCache, preferably after it knows for certain that a blob truly exists at a specific location. func (s *ociImageSource) GetBlob(ctx context.Context, info types.BlobInfo, cache types.BlobInfoCache) (io.ReadCloser, int64, error) { if len(info.URLs) != 0 { - return s.getExternalBlob(ctx, info.URLs) + r, s, err := s.getExternalBlob(ctx, info.URLs) + if err != nil { + return nil, 0, err + } else if r != nil { + return r, s, nil + } } path, err := s.ref.blobPath(info.Digest, s.sharedBlobDir) @@ -140,34 +146,44 @@ func (s *ociImageSource) GetSignatures(ctx context.Context, instanceDigest *dige return [][]byte{}, nil } +// getExternalBlob returns the reader of the first available blob URL from urls, which must not be empty. +// This function can return nil reader when no url is supported by this function. In this case, the caller +// should fallback to fetch the non-external blob (i.e. pull from the registry). func (s *ociImageSource) getExternalBlob(ctx context.Context, urls []string) (io.ReadCloser, int64, error) { if len(urls) == 0 { return nil, 0, errors.New("internal error: getExternalBlob called with no URLs") } errWrap := errors.New("failed fetching external blob from all urls") - for _, url := range urls { - - req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + hasSupportedURL := false + for _, u := range urls { + if u, err := url.Parse(u); err != nil || (u.Scheme != "http" && u.Scheme != "https") { + continue // unsupported url. skip this url. + } + hasSupportedURL = true + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u, nil) if err != nil { - errWrap = errors.Wrapf(errWrap, "fetching %s failed %s", url, err.Error()) + errWrap = errors.Wrapf(errWrap, "fetching %s failed %s", u, err.Error()) continue } resp, err := s.client.Do(req) if err != nil { - errWrap = errors.Wrapf(errWrap, "fetching %s failed %s", url, err.Error()) + errWrap = errors.Wrapf(errWrap, "fetching %s failed %s", u, err.Error()) continue } if resp.StatusCode != http.StatusOK { resp.Body.Close() - errWrap = errors.Wrapf(errWrap, "fetching %s failed, response code not 200", url) + errWrap = errors.Wrapf(errWrap, "fetching %s failed, response code not 200", u) continue } return resp.Body, getBlobSize(resp), nil } + if !hasSupportedURL { + return nil, 0, nil // fallback to non-external blob + } return nil, 0, errWrap } diff --git a/vendor/github.com/containers/image/v5/pkg/docker/config/config.go b/vendor/github.com/containers/image/v5/pkg/docker/config/config.go index e37f4c19e..63f5bd53e 100644 --- a/vendor/github.com/containers/image/v5/pkg/docker/config/config.go +++ b/vendor/github.com/containers/image/v5/pkg/docker/config/config.go @@ -268,18 +268,18 @@ func getCredentialsWithHomeDir(sys *types.SystemContext, ref reference.Named, re } // Anonymous function to query credentials from auth files. - getCredentialsFromAuthFiles := func() (types.DockerAuthConfig, error) { + getCredentialsFromAuthFiles := func() (types.DockerAuthConfig, string, error) { for _, path := range getAuthFilePaths(sys, homeDir) { authConfig, err := findAuthentication(ref, registry, path.path, path.legacyFormat) if err != nil { - return types.DockerAuthConfig{}, err + return types.DockerAuthConfig{}, "", err } if (authConfig.Username != "" && authConfig.Password != "") || authConfig.IdentityToken != "" { - return authConfig, nil + return authConfig, path.path, nil } } - return types.DockerAuthConfig{}, nil + return types.DockerAuthConfig{}, "", nil } helpers, err := sysregistriesv2.CredentialHelpers(sys) @@ -289,12 +289,15 @@ func getCredentialsWithHomeDir(sys *types.SystemContext, ref reference.Named, re var multiErr error for _, helper := range helpers { - var creds types.DockerAuthConfig - var err error + var ( + creds types.DockerAuthConfig + credHelperPath string + err error + ) switch helper { // Special-case the built-in helper for auth files. case sysregistriesv2.AuthenticationFileHelper: - creds, err = getCredentialsFromAuthFiles() + creds, credHelperPath, err = getCredentialsFromAuthFiles() // External helpers. default: creds, err = getAuthFromCredHelper(helper, registry) @@ -307,7 +310,11 @@ func getCredentialsWithHomeDir(sys *types.SystemContext, ref reference.Named, re if len(creds.Username)+len(creds.Password)+len(creds.IdentityToken) == 0 { continue } - logrus.Debugf("Found credentials for %s in credential helper %s", registry, helper) + msg := fmt.Sprintf("Found credentials for %s in credential helper %s", registry, helper) + if credHelperPath != "" { + msg = fmt.Sprintf("%s in file %s", msg, credHelperPath) + } + logrus.Debug(msg) return creds, nil } if multiErr != nil { diff --git a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go index 4c1629f56..c8a603c4e 100644 --- a/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go +++ b/vendor/github.com/containers/image/v5/pkg/sysregistriesv2/system_registries_v2.go @@ -80,7 +80,7 @@ func (e *Endpoint) rewriteReference(ref reference.Named, prefix string) (referen // be dropped. // https://github.com/containers/image/pull/1191#discussion_r610621608 if e.Location == "" { - if prefix[:2] != "*." { + if !strings.HasPrefix(prefix, "*.") { return nil, fmt.Errorf("invalid prefix '%v' for empty location, should be in the format: *.example.com", prefix) } return ref, nil @@ -369,7 +369,7 @@ func (config *V2RegistriesConf) postProcessRegistries() error { } // FIXME: allow config authors to always use Prefix. // https://github.com/containers/image/pull/1191#discussion_r610622495 - if reg.Prefix[:2] != "*." && reg.Location == "" { + if !strings.HasPrefix(reg.Prefix, "*.") && reg.Location == "" { return &InvalidRegistries{s: "invalid condition: location is unset and prefix is not in the format: *.example.com"} } } @@ -804,7 +804,7 @@ func refMatchingSubdomainPrefix(ref, prefix string) int { // (This is split from the caller primarily to make testing easier.) func refMatchingPrefix(ref, prefix string) int { switch { - case prefix[0:2] == "*.": + case strings.HasPrefix(prefix, "*."): return refMatchingSubdomainPrefix(ref, prefix) case len(ref) < len(prefix): return -1 @@ -924,7 +924,7 @@ func loadConfigFile(path string, forceV2 bool) (*parsedConfig, error) { // https://github.com/containers/image/pull/1191#discussion_r610623829 for i := range res.partialV2.Registries { prefix := res.partialV2.Registries[i].Prefix - if prefix[:2] == "*." && strings.ContainsAny(prefix, "/@:") { + if strings.HasPrefix(prefix, "*.") && strings.ContainsAny(prefix, "/@:") { msg := fmt.Sprintf("Wildcarded prefix should be in the format: *.example.com. Current prefix %q is incorrectly formatted", prefix) return nil, &InvalidRegistries{s: msg} } diff --git a/vendor/github.com/containers/image/v5/storage/storage_transport.go b/vendor/github.com/containers/image/v5/storage/storage_transport.go index ab59c8a29..07393ee74 100644 --- a/vendor/github.com/containers/image/v5/storage/storage_transport.go +++ b/vendor/github.com/containers/image/v5/storage/storage_transport.go @@ -225,7 +225,7 @@ func (s *storageTransport) ParseReference(reference string) (types.ImageReferenc // needs to match a store that was previously initialized using // storage.GetStore(), or be enough to let the storage library fill out // the rest using knowledge that it has from elsewhere. - if reference[0] == '[' { + if len(reference) > 0 && reference[0] == '[' { closeIndex := strings.IndexRune(reference, ']') if closeIndex < 1 { return nil, ErrInvalidReference diff --git a/vendor/github.com/containers/image/v5/types/types.go b/vendor/github.com/containers/image/v5/types/types.go index 354b3f663..c98a6c6fd 100644 --- a/vendor/github.com/containers/image/v5/types/types.go +++ b/vendor/github.com/containers/image/v5/types/types.go @@ -622,6 +622,10 @@ type SystemContext struct { DockerLogMirrorChoice bool // Directory to use for OSTree temporary files OSTreeTmpDirPath string + // If true, all blobs will have precomputed digests to ensure layers are not uploaded that already exist on the registry. + // Note that this requires writing blobs to temporary files, and takes more time than the default behavior, + // when the digest for a blob is unknown. + DockerRegistryPushPrecomputeDigests bool // === docker/daemon.Transport overrides === // A directory containing a CA certificate (ending with ".crt"), diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go index 7f68c7cd0..ffb2a4ce2 100644 --- a/vendor/github.com/containers/image/v5/version/version.go +++ b/vendor/github.com/containers/image/v5/version/version.go @@ -6,9 +6,9 @@ const ( // VersionMajor is for an API incompatible changes VersionMajor = 5 // VersionMinor is for functionality in a backwards-compatible manner - VersionMinor = 16 + VersionMinor = 17 // VersionPatch is for backwards-compatible bug fixes - VersionPatch = 1 + VersionPatch = 0 // VersionDev indicates development branch. Releases will be empty string. VersionDev = "" diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go index 1efe7316d..15ba57467 100644 --- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go +++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go @@ -155,6 +155,15 @@ func hasMetacopyOption(opts []string) bool { return false } +func stripOption(opts []string, option string) []string { + for i, s := range opts { + if s == option { + return stripOption(append(opts[:i], opts[i+1:]...), option) + } + } + return opts +} + func hasVolatileOption(opts []string) bool { for _, s := range opts { if s == "volatile" { @@ -881,11 +890,18 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, disable if err != nil { return err } + + idPair := idtools.IDPair{ + UID: rootUID, + GID: rootGID, + } + // Make the link directory if it does not exist - if err := idtools.MkdirAllAs(path.Join(d.home, linkDir), 0700, rootUID, rootGID); err != nil { + if err := idtools.MkdirAllAndChownNew(path.Join(d.home, linkDir), 0700, idPair); err != nil { return err } - if err := idtools.MkdirAllAs(path.Dir(dir), 0700, rootUID, rootGID); err != nil { + + if err := idtools.MkdirAllAndChownNew(path.Dir(dir), 0700, idPair); err != nil { return err } if parent != "" { @@ -896,7 +912,7 @@ func (d *Driver) create(id, parent string, opts *graphdriver.CreateOpts, disable rootUID = int(st.UID()) rootGID = int(st.GID()) } - if err := idtools.MkdirAs(dir, 0700, rootUID, rootGID); err != nil { + if err := idtools.MkdirAllAndChownNew(dir, 0700, idPair); err != nil { return err } @@ -1175,7 +1191,7 @@ func (d *Driver) recreateSymlinks() error { // Read the "link" file under each layer to get the name of the symlink data, err := ioutil.ReadFile(path.Join(d.dir(dir.Name()), "link")) if err != nil { - errs = multierror.Append(errs, errors.Wrapf(err, "reading name of symlink for %q", dir)) + errs = multierror.Append(errs, errors.Wrapf(err, "reading name of symlink for %q", dir.Name())) continue } linkPath := path.Join(d.home, linkDir, strings.Trim(string(data), "\n")) @@ -1254,6 +1270,10 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO disableShifting = true } + logLevel := logrus.WarnLevel + if unshare.IsRootless() { + logLevel = logrus.DebugLevel + } optsList := options.Options if len(optsList) == 0 { optsList = strings.Split(d.options.mountOptions, ",") @@ -1262,16 +1282,18 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO // options otherwise the kernel refuses to follow the metacopy xattr. if hasMetacopyOption(strings.Split(d.options.mountOptions, ",")) && !hasMetacopyOption(options.Options) { if d.usingMetacopy { + logrus.StandardLogger().Logf(logrus.DebugLevel, "Adding metacopy option, configured globally") optsList = append(optsList, "metacopy=on") - } else { - logLevel := logrus.WarnLevel - if unshare.IsRootless() { - logLevel = logrus.DebugLevel - } - logrus.StandardLogger().Logf(logLevel, "Ignoring metacopy option from storage.conf, not supported with booted kernel") } } } + if !d.usingMetacopy { + if hasMetacopyOption(optsList) { + logrus.StandardLogger().Logf(logLevel, "Ignoring global metacopy option, not supported with booted kernel") + } + optsList = stripOption(optsList, "metacopy=on") + } + for _, o := range optsList { if o == "ro" { readWrite = false diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod index 2d68cc2ef..04d5adac4 100644 --- a/vendor/github.com/containers/storage/go.mod +++ b/vendor/github.com/containers/storage/go.mod @@ -4,9 +4,9 @@ module github.com/containers/storage require ( github.com/BurntSushi/toml v0.4.1 - github.com/Microsoft/go-winio v0.5.0 - github.com/Microsoft/hcsshim v0.9.0 - github.com/containerd/stargz-snapshotter/estargz v0.9.0 + github.com/Microsoft/go-winio v0.5.1 + github.com/Microsoft/hcsshim v0.9.1 + github.com/containerd/stargz-snapshotter/estargz v0.10.1 github.com/docker/go-units v0.4.0 github.com/google/go-intervals v0.0.2 github.com/hashicorp/go-multierror v1.1.1 @@ -15,11 +15,11 @@ require ( github.com/klauspost/pgzip v1.2.5 github.com/mattn/go-shellwords v1.0.12 github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible - github.com/moby/sys/mountinfo v0.4.1 + github.com/moby/sys/mountinfo v0.5.0 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/runc v1.0.2 github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 - github.com/opencontainers/selinux v1.9.1 + github.com/opencontainers/selinux v1.10.0 github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 @@ -28,6 +28,6 @@ require ( github.com/ulikunitz/xz v0.5.10 github.com/vbatts/tar-split v0.11.2 golang.org/x/net v0.0.0-20210825183410-e898025ed96a - golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55 + golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 gotest.tools v2.2.0+incompatible ) diff --git a/vendor/github.com/containers/storage/go.sum b/vendor/github.com/containers/storage/go.sum index ebb3a5a52..35328e287 100644 --- a/vendor/github.com/containers/storage/go.sum +++ b/vendor/github.com/containers/storage/go.sum @@ -47,8 +47,8 @@ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugX github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= -github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.1 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= +github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= @@ -57,8 +57,8 @@ github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2 github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= -github.com/Microsoft/hcsshim v0.9.0 h1:BBgYMxl5YZDZVIijz02AlDINpYZOzQqRNCl9CZM13vk= -github.com/Microsoft/hcsshim v0.9.0/go.mod h1:VBJWdC71NSWPlEo7lwde1aL21748J8B6Sdgno7NqEGE= +github.com/Microsoft/hcsshim v0.9.1 h1:VfDCj+QnY19ktX5TsH22JHcjaZ05RWQiwDbOyEg5ziM= +github.com/Microsoft/hcsshim v0.9.1/go.mod h1:Y/0uV2jUab5kBI7SQgl62at0AVX7uaruzADAVmxm3eM= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -92,6 +92,7 @@ github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7 github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -172,13 +173,14 @@ github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFY github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM= -github.com/containerd/stargz-snapshotter/estargz v0.9.0 h1:PkB6BSTfOKX23erT2GkoUKkJEcXfNcyKskIViK770v8= -github.com/containerd/stargz-snapshotter/estargz v0.9.0/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0= +github.com/containerd/stargz-snapshotter/estargz v0.10.1 h1:hd1EoVjI2Ax8Cr64tdYqnJ4i4pZU49FkEf5kU8KxQng= +github.com/containerd/stargz-snapshotter/estargz v0.10.1/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0= github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= +github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ= github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk= github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= @@ -457,8 +459,9 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= -github.com/moby/sys/mountinfo v0.4.1 h1:1O+1cHA1aujwEwwVMa2Xm2l+gIpUHyd3+D+d7LZh1kM= github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9ObI= +github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -522,8 +525,8 @@ github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mo github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= -github.com/opencontainers/selinux v1.9.1 h1:b4VPEF3O5JLZgdTDBmGepaaIbAo0GqoF6EBRq5f/g3Y= -github.com/opencontainers/selinux v1.9.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/opencontainers/selinux v1.10.0 h1:rAiKF8hTcgLI3w0DHm6i0ylVVcOrlgR1kK99DRLDhyU= +github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= @@ -833,8 +836,8 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55 h1:rw6UNGRMfarCepjI8qOepea/SXwIBVfTKjztZ5gBbq4= -golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 h1:2B5p2L5IfGiD7+b9BOoRMC6DgObAVZV+Fsp050NqXik= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -972,6 +975,7 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go b/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go index 6efc6a4c8..d18ab299b 100644 --- a/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go +++ b/vendor/github.com/containers/storage/pkg/chunked/storage_linux.go @@ -67,6 +67,24 @@ func timeToTimespec(time time.Time) (ts unix.Timespec) { return unix.NsecToTimespec(time.UnixNano()) } +func doHardLink(srcFd int, destDirFd int, destBase string) error { + doLink := func() error { + // Using unix.AT_EMPTY_PATH requires CAP_DAC_READ_SEARCH while this variant that uses + // /proc/self/fd doesn't and can be used with rootless. + srcPath := fmt.Sprintf("/proc/self/fd/%d", srcFd) + return unix.Linkat(unix.AT_FDCWD, srcPath, destDirFd, destBase, unix.AT_SYMLINK_FOLLOW) + } + + err := doLink() + + // if the destination exists, unlink it first and try again + if err != nil && os.IsExist(err) { + unix.Unlinkat(destDirFd, destBase, 0) + return doLink() + } + return err +} + func copyFileContent(srcFd int, destFile string, dirfd int, mode os.FileMode, useHardLinks bool) (*os.File, int64, error) { src := fmt.Sprintf("/proc/self/fd/%d", srcFd) st, err := os.Stat(src) @@ -83,20 +101,7 @@ func copyFileContent(srcFd int, destFile string, dirfd int, mode os.FileMode, us if err == nil { defer destDir.Close() - doLink := func() error { - // Using unix.AT_EMPTY_PATH requires CAP_DAC_READ_SEARCH while this variant that uses - // /proc/self/fd doesn't and can be used with rootless. - srcPath := fmt.Sprintf("/proc/self/fd/%d", srcFd) - return unix.Linkat(unix.AT_FDCWD, srcPath, int(destDir.Fd()), destBase, unix.AT_SYMLINK_FOLLOW) - } - - err := doLink() - - // if the destination exists, unlink it first and try again - if err != nil && os.IsExist(err) { - unix.Unlinkat(int(destDir.Fd()), destBase, 0) - err = doLink() - } + err := doHardLink(srcFd, int(destDir.Fd()), destBase) if err == nil { return nil, st.Size(), nil } @@ -797,7 +802,7 @@ func safeLink(dirfd int, mode os.FileMode, metadata *internal.FileMetadata, opti destDirFd = int(f.Fd()) } - err = unix.Linkat(int(sourceFile.Fd()), "", destDirFd, destBase, unix.AT_EMPTY_PATH) + err = doHardLink(int(sourceFile.Fd()), destDirFd, destBase) if err != nil { return err } @@ -861,7 +866,7 @@ func (d whiteoutHandler) Mknod(path string, mode uint32, dev int) error { func checkChownErr(err error, name string, uid, gid int) error { if errors.Is(err, syscall.EINVAL) { - return errors.Wrapf(err, "potentially insufficient UIDs or GIDs available in user namespace (requested %d:%d for %s): Check /etc/subuid and /etc/subgid", uid, gid, name) + return errors.Wrapf(err, "potentially insufficient UIDs or GIDs available in user namespace (requested %d:%d for %s): Check /etc/subuid and /etc/subgid if configured locally", uid, gid, name) } return err } diff --git a/vendor/github.com/containers/storage/pkg/idtools/idtools.go b/vendor/github.com/containers/storage/pkg/idtools/idtools.go index 83bc8c34f..83e797599 100644 --- a/vendor/github.com/containers/storage/pkg/idtools/idtools.go +++ b/vendor/github.com/containers/storage/pkg/idtools/idtools.go @@ -185,18 +185,14 @@ func (i *IDMappings) RootPair() IDPair { // Remapping is only performed if the ids aren't already the remapped root ids func (i *IDMappings) ToHost(pair IDPair) (IDPair, error) { var err error - target := i.RootPair() + var target IDPair - if pair.UID != target.UID { - target.UID, err = toHost(pair.UID, i.uids) - if err != nil { - return target, err - } + target.UID, err = toHost(pair.UID, i.uids) + if err != nil { + return target, err } - if pair.GID != target.GID { - target.GID, err = toHost(pair.GID, i.gids) - } + target.GID, err = toHost(pair.GID, i.gids) return target, err } @@ -293,7 +289,7 @@ func parseSubidFile(path, username string) (ranges, error) { func checkChownErr(err error, name string, uid, gid int) error { if e, ok := err.(*os.PathError); ok && e.Err == syscall.EINVAL { - return errors.Wrapf(err, "potentially insufficient UIDs or GIDs available in user namespace (requested %d:%d for %s): Check /etc/subuid and /etc/subgid", uid, gid, name) + return errors.Wrapf(err, "potentially insufficient UIDs or GIDs available in user namespace (requested %d:%d for %s): Check /etc/subuid and /etc/subgid if configured locally", uid, gid, name) } return err } diff --git a/vendor/github.com/containers/storage/pkg/idtools/idtools_unix.go b/vendor/github.com/containers/storage/pkg/idtools/idtools_unix.go index 9776b2a12..7f270c61f 100644 --- a/vendor/github.com/containers/storage/pkg/idtools/idtools_unix.go +++ b/vendor/github.com/containers/storage/pkg/idtools/idtools_unix.go @@ -46,6 +46,9 @@ func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chown // walk back to "/" looking for directories which do not exist // and add them to the paths array for chown after creation dirPath := path + if !filepath.IsAbs(dirPath) { + return fmt.Errorf("path: %s should be absolute", dirPath) + } for { dirPath = filepath.Dir(dirPath) if dirPath == "/" { diff --git a/vendor/github.com/containers/storage/pkg/reexec/command_linux.go b/vendor/github.com/containers/storage/pkg/reexec/command_linux.go index 372bee732..d3dd86d34 100644 --- a/vendor/github.com/containers/storage/pkg/reexec/command_linux.go +++ b/vendor/github.com/containers/storage/pkg/reexec/command_linux.go @@ -17,6 +17,7 @@ func Self() string { // This will use the in-memory version (/proc/self/exe) of the current binary, // it is thus safe to delete or replace the on-disk binary (os.Args[0]). func Command(args ...string) *exec.Cmd { + panicIfNotInitialized() cmd := exec.Command(Self()) cmd.Args = args return cmd @@ -26,6 +27,7 @@ func Command(args ...string) *exec.Cmd { // This will use the in-memory version (/proc/self/exe) of the current binary, // it is thus safe to delete or replace the on-disk binary (os.Args[0]). func CommandContext(ctx context.Context, args ...string) *exec.Cmd { + panicIfNotInitialized() cmd := exec.CommandContext(ctx, Self()) cmd.Args = args return cmd diff --git a/vendor/github.com/containers/storage/pkg/reexec/command_unix.go b/vendor/github.com/containers/storage/pkg/reexec/command_unix.go index 1ecaa906f..9dd8cb9bb 100644 --- a/vendor/github.com/containers/storage/pkg/reexec/command_unix.go +++ b/vendor/github.com/containers/storage/pkg/reexec/command_unix.go @@ -17,6 +17,7 @@ func Self() string { // For example if current binary is "docker" at "/usr/bin/", then cmd.Path will // be set to "/usr/bin/docker". func Command(args ...string) *exec.Cmd { + panicIfNotInitialized() cmd := exec.Command(Self()) cmd.Args = args return cmd @@ -24,6 +25,7 @@ func Command(args ...string) *exec.Cmd { // CommandContext returns *exec.Cmd which has Path as current binary. func CommandContext(ctx context.Context, args ...string) *exec.Cmd { + panicIfNotInitialized() cmd := exec.CommandContext(ctx, Self()) cmd.Args = args return cmd diff --git a/vendor/github.com/containers/storage/pkg/reexec/command_unsupported.go b/vendor/github.com/containers/storage/pkg/reexec/command_unsupported.go index 9d9374268..5b3605f31 100644 --- a/vendor/github.com/containers/storage/pkg/reexec/command_unsupported.go +++ b/vendor/github.com/containers/storage/pkg/reexec/command_unsupported.go @@ -9,10 +9,12 @@ import ( // Command is unsupported on operating systems apart from Linux, Windows, Solaris and Darwin. func Command(args ...string) *exec.Cmd { + panicIfNotInitialized() return nil } // CommandContext is unsupported on operating systems apart from Linux, Windows, Solaris and Darwin. func CommandContext(ctx context.Context, args ...string) *exec.Cmd { + panicIfNotInitialized() return nil } diff --git a/vendor/github.com/containers/storage/pkg/reexec/command_windows.go b/vendor/github.com/containers/storage/pkg/reexec/command_windows.go index 673ab476a..d86856476 100644 --- a/vendor/github.com/containers/storage/pkg/reexec/command_windows.go +++ b/vendor/github.com/containers/storage/pkg/reexec/command_windows.go @@ -17,6 +17,7 @@ func Self() string { // For example if current binary is "docker.exe" at "C:\", then cmd.Path will // be set to "C:\docker.exe". func Command(args ...string) *exec.Cmd { + panicIfNotInitialized() cmd := exec.Command(Self()) cmd.Args = args return cmd @@ -26,6 +27,7 @@ func Command(args ...string) *exec.Cmd { // For example if current binary is "docker.exe" at "C:\", then cmd.Path will // be set to "C:\docker.exe". func CommandContext(ctx context.Context, args ...string) *exec.Cmd { + panicIfNotInitialized() cmd := exec.CommandContext(ctx, Self()) cmd.Args = args return cmd diff --git a/vendor/github.com/containers/storage/pkg/reexec/reexec.go b/vendor/github.com/containers/storage/pkg/reexec/reexec.go index c56671d91..a1938cd4f 100644 --- a/vendor/github.com/containers/storage/pkg/reexec/reexec.go +++ b/vendor/github.com/containers/storage/pkg/reexec/reexec.go @@ -7,7 +7,10 @@ import ( "path/filepath" ) -var registeredInitializers = make(map[string]func()) +var ( + registeredInitializers = make(map[string]func()) + initWasCalled = false +) // Register adds an initialization func under the specified name func Register(name string, initializer func()) { @@ -22,6 +25,7 @@ func Register(name string, initializer func()) { // initialization function was called. func Init() bool { initializer, exists := registeredInitializers[os.Args[0]] + initWasCalled = true if exists { initializer() @@ -30,6 +34,21 @@ func Init() bool { return false } +func panicIfNotInitialized() { + if !initWasCalled { + // The reexec package is used to run subroutines in + // subprocesses which would otherwise have unacceptable side + // effects on the main thread. If you found this error, then + // your program uses a package which needs to do this. In + // order for that to work, main() should start with this + // boilerplate, or an equivalent: + // if reexec.Init() { + // return + // } + panic("a library subroutine needed to run a subprocess, but reexec.Init() was not called in main()") + } +} + func naiveSelf() string { name := os.Args[0] if filepath.Base(name) == name { diff --git a/vendor/github.com/containers/storage/storage.conf b/vendor/github.com/containers/storage/storage.conf index bf1534adc..c17dd6d37 100644 --- a/vendor/github.com/containers/storage/storage.conf +++ b/vendor/github.com/containers/storage/storage.conf @@ -1,5 +1,14 @@ # This file is is the configuration file for all tools -# that use the containers/storage library. +# that use the containers/storage library. The storage.conf file +# overrides all other storage.conf files. Container engines using the +# container/storage library do not inherit fields from other storage.conf +# files. +# +# Note: The storage.conf file overrides other storage.conf files based on this precedence: +# /usr/containers/storage.conf +# /etc/containers/storage.conf +# $HOME/.config/containers/storage.conf +# $XDG_CONFIG_HOME/containers/storage.conf (If XDG_CONFIG_HOME is set) # See man 5 containers-storage.conf for more information # The "container storage" table contains all of the server options. [storage] diff --git a/vendor/github.com/containers/storage/store.go b/vendor/github.com/containers/storage/store.go index 4d28eb140..bf1cd4f38 100644 --- a/vendor/github.com/containers/storage/store.go +++ b/vendor/github.com/containers/storage/store.go @@ -2371,22 +2371,16 @@ func (s *store) DeleteImage(id string, commit bool) (layers []string, err error) if err != nil { return nil, err } - childrenByParent := make(map[string]*[]string) + childrenByParent := make(map[string][]string) for _, layer := range layers { - parent := layer.Parent - if list, ok := childrenByParent[parent]; ok { - newList := append(*list, layer.ID) - childrenByParent[parent] = &newList - } else { - childrenByParent[parent] = &([]string{layer.ID}) - } + childrenByParent[layer.Parent] = append(childrenByParent[layer.Parent], layer.ID) } - otherImagesByTopLayer := make(map[string]string) + otherImagesTopLayers := make(map[string]struct{}) for _, img := range images { if img.ID != id { - otherImagesByTopLayer[img.TopLayer] = img.ID + otherImagesTopLayers[img.TopLayer] = struct{}{} for _, layerID := range img.MappedTopLayers { - otherImagesByTopLayer[layerID] = img.ID + otherImagesTopLayers[layerID] = struct{}{} } } } @@ -2396,43 +2390,46 @@ func (s *store) DeleteImage(id string, commit bool) (layers []string, err error) } } layer := image.TopLayer - lastRemoved := "" + layersToRemoveMap := make(map[string]struct{}) for layer != "" { if rcstore.Exists(layer) { break } - if _, ok := otherImagesByTopLayer[layer]; ok { + if _, used := otherImagesTopLayers[layer]; used { break } parent := "" if l, err := rlstore.Get(layer); err == nil { parent = l.Parent } - hasOtherRefs := func() bool { + hasChildrenNotBeingRemoved := func() bool { layersToCheck := []string{layer} if layer == image.TopLayer { layersToCheck = append(layersToCheck, image.MappedTopLayers...) } for _, layer := range layersToCheck { - if childList, ok := childrenByParent[layer]; ok && childList != nil { - children := *childList - for _, child := range children { - if child != lastRemoved { - return true + if childList := childrenByParent[layer]; len(childList) > 0 { + for _, child := range childList { + if _, childIsSlatedForRemoval := layersToRemoveMap[child]; childIsSlatedForRemoval { + continue } + return true } } } return false } - if hasOtherRefs() { + if hasChildrenNotBeingRemoved() { break } - lastRemoved = layer if layer == image.TopLayer { layersToRemove = append(layersToRemove, image.MappedTopLayers...) + for _, mappedTopLayer := range image.MappedTopLayers { + layersToRemoveMap[mappedTopLayer] = struct{}{} + } } - layersToRemove = append(layersToRemove, lastRemoved) + layersToRemove = append(layersToRemove, layer) + layersToRemoveMap[layer] = struct{}{} layer = parent } } else { diff --git a/vendor/github.com/juju/ansiterm/LICENSE b/vendor/github.com/juju/ansiterm/LICENSE deleted file mode 100644 index ade9307b3..000000000 --- a/vendor/github.com/juju/ansiterm/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -All files in this repository are licensed as follows. If you contribute -to this repository, it is assumed that you license your contribution -under the same license unless you state otherwise. - -All files Copyright (C) 2015 Canonical Ltd. unless otherwise specified in the file. - -This software is licensed under the LGPLv3, included below. - -As a special exception to the GNU Lesser General Public License version 3 -("LGPL3"), the copyright holders of this Library give you permission to -convey to a third party a Combined Work that links statically or dynamically -to this Library without providing any Minimal Corresponding Source or -Minimal Application Code as set out in 4d or providing the installation -information set out in section 4e, provided that you comply with the other -provisions of LGPL3 and provided that you meet, for the Application the -terms and conditions of the license(s) which apply to the Application. - -Except as stated in this special exception, the provisions of LGPL3 will -continue to comply in full to this Library. If you modify this Library, you -may apply this exception to your version of this Library, but you are not -obliged to do so. If you do not wish to do so, delete this exception -statement from your version. This exception does not (and cannot) modify any -license terms which apply to the Application, with which you must still -comply. - - - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/vendor/github.com/juju/ansiterm/Makefile b/vendor/github.com/juju/ansiterm/Makefile deleted file mode 100644 index 212fdcbe5..000000000 --- a/vendor/github.com/juju/ansiterm/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright 2016 Canonical Ltd. -# Licensed under the LGPLv3, see LICENCE file for details. - -default: check - -check: - go test - -docs: - godoc2md github.com/juju/ansiterm > README.md - sed -i 's|\[godoc-link-here\]|[![GoDoc](https://godoc.org/github.com/juju/ansiterm?status.svg)](https://godoc.org/github.com/juju/ansiterm)|' README.md - - -.PHONY: default check docs diff --git a/vendor/github.com/juju/ansiterm/README.md b/vendor/github.com/juju/ansiterm/README.md deleted file mode 100644 index 567438721..000000000 --- a/vendor/github.com/juju/ansiterm/README.md +++ /dev/null @@ -1,323 +0,0 @@ - -# ansiterm - import "github.com/juju/ansiterm" - -Package ansiterm provides a Writer that writes out the ANSI escape -codes for color and styles. - - - - - - - -## type Color -``` go -type Color int -``` -Color represents one of the standard 16 ANSI colors. - - - -``` go -const ( - Default Color - Black - Red - Green - Yellow - Blue - Magenta - Cyan - Gray - DarkGray - BrightRed - BrightGreen - BrightYellow - BrightBlue - BrightMagenta - BrightCyan - White -) -``` - - - - - - - - -### func (Color) String -``` go -func (c Color) String() string -``` -String returns the name of the color. - - - -## type Context -``` go -type Context struct { - Foreground Color - Background Color - Styles []Style -} -``` -Context provides a way to specify both foreground and background colors -along with other styles and write text to a Writer with those colors and -styles. - - - - - - - - - -### func Background -``` go -func Background(color Color) *Context -``` -Background is a convenience function that creates a Context with the -specified color as the background color. - - -### func Foreground -``` go -func Foreground(color Color) *Context -``` -Foreground is a convenience function that creates a Context with the -specified color as the foreground color. - - -### func Styles -``` go -func Styles(styles ...Style) *Context -``` -Styles is a convenience function that creates a Context with the -specified styles set. - - - - -### func (\*Context) Fprint -``` go -func (c *Context) Fprint(w sgrWriter, args ...interface{}) -``` -Fprint will set the sgr values of the writer to the specified foreground, -background and styles, then formats using the default formats for its -operands and writes to w. Spaces are added between operands when neither is -a string. It returns the number of bytes written and any write error -encountered. - - - -### func (\*Context) Fprintf -``` go -func (c *Context) Fprintf(w sgrWriter, format string, args ...interface{}) -``` -Fprintf will set the sgr values of the writer to the specified -foreground, background and styles, then write the formatted string, -then reset the writer. - - - -### func (\*Context) SetBackground -``` go -func (c *Context) SetBackground(color Color) *Context -``` -SetBackground sets the background to the specified color. - - - -### func (\*Context) SetForeground -``` go -func (c *Context) SetForeground(color Color) *Context -``` -SetForeground sets the foreground to the specified color. - - - -### func (\*Context) SetStyle -``` go -func (c *Context) SetStyle(styles ...Style) *Context -``` -SetStyle replaces the styles with the new values. - - - -## type Style -``` go -type Style int -``` - - -``` go -const ( - Bold Style - Faint - Italic - Underline - Blink - Reverse - Strikethrough - Conceal -) -``` - - - - - - - - -### func (Style) String -``` go -func (s Style) String() string -``` - - -## type TabWriter -``` go -type TabWriter struct { - Writer - // contains filtered or unexported fields -} -``` -TabWriter is a filter that inserts padding around tab-delimited -columns in its input to align them in the output. - -It also setting of colors and styles over and above the standard -tabwriter package. - - - - - - - - - -### func NewTabWriter -``` go -func NewTabWriter(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *TabWriter -``` -NewTabWriter returns a writer that is able to set colors and styels. -The ansi escape codes are stripped for width calculations. - - - - -### func (\*TabWriter) Flush -``` go -func (t *TabWriter) Flush() error -``` -Flush should be called after the last call to Write to ensure -that any data buffered in the Writer is written to output. Any -incomplete escape sequence at the end is considered -complete for formatting purposes. - - - -### func (\*TabWriter) Init -``` go -func (t *TabWriter) Init(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *TabWriter -``` -A Writer must be initialized with a call to Init. The first parameter (output) -specifies the filter output. The remaining parameters control the formatting: - - - minwidth minimal cell width including any padding - tabwidth width of tab characters (equivalent number of spaces) - padding padding added to a cell before computing its width - padchar ASCII char used for padding - if padchar == '\t', the Writer will assume that the - width of a '\t' in the formatted output is tabwidth, - and cells are left-aligned independent of align_left - (for correct-looking results, tabwidth must correspond - to the tab width in the viewer displaying the result) - flags formatting control - - - -## type Writer -``` go -type Writer struct { - io.Writer - // contains filtered or unexported fields -} -``` -Writer allows colors and styles to be specified. If the io.Writer -is not a terminal capable of color, all attempts to set colors or -styles are no-ops. - - - - - - - - - -### func NewWriter -``` go -func NewWriter(w io.Writer) *Writer -``` -NewWriter returns a Writer that allows the caller to specify colors and -styles. If the io.Writer is not a terminal capable of color, all attempts -to set colors or styles are no-ops. - - - - -### func (\*Writer) ClearStyle -``` go -func (w *Writer) ClearStyle(s Style) -``` -ClearStyle clears the text style. - - - -### func (\*Writer) Reset -``` go -func (w *Writer) Reset() -``` -Reset returns the default foreground and background colors with no styles. - - - -### func (\*Writer) SetBackground -``` go -func (w *Writer) SetBackground(c Color) -``` -SetBackground sets the background color. - - - -### func (\*Writer) SetForeground -``` go -func (w *Writer) SetForeground(c Color) -``` -SetForeground sets the foreground color. - - - -### func (\*Writer) SetStyle -``` go -func (w *Writer) SetStyle(s Style) -``` -SetStyle sets the text style. - - - - - - - - - -- - - -Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md)
\ No newline at end of file diff --git a/vendor/github.com/juju/ansiterm/attribute.go b/vendor/github.com/juju/ansiterm/attribute.go deleted file mode 100644 index f2daa4813..000000000 --- a/vendor/github.com/juju/ansiterm/attribute.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package ansiterm - -import ( - "fmt" - "sort" - "strings" -) - -type attribute int - -const ( - unknownAttribute attribute = -1 - reset attribute = 0 -) - -// sgr returns the escape sequence for the Select Graphic Rendition -// for the attribute. -func (a attribute) sgr() string { - if a < 0 { - return "" - } - return fmt.Sprintf("\x1b[%dm", a) -} - -type attributes []attribute - -func (a attributes) Len() int { return len(a) } -func (a attributes) Less(i, j int) bool { return a[i] < a[j] } -func (a attributes) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - -// sgr returns the combined escape sequence for the Select Graphic Rendition -// for the sequence of attributes. -func (a attributes) sgr() string { - switch len(a) { - case 0: - return "" - case 1: - return a[0].sgr() - default: - sort.Sort(a) - var values []string - for _, attr := range a { - values = append(values, fmt.Sprint(attr)) - } - return fmt.Sprintf("\x1b[%sm", strings.Join(values, ";")) - } -} diff --git a/vendor/github.com/juju/ansiterm/color.go b/vendor/github.com/juju/ansiterm/color.go deleted file mode 100644 index 0a97de31e..000000000 --- a/vendor/github.com/juju/ansiterm/color.go +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package ansiterm - -const ( - _ Color = iota - Default - Black - Red - Green - Yellow - Blue - Magenta - Cyan - Gray - DarkGray - BrightRed - BrightGreen - BrightYellow - BrightBlue - BrightMagenta - BrightCyan - White -) - -// Color represents one of the standard 16 ANSI colors. -type Color int - -// String returns the name of the color. -func (c Color) String() string { - switch c { - case Default: - return "default" - case Black: - return "black" - case Red: - return "red" - case Green: - return "green" - case Yellow: - return "yellow" - case Blue: - return "blue" - case Magenta: - return "magenta" - case Cyan: - return "cyan" - case Gray: - return "gray" - case DarkGray: - return "darkgray" - case BrightRed: - return "brightred" - case BrightGreen: - return "brightgreen" - case BrightYellow: - return "brightyellow" - case BrightBlue: - return "brightblue" - case BrightMagenta: - return "brightmagenta" - case BrightCyan: - return "brightcyan" - case White: - return "white" - default: - return "" - } -} - -func (c Color) foreground() attribute { - switch c { - case Default: - return 39 - case Black: - return 30 - case Red: - return 31 - case Green: - return 32 - case Yellow: - return 33 - case Blue: - return 34 - case Magenta: - return 35 - case Cyan: - return 36 - case Gray: - return 37 - case DarkGray: - return 90 - case BrightRed: - return 91 - case BrightGreen: - return 92 - case BrightYellow: - return 93 - case BrightBlue: - return 94 - case BrightMagenta: - return 95 - case BrightCyan: - return 96 - case White: - return 97 - default: - return unknownAttribute - } -} - -func (c Color) background() attribute { - value := c.foreground() - if value != unknownAttribute { - return value + 10 - } - return value -} diff --git a/vendor/github.com/juju/ansiterm/context.go b/vendor/github.com/juju/ansiterm/context.go deleted file mode 100644 index e61a867ff..000000000 --- a/vendor/github.com/juju/ansiterm/context.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package ansiterm - -import ( - "fmt" - "io" -) - -// Context provides a way to specify both foreground and background colors -// along with other styles and write text to a Writer with those colors and -// styles. -type Context struct { - Foreground Color - Background Color - Styles []Style -} - -// Foreground is a convenience function that creates a Context with the -// specified color as the foreground color. -func Foreground(color Color) *Context { - return &Context{Foreground: color} -} - -// Background is a convenience function that creates a Context with the -// specified color as the background color. -func Background(color Color) *Context { - return &Context{Background: color} -} - -// Styles is a convenience function that creates a Context with the -// specified styles set. -func Styles(styles ...Style) *Context { - return &Context{Styles: styles} -} - -// SetForeground sets the foreground to the specified color. -func (c *Context) SetForeground(color Color) *Context { - c.Foreground = color - return c -} - -// SetBackground sets the background to the specified color. -func (c *Context) SetBackground(color Color) *Context { - c.Background = color - return c -} - -// SetStyle replaces the styles with the new values. -func (c *Context) SetStyle(styles ...Style) *Context { - c.Styles = styles - return c -} - -type sgrWriter interface { - io.Writer - writeSGR(value sgr) -} - -// Fprintf will set the sgr values of the writer to the specified -// foreground, background and styles, then write the formatted string, -// then reset the writer. -func (c *Context) Fprintf(w sgrWriter, format string, args ...interface{}) { - w.writeSGR(c) - fmt.Fprintf(w, format, args...) - w.writeSGR(reset) -} - -// Fprint will set the sgr values of the writer to the specified foreground, -// background and styles, then formats using the default formats for its -// operands and writes to w. Spaces are added between operands when neither is -// a string. It returns the number of bytes written and any write error -// encountered. -func (c *Context) Fprint(w sgrWriter, args ...interface{}) { - w.writeSGR(c) - fmt.Fprint(w, args...) - w.writeSGR(reset) -} - -func (c *Context) sgr() string { - var values attributes - if foreground := c.Foreground.foreground(); foreground != unknownAttribute { - values = append(values, foreground) - } - if background := c.Background.background(); background != unknownAttribute { - values = append(values, background) - } - for _, style := range c.Styles { - if value := style.enable(); value != unknownAttribute { - values = append(values, value) - } - } - return values.sgr() -} diff --git a/vendor/github.com/juju/ansiterm/doc.go b/vendor/github.com/juju/ansiterm/doc.go deleted file mode 100644 index 782700779..000000000 --- a/vendor/github.com/juju/ansiterm/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -// Package ansiterm provides a Writer that writes out the ANSI escape -// codes for color and styles. -package ansiterm diff --git a/vendor/github.com/juju/ansiterm/style.go b/vendor/github.com/juju/ansiterm/style.go deleted file mode 100644 index 0be42da56..000000000 --- a/vendor/github.com/juju/ansiterm/style.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package ansiterm - -const ( - _ Style = iota - Bold - Faint - Italic - Underline - Blink - Reverse - Strikethrough - Conceal -) - -type Style int - -func (s Style) String() string { - switch s { - case Bold: - return "bold" - case Faint: - return "faint" - case Italic: - return "italic" - case Underline: - return "underline" - case Blink: - return "blink" - case Reverse: - return "reverse" - case Strikethrough: - return "strikethrough" - case Conceal: - return "conceal" - default: - return "" - } -} - -func (s Style) enable() attribute { - switch s { - case Bold: - return 1 - case Faint: - return 2 - case Italic: - return 3 - case Underline: - return 4 - case Blink: - return 5 - case Reverse: - return 7 - case Conceal: - return 8 - case Strikethrough: - return 9 - default: - return unknownAttribute - } -} - -func (s Style) disable() attribute { - value := s.enable() - if value != unknownAttribute { - return value + 20 - } - return value -} diff --git a/vendor/github.com/juju/ansiterm/tabwriter.go b/vendor/github.com/juju/ansiterm/tabwriter.go deleted file mode 100644 index 1ff6faaaf..000000000 --- a/vendor/github.com/juju/ansiterm/tabwriter.go +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package ansiterm - -import ( - "io" - - "github.com/juju/ansiterm/tabwriter" -) - -// NewTabWriter returns a writer that is able to set colors and styels. -// The ansi escape codes are stripped for width calculations. -func NewTabWriter(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *TabWriter { - return new(TabWriter).Init(output, minwidth, tabwidth, padding, padchar, flags) -} - -// TabWriter is a filter that inserts padding around tab-delimited -// columns in its input to align them in the output. -// -// It also setting of colors and styles over and above the standard -// tabwriter package. -type TabWriter struct { - Writer - tw tabwriter.Writer -} - -// Flush should be called after the last call to Write to ensure -// that any data buffered in the Writer is written to output. Any -// incomplete escape sequence at the end is considered -// complete for formatting purposes. -// -func (t *TabWriter) Flush() error { - return t.tw.Flush() -} - -// SetColumnAlignRight will mark a particular column as align right. -// This is reset on the next flush. -func (t *TabWriter) SetColumnAlignRight(column int) { - t.tw.SetColumnAlignRight(column) -} - -// A Writer must be initialized with a call to Init. The first parameter (output) -// specifies the filter output. The remaining parameters control the formatting: -// -// minwidth minimal cell width including any padding -// tabwidth width of tab characters (equivalent number of spaces) -// padding padding added to a cell before computing its width -// padchar ASCII char used for padding -// if padchar == '\t', the Writer will assume that the -// width of a '\t' in the formatted output is tabwidth, -// and cells are left-aligned independent of align_left -// (for correct-looking results, tabwidth must correspond -// to the tab width in the viewer displaying the result) -// flags formatting control -// -func (t *TabWriter) Init(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *TabWriter { - writer, colorCapable := colorEnabledWriter(output) - t.Writer = Writer{ - Writer: t.tw.Init(writer, minwidth, tabwidth, padding, padchar, flags), - noColor: !colorCapable, - } - return t -} diff --git a/vendor/github.com/juju/ansiterm/tabwriter/LICENSE b/vendor/github.com/juju/ansiterm/tabwriter/LICENSE deleted file mode 100644 index 744875676..000000000 --- a/vendor/github.com/juju/ansiterm/tabwriter/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2012 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/juju/ansiterm/tabwriter/tabwriter.go b/vendor/github.com/juju/ansiterm/tabwriter/tabwriter.go deleted file mode 100644 index 98949d036..000000000 --- a/vendor/github.com/juju/ansiterm/tabwriter/tabwriter.go +++ /dev/null @@ -1,587 +0,0 @@ -// 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. - -// This file is mostly a copy of the go standard library text/tabwriter. With -// the additional stripping of ansi control characters for width calculations. - -// Package tabwriter implements a write filter (tabwriter.Writer) that -// translates tabbed columns in input into properly aligned text. -// -// The package is using the Elastic Tabstops algorithm described at -// http://nickgravgaard.com/elastictabstops/index.html. -// -package tabwriter - -import ( - "bytes" - "io" - "unicode/utf8" - - "github.com/lunixbochs/vtclean" -) - -// ---------------------------------------------------------------------------- -// Filter implementation - -// A cell represents a segment of text terminated by tabs or line breaks. -// The text itself is stored in a separate buffer; cell only describes the -// segment's size in bytes, its width in runes, and whether it's an htab -// ('\t') terminated cell. -// -type cell struct { - size int // cell size in bytes - width int // cell width in runes - htab bool // true if the cell is terminated by an htab ('\t') -} - -// A Writer is a filter that inserts padding around tab-delimited -// columns in its input to align them in the output. -// -// The Writer treats incoming bytes as UTF-8 encoded text consisting -// of cells terminated by (horizontal or vertical) tabs or line -// breaks (newline or formfeed characters). Cells in adjacent lines -// constitute a column. The Writer inserts padding as needed to -// make all cells in a column have the same width, effectively -// aligning the columns. It assumes that all characters have the -// same width except for tabs for which a tabwidth must be specified. -// Note that cells are tab-terminated, not tab-separated: trailing -// non-tab text at the end of a line does not form a column cell. -// -// The Writer assumes that all Unicode code points have the same width; -// this may not be true in some fonts. -// -// If DiscardEmptyColumns is set, empty columns that are terminated -// entirely by vertical (or "soft") tabs are discarded. Columns -// terminated by horizontal (or "hard") tabs are not affected by -// this flag. -// -// If a Writer is configured to filter HTML, HTML tags and entities -// are passed through. The widths of tags and entities are -// assumed to be zero (tags) and one (entities) for formatting purposes. -// -// A segment of text may be escaped by bracketing it with Escape -// characters. The tabwriter passes escaped text segments through -// unchanged. In particular, it does not interpret any tabs or line -// breaks within the segment. If the StripEscape flag is set, the -// Escape characters are stripped from the output; otherwise they -// are passed through as well. For the purpose of formatting, the -// width of the escaped text is always computed excluding the Escape -// characters. -// -// The formfeed character ('\f') acts like a newline but it also -// terminates all columns in the current line (effectively calling -// Flush). Cells in the next line start new columns. Unless found -// inside an HTML tag or inside an escaped text segment, formfeed -// characters appear as newlines in the output. -// -// The Writer must buffer input internally, because proper spacing -// of one line may depend on the cells in future lines. Clients must -// call Flush when done calling Write. -// -type Writer struct { - // configuration - output io.Writer - minwidth int - tabwidth int - padding int - padbytes [8]byte - flags uint - - // current state - buf bytes.Buffer // collected text excluding tabs or line breaks - pos int // buffer position up to which cell.width of incomplete cell has been computed - cell cell // current incomplete cell; cell.width is up to buf[pos] excluding ignored sections - endChar byte // terminating char of escaped sequence (Escape for escapes, '>', ';' for HTML tags/entities, or 0) - lines [][]cell // list of lines; each line is a list of cells - widths []int // list of column widths in runes - re-used during formatting - alignment map[int]uint // column alignment -} - -func (b *Writer) addLine() { b.lines = append(b.lines, []cell{}) } - -// Reset the current state. -func (b *Writer) reset() { - b.buf.Reset() - b.pos = 0 - b.cell = cell{} - b.endChar = 0 - b.lines = b.lines[0:0] - b.widths = b.widths[0:0] - b.alignment = make(map[int]uint) - b.addLine() -} - -// Internal representation (current state): -// -// - all text written is appended to buf; tabs and line breaks are stripped away -// - at any given time there is a (possibly empty) incomplete cell at the end -// (the cell starts after a tab or line break) -// - cell.size is the number of bytes belonging to the cell so far -// - cell.width is text width in runes of that cell from the start of the cell to -// position pos; html tags and entities are excluded from this width if html -// filtering is enabled -// - the sizes and widths of processed text are kept in the lines list -// which contains a list of cells for each line -// - the widths list is a temporary list with current widths used during -// formatting; it is kept in Writer because it's re-used -// -// |<---------- size ---------->| -// | | -// |<- width ->|<- ignored ->| | -// | | | | -// [---processed---tab------------<tag>...</tag>...] -// ^ ^ ^ -// | | | -// buf start of incomplete cell pos - -// Formatting can be controlled with these flags. -const ( - // Ignore html tags and treat entities (starting with '&' - // and ending in ';') as single characters (width = 1). - FilterHTML uint = 1 << iota - - // Strip Escape characters bracketing escaped text segments - // instead of passing them through unchanged with the text. - StripEscape - - // Force right-alignment of cell content. - // Default is left-alignment. - AlignRight - - // Handle empty columns as if they were not present in - // the input in the first place. - DiscardEmptyColumns - - // Always use tabs for indentation columns (i.e., padding of - // leading empty cells on the left) independent of padchar. - TabIndent - - // Print a vertical bar ('|') between columns (after formatting). - // Discarded columns appear as zero-width columns ("||"). - Debug -) - -// A Writer must be initialized with a call to Init. The first parameter (output) -// specifies the filter output. The remaining parameters control the formatting: -// -// minwidth minimal cell width including any padding -// tabwidth width of tab characters (equivalent number of spaces) -// padding padding added to a cell before computing its width -// padchar ASCII char used for padding -// if padchar == '\t', the Writer will assume that the -// width of a '\t' in the formatted output is tabwidth, -// and cells are left-aligned independent of align_left -// (for correct-looking results, tabwidth must correspond -// to the tab width in the viewer displaying the result) -// flags formatting control -// -func (b *Writer) Init(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *Writer { - if minwidth < 0 || tabwidth < 0 || padding < 0 { - panic("negative minwidth, tabwidth, or padding") - } - b.output = output - b.minwidth = minwidth - b.tabwidth = tabwidth - b.padding = padding - for i := range b.padbytes { - b.padbytes[i] = padchar - } - if padchar == '\t' { - // tab padding enforces left-alignment - flags &^= AlignRight - } - b.flags = flags - - b.reset() - - return b -} - -// debugging support (keep code around) -func (b *Writer) dump() { - pos := 0 - for i, line := range b.lines { - print("(", i, ") ") - for _, c := range line { - print("[", string(b.buf.Bytes()[pos:pos+c.size]), "]") - pos += c.size - } - print("\n") - } - print("\n") -} - -// local error wrapper so we can distinguish errors we want to return -// as errors from genuine panics (which we don't want to return as errors) -type osError struct { - err error -} - -func (b *Writer) write0(buf []byte) { - n, err := b.output.Write(buf) - if n != len(buf) && err == nil { - err = io.ErrShortWrite - } - if err != nil { - panic(osError{err}) - } -} - -func (b *Writer) writeN(src []byte, n int) { - for n > len(src) { - b.write0(src) - n -= len(src) - } - b.write0(src[0:n]) -} - -var ( - newline = []byte{'\n'} - tabs = []byte("\t\t\t\t\t\t\t\t") -) - -func (b *Writer) writePadding(textw, cellw int, useTabs bool) { - if b.padbytes[0] == '\t' || useTabs { - // padding is done with tabs - if b.tabwidth == 0 { - return // tabs have no width - can't do any padding - } - // make cellw the smallest multiple of b.tabwidth - cellw = (cellw + b.tabwidth - 1) / b.tabwidth * b.tabwidth - n := cellw - textw // amount of padding - if n < 0 { - panic("internal error") - } - b.writeN(tabs, (n+b.tabwidth-1)/b.tabwidth) - return - } - - // padding is done with non-tab characters - b.writeN(b.padbytes[0:], cellw-textw) -} - -var vbar = []byte{'|'} - -func (b *Writer) writeLines(pos0 int, line0, line1 int) (pos int) { - pos = pos0 - for i := line0; i < line1; i++ { - line := b.lines[i] - - // if TabIndent is set, use tabs to pad leading empty cells - useTabs := b.flags&TabIndent != 0 - - for j, c := range line { - if j > 0 && b.flags&Debug != 0 { - // indicate column break - b.write0(vbar) - } - - if c.size == 0 { - // empty cell - if j < len(b.widths) { - b.writePadding(c.width, b.widths[j], useTabs) - } - } else { - // non-empty cell - useTabs = false - alignColumnRight := b.alignment[j] == AlignRight - if (b.flags&AlignRight == 0) && !alignColumnRight { // align left - b.write0(b.buf.Bytes()[pos : pos+c.size]) - pos += c.size - if j < len(b.widths) { - b.writePadding(c.width, b.widths[j], false) - } - } else if alignColumnRight && j < len(b.widths) { - // just this column - internalSize := b.widths[j] - b.padding - if j < len(b.widths) { - b.writePadding(c.width, internalSize, false) - } - b.write0(b.buf.Bytes()[pos : pos+c.size]) - if b.padding > 0 { - b.writePadding(0, b.padding, false) - } - pos += c.size - } else { // align right - if j < len(b.widths) { - b.writePadding(c.width, b.widths[j], false) - } - b.write0(b.buf.Bytes()[pos : pos+c.size]) - pos += c.size - } - } - } - - if i+1 == len(b.lines) { - // last buffered line - we don't have a newline, so just write - // any outstanding buffered data - b.write0(b.buf.Bytes()[pos : pos+b.cell.size]) - pos += b.cell.size - } else { - // not the last line - write newline - b.write0(newline) - } - } - return -} - -// Format the text between line0 and line1 (excluding line1); pos -// is the buffer position corresponding to the beginning of line0. -// Returns the buffer position corresponding to the beginning of -// line1 and an error, if any. -// -func (b *Writer) format(pos0 int, line0, line1 int) (pos int) { - pos = pos0 - column := len(b.widths) - for this := line0; this < line1; this++ { - line := b.lines[this] - - if column < len(line)-1 { - // cell exists in this column => this line - // has more cells than the previous line - // (the last cell per line is ignored because cells are - // tab-terminated; the last cell per line describes the - // text before the newline/formfeed and does not belong - // to a column) - - // print unprinted lines until beginning of block - pos = b.writeLines(pos, line0, this) - line0 = this - - // column block begin - width := b.minwidth // minimal column width - discardable := true // true if all cells in this column are empty and "soft" - for ; this < line1; this++ { - line = b.lines[this] - if column < len(line)-1 { - // cell exists in this column - c := line[column] - // update width - if w := c.width + b.padding; w > width { - width = w - } - // update discardable - if c.width > 0 || c.htab { - discardable = false - } - } else { - break - } - } - // column block end - - // discard empty columns if necessary - if discardable && b.flags&DiscardEmptyColumns != 0 { - width = 0 - } - - // format and print all columns to the right of this column - // (we know the widths of this column and all columns to the left) - b.widths = append(b.widths, width) // push width - pos = b.format(pos, line0, this) - b.widths = b.widths[0 : len(b.widths)-1] // pop width - line0 = this - } - } - - // print unprinted lines until end - return b.writeLines(pos, line0, line1) -} - -// Append text to current cell. -func (b *Writer) append(text []byte) { - b.buf.Write(text) - b.cell.size += len(text) -} - -// Update the cell width. -func (b *Writer) updateWidth() { - // ---- Changes here ----- - newChars := b.buf.Bytes()[b.pos:b.buf.Len()] - cleaned := vtclean.Clean(string(newChars), false) // false to strip colors - b.cell.width += utf8.RuneCount([]byte(cleaned)) - // --- end of changes ---- - b.pos = b.buf.Len() -} - -// To escape a text segment, bracket it with Escape characters. -// For instance, the tab in this string "Ignore this tab: \xff\t\xff" -// does not terminate a cell and constitutes a single character of -// width one for formatting purposes. -// -// The value 0xff was chosen because it cannot appear in a valid UTF-8 sequence. -// -const Escape = '\xff' - -// Start escaped mode. -func (b *Writer) startEscape(ch byte) { - switch ch { - case Escape: - b.endChar = Escape - case '<': - b.endChar = '>' - case '&': - b.endChar = ';' - } -} - -// Terminate escaped mode. If the escaped text was an HTML tag, its width -// is assumed to be zero for formatting purposes; if it was an HTML entity, -// its width is assumed to be one. In all other cases, the width is the -// unicode width of the text. -// -func (b *Writer) endEscape() { - switch b.endChar { - case Escape: - b.updateWidth() - if b.flags&StripEscape == 0 { - b.cell.width -= 2 // don't count the Escape chars - } - case '>': // tag of zero width - case ';': - b.cell.width++ // entity, count as one rune - } - b.pos = b.buf.Len() - b.endChar = 0 -} - -// Terminate the current cell by adding it to the list of cells of the -// current line. Returns the number of cells in that line. -// -func (b *Writer) terminateCell(htab bool) int { - b.cell.htab = htab - line := &b.lines[len(b.lines)-1] - *line = append(*line, b.cell) - b.cell = cell{} - return len(*line) -} - -func handlePanic(err *error, op string) { - if e := recover(); e != nil { - if nerr, ok := e.(osError); ok { - *err = nerr.err - return - } - panic("tabwriter: panic during " + op) - } -} - -// Flush should be called after the last call to Write to ensure -// that any data buffered in the Writer is written to output. Any -// incomplete escape sequence at the end is considered -// complete for formatting purposes. -// -func (b *Writer) Flush() (err error) { - defer b.reset() // even in the presence of errors - defer handlePanic(&err, "Flush") - - // add current cell if not empty - if b.cell.size > 0 { - if b.endChar != 0 { - // inside escape - terminate it even if incomplete - b.endEscape() - } - b.terminateCell(false) - } - - // format contents of buffer - b.format(0, 0, len(b.lines)) - - return -} - -var hbar = []byte("---\n") - -// SetColumnAlignRight will mark a particular column as align right. -// This is reset on the next flush. -func (b *Writer) SetColumnAlignRight(column int) { - b.alignment[column] = AlignRight -} - -// Write writes buf to the writer b. -// The only errors returned are ones encountered -// while writing to the underlying output stream. -// -func (b *Writer) Write(buf []byte) (n int, err error) { - defer handlePanic(&err, "Write") - - // split text into cells - n = 0 - for i, ch := range buf { - if b.endChar == 0 { - // outside escape - switch ch { - case '\t', '\v', '\n', '\f': - // end of cell - b.append(buf[n:i]) - b.updateWidth() - n = i + 1 // ch consumed - ncells := b.terminateCell(ch == '\t') - if ch == '\n' || ch == '\f' { - // terminate line - b.addLine() - if ch == '\f' || ncells == 1 { - // A '\f' always forces a flush. Otherwise, if the previous - // line has only one cell which does not have an impact on - // the formatting of the following lines (the last cell per - // line is ignored by format()), thus we can flush the - // Writer contents. - if err = b.Flush(); err != nil { - return - } - if ch == '\f' && b.flags&Debug != 0 { - // indicate section break - b.write0(hbar) - } - } - } - - case Escape: - // start of escaped sequence - b.append(buf[n:i]) - b.updateWidth() - n = i - if b.flags&StripEscape != 0 { - n++ // strip Escape - } - b.startEscape(Escape) - - case '<', '&': - // possibly an html tag/entity - if b.flags&FilterHTML != 0 { - // begin of tag/entity - b.append(buf[n:i]) - b.updateWidth() - n = i - b.startEscape(ch) - } - } - - } else { - // inside escape - if ch == b.endChar { - // end of tag/entity - j := i + 1 - if ch == Escape && b.flags&StripEscape != 0 { - j = i // strip Escape - } - b.append(buf[n:j]) - n = i + 1 // ch consumed - b.endEscape() - } - } - } - - // append leftover text - b.append(buf[n:]) - n = len(buf) - return -} - -// NewWriter allocates and initializes a new tabwriter.Writer. -// The parameters are the same as for the Init function. -// -func NewWriter(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *Writer { - return new(Writer).Init(output, minwidth, tabwidth, padding, padchar, flags) -} diff --git a/vendor/github.com/juju/ansiterm/terminal.go b/vendor/github.com/juju/ansiterm/terminal.go deleted file mode 100644 index 96fd11c51..000000000 --- a/vendor/github.com/juju/ansiterm/terminal.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package ansiterm - -import ( - "io" - "os" - - "github.com/mattn/go-colorable" - "github.com/mattn/go-isatty" -) - -// colorEnabledWriter returns a writer that can handle the ansi color codes -// and true if the writer passed in is a terminal capable of color. If the -// TERM environment variable is set to "dumb", the terminal is not considered -// color capable. -func colorEnabledWriter(w io.Writer) (io.Writer, bool) { - f, ok := w.(*os.File) - if !ok { - return w, false - } - // Check the TERM environment variable specifically - // to check for "dumb" terminals. - if os.Getenv("TERM") == "dumb" { - return w, false - } - if !isatty.IsTerminal(f.Fd()) { - return w, false - } - return colorable.NewColorable(f), true -} diff --git a/vendor/github.com/juju/ansiterm/writer.go b/vendor/github.com/juju/ansiterm/writer.go deleted file mode 100644 index 32437bb27..000000000 --- a/vendor/github.com/juju/ansiterm/writer.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2016 Canonical Ltd. -// Licensed under the LGPLv3, see LICENCE file for details. - -package ansiterm - -import ( - "fmt" - "io" -) - -// Writer allows colors and styles to be specified. If the io.Writer -// is not a terminal capable of color, all attempts to set colors or -// styles are no-ops. -type Writer struct { - io.Writer - - noColor bool -} - -// NewWriter returns a Writer that allows the caller to specify colors and -// styles. If the io.Writer is not a terminal capable of color, all attempts -// to set colors or styles are no-ops. -func NewWriter(w io.Writer) *Writer { - writer, colorCapable := colorEnabledWriter(w) - return &Writer{ - Writer: writer, - noColor: !colorCapable, - } -} - -// SetColorCapable forces the writer to either write the ANSI escape color -// if capable is true, or to not write them if capable is false. -func (w *Writer) SetColorCapable(capable bool) { - w.noColor = !capable -} - -// SetForeground sets the foreground color. -func (w *Writer) SetForeground(c Color) { - w.writeSGR(c.foreground()) -} - -// SetBackground sets the background color. -func (w *Writer) SetBackground(c Color) { - w.writeSGR(c.background()) -} - -// SetStyle sets the text style. -func (w *Writer) SetStyle(s Style) { - w.writeSGR(s.enable()) -} - -// ClearStyle clears the text style. -func (w *Writer) ClearStyle(s Style) { - w.writeSGR(s.disable()) -} - -// Reset returns the default foreground and background colors with no styles. -func (w *Writer) Reset() { - w.writeSGR(reset) -} - -type sgr interface { - // sgr returns the combined escape sequence for the Select Graphic Rendition. - sgr() string -} - -// writeSGR takes the appropriate integer SGR parameters -// and writes out the ANIS escape code. -func (w *Writer) writeSGR(value sgr) { - if w.noColor { - return - } - fmt.Fprint(w, value.sgr()) -} diff --git a/vendor/github.com/lunixbochs/vtclean/.travis.yml b/vendor/github.com/lunixbochs/vtclean/.travis.yml deleted file mode 100644 index fc0a54325..000000000 --- a/vendor/github.com/lunixbochs/vtclean/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: go -sudo: false - -script: go test -v - -go: - - 1.5 - - 1.6 - - 1.7 diff --git a/vendor/github.com/lunixbochs/vtclean/LICENSE b/vendor/github.com/lunixbochs/vtclean/LICENSE deleted file mode 100644 index 42e82633f..000000000 --- a/vendor/github.com/lunixbochs/vtclean/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015 Ryan Hileman - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/lunixbochs/vtclean/README.md b/vendor/github.com/lunixbochs/vtclean/README.md deleted file mode 100644 index 99910a460..000000000 --- a/vendor/github.com/lunixbochs/vtclean/README.md +++ /dev/null @@ -1,46 +0,0 @@ -[![Build Status](https://travis-ci.org/lunixbochs/vtclean.svg?branch=master)](https://travis-ci.org/lunixbochs/vtclean) - -vtclean ----- - -Clean up raw terminal output by stripping escape sequences, optionally preserving color. - -Get it: `go get github.com/lunixbochs/vtclean/vtclean` - -API: - - import "github.com/lunixbochs/vtclean" - vtclean.Clean(line string, color bool) string - -Command line example: - - $ echo -e '\x1b[1;32mcolor example - color forced to stop at end of line - backspace is ba\b\bgood - no beeps!\x07\x07' | ./vtclean -color - - color example - color forced to stop at end of line - backspace is good - no beeps! - -Go example: - - package main - - import ( - "fmt" - "github.com/lunixbochs/vtclean" - ) - - func main() { - line := vtclean.Clean( - "\033[1;32mcolor, " + - "curs\033[Aor, " + - "backspace\b\b\b\b\b\b\b\b\b\b\b\033[K", false) - fmt.Println(line) - } - -Output: - - color, cursor diff --git a/vendor/github.com/lunixbochs/vtclean/io.go b/vendor/github.com/lunixbochs/vtclean/io.go deleted file mode 100644 index 31be0076a..000000000 --- a/vendor/github.com/lunixbochs/vtclean/io.go +++ /dev/null @@ -1,93 +0,0 @@ -package vtclean - -import ( - "bufio" - "bytes" - "io" -) - -type reader struct { - io.Reader - scanner *bufio.Scanner - buf []byte - - color bool -} - -func NewReader(r io.Reader, color bool) io.Reader { - return &reader{Reader: r, color: color} -} - -func (r *reader) scan() bool { - if r.scanner == nil { - r.scanner = bufio.NewScanner(r.Reader) - } - if len(r.buf) > 0 { - return true - } - if r.scanner.Scan() { - r.buf = []byte(Clean(r.scanner.Text(), r.color) + "\n") - return true - } - return false -} - -func (r *reader) fill(p []byte) int { - n := len(r.buf) - copy(p, r.buf) - if len(p) < len(r.buf) { - r.buf = r.buf[len(p):] - n = len(p) - } else { - r.buf = nil - } - return n -} - -func (r *reader) Read(p []byte) (int, error) { - n := r.fill(p) - if n < len(p) { - if !r.scan() { - if n == 0 { - return 0, io.EOF - } - return n, nil - } - n += r.fill(p[n:]) - } - return n, nil -} - -type writer struct { - io.Writer - buf []byte - color bool -} - -func NewWriter(w io.Writer, color bool) io.WriteCloser { - return &writer{Writer: w, color: color} -} - -func (w *writer) Write(p []byte) (int, error) { - buf := append(w.buf, p...) - lines := bytes.Split(buf, []byte("\n")) - if len(lines) > 0 { - last := len(lines) - 1 - w.buf = lines[last] - count := 0 - for _, line := range lines[:last] { - n, err := w.Writer.Write([]byte(Clean(string(line), w.color) + "\n")) - count += n - if err != nil { - return count, err - } - } - } - return len(p), nil -} - -func (w *writer) Close() error { - cl := Clean(string(w.buf), w.color) - _, err := w.Writer.Write([]byte(cl)) - return err -} diff --git a/vendor/github.com/lunixbochs/vtclean/line.go b/vendor/github.com/lunixbochs/vtclean/line.go deleted file mode 100644 index 66ee990be..000000000 --- a/vendor/github.com/lunixbochs/vtclean/line.go +++ /dev/null @@ -1,113 +0,0 @@ -package vtclean - -type char struct { - char byte - vt100 []byte -} - -func chars(p []byte) []char { - tmp := make([]char, len(p)) - for i, v := range p { - tmp[i].char = v - } - return tmp -} - -type lineEdit struct { - buf []char - pos, size int - vt100 []byte -} - -func newLineEdit(length int) *lineEdit { - return &lineEdit{buf: make([]char, length)} -} - -func (l *lineEdit) Vt100(p []byte) { - l.vt100 = p -} - -func (l *lineEdit) Move(x int) { - if x < 0 && l.pos <= -x { - l.pos = 0 - } else if x > 0 && l.pos+x > l.size { - l.pos = l.size - } else { - l.pos += x - } -} - -func (l *lineEdit) MoveAbs(x int) { - if x < l.size { - l.pos = x - } -} - -func (l *lineEdit) Write(p []byte) { - c := chars(p) - if len(c) > 0 { - c[0].vt100 = l.vt100 - l.vt100 = nil - } - if len(l.buf)-l.pos < len(c) { - l.buf = append(l.buf[:l.pos], c...) - } else { - copy(l.buf[l.pos:], c) - } - l.pos += len(c) - if l.pos > l.size { - l.size = l.pos - } -} - -func (l *lineEdit) Insert(p []byte) { - c := chars(p) - if len(c) > 0 { - c[0].vt100 = l.vt100 - l.vt100 = nil - } - l.size += len(c) - c = append(c, l.buf[l.pos:]...) - l.buf = append(l.buf[:l.pos], c...) -} - -func (l *lineEdit) Delete(n int) { - most := l.size - l.pos - if n > most { - n = most - } - copy(l.buf[l.pos:], l.buf[l.pos+n:]) - l.size -= n -} - -func (l *lineEdit) Clear() { - for i := 0; i < len(l.buf); i++ { - l.buf[i].char = ' ' - } -} -func (l *lineEdit) ClearLeft() { - for i := 0; i < l.pos+1; i++ { - l.buf[i].char = ' ' - } -} -func (l *lineEdit) ClearRight() { - l.size = l.pos -} - -func (l *lineEdit) Bytes() []byte { - length := 0 - buf := l.buf[:l.size] - for _, v := range buf { - length += 1 + len(v.vt100) - } - tmp := make([]byte, 0, length) - for _, v := range buf { - tmp = append(tmp, v.vt100...) - tmp = append(tmp, v.char) - } - return tmp -} - -func (l *lineEdit) String() string { - return string(l.Bytes()) -} diff --git a/vendor/github.com/lunixbochs/vtclean/vtclean.go b/vendor/github.com/lunixbochs/vtclean/vtclean.go deleted file mode 100644 index 64fe01fdb..000000000 --- a/vendor/github.com/lunixbochs/vtclean/vtclean.go +++ /dev/null @@ -1,95 +0,0 @@ -package vtclean - -import ( - "bytes" - "regexp" - "strconv" -) - -// regex based on ECMA-48: -// 1. optional: -// one of [ or ] -// any amount of 0x30-0x3f -// any amount of 0x20-0x2f -// 3. exactly one 0x40-0x7e -var vt100re = regexp.MustCompile(`^\033([\[\]]([0-9:;<=>\?]*)([!"#$%&'()*+,\-./]*))?([@A-Z\[\]^_\x60a-z{|}~])`) -var vt100exc = regexp.MustCompile(`^\033(\[[^a-zA-Z0-9@\?]+|[\(\)]).`) - -// this is to handle the RGB escape generated by `tput initc 1 500 500 500` -var vt100long = regexp.MustCompile(`^\033](\d+);([^\033]+)\033\\`) - -func Clean(line string, color bool) string { - var edit = newLineEdit(len(line)) - lineb := []byte(line) - - hadColor := false - for i := 0; i < len(lineb); { - c := lineb[i] - switch c { - case '\r': - edit.MoveAbs(0) - case '\b': - edit.Move(-1) - case '\033': - // set terminal title - if bytes.HasPrefix(lineb[i:], []byte("\x1b]0;")) { - pos := bytes.Index(lineb[i:], []byte("\a")) - if pos != -1 { - i += pos + 1 - continue - } - } - if m := vt100long.Find(lineb[i:]); m != nil { - i += len(m) - } else if m := vt100exc.Find(lineb[i:]); m != nil { - i += len(m) - } else if m := vt100re.FindSubmatch(lineb[i:]); m != nil { - i += len(m[0]) - num := string(m[2]) - n, err := strconv.Atoi(num) - if err != nil || n > 10000 { - n = 1 - } - switch m[4][0] { - case 'm': - if color { - hadColor = true - edit.Vt100(m[0]) - } - case '@': - edit.Insert(bytes.Repeat([]byte{' '}, n)) - case 'G': - edit.MoveAbs(n) - case 'C': - edit.Move(n) - case 'D': - edit.Move(-n) - case 'P': - edit.Delete(n) - case 'K': - switch num { - case "", "0": - edit.ClearRight() - case "1": - edit.ClearLeft() - case "2": - edit.Clear() - } - } - } else { - i += 1 - } - continue - default: - if c == '\n' || c == '\t' || c >= ' ' { - edit.Write([]byte{c}) - } - } - i += 1 - } - out := edit.Bytes() - if hadColor { - out = append(out, []byte("\033[0m")...) - } - return string(out) -} diff --git a/vendor/github.com/manifoldco/promptui/CHANGELOG.md b/vendor/github.com/manifoldco/promptui/CHANGELOG.md index 563e9d00a..ff30afdf0 100644 --- a/vendor/github.com/manifoldco/promptui/CHANGELOG.md +++ b/vendor/github.com/manifoldco/promptui/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +## [0.9.0] - 2021-10-30 + +### Fixed + +- Resolve license incompatibility in tabwriter + + ## [0.8.0] - 2020-09-28 ### Added diff --git a/vendor/github.com/manifoldco/promptui/go.mod b/vendor/github.com/manifoldco/promptui/go.mod index 760a44deb..a69023954 100644 --- a/vendor/github.com/manifoldco/promptui/go.mod +++ b/vendor/github.com/manifoldco/promptui/go.mod @@ -6,11 +6,5 @@ require ( github.com/chzyer/logex v1.1.10 // indirect github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect - github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a - github.com/kr/pretty v0.1.0 // indirect - github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a // indirect - github.com/mattn/go-colorable v0.0.9 // indirect - github.com/mattn/go-isatty v0.0.4 // indirect golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b // indirect - gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect ) diff --git a/vendor/github.com/manifoldco/promptui/go.sum b/vendor/github.com/manifoldco/promptui/go.sum index be5f99025..fcb24c854 100644 --- a/vendor/github.com/manifoldco/promptui/go.sum +++ b/vendor/github.com/manifoldco/promptui/go.sum @@ -4,20 +4,5 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5O github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU= -github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a h1:weJVJJRzAJBFRlAiJQROKQs8oC9vOxvm4rZmBBk0ONw= -github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= -github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b h1:MQE+LT/ABUuuvEZ+YQAMSXindAdUh7slEmAkup74op4= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/github.com/manifoldco/promptui/select.go b/vendor/github.com/manifoldco/promptui/select.go index 19b9e0c2e..b58ed9734 100644 --- a/vendor/github.com/manifoldco/promptui/select.go +++ b/vendor/github.com/manifoldco/promptui/select.go @@ -5,10 +5,10 @@ import ( "fmt" "io" "os" + "text/tabwriter" "text/template" "github.com/chzyer/readline" - "github.com/juju/ansiterm" "github.com/manifoldco/promptui/list" "github.com/manifoldco/promptui/screenbuf" ) @@ -587,7 +587,8 @@ func (s *Select) renderDetails(item interface{}) [][]byte { } var buf bytes.Buffer - w := ansiterm.NewTabWriter(&buf, 0, 0, 8, ' ', 0) + + w := tabwriter.NewWriter(&buf, 0, 0, 8, ' ', 0) err := s.Templates.details.Execute(w, item) if err != nil { diff --git a/vendor/github.com/mattn/go-colorable/.travis.yml b/vendor/github.com/mattn/go-colorable/.travis.yml deleted file mode 100644 index 7942c565c..000000000 --- a/vendor/github.com/mattn/go-colorable/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go -sudo: false -go: - - 1.13.x - - tip - -before_install: - - go get -t -v ./... - -script: - - ./go.test.sh - -after_success: - - bash <(curl -s https://codecov.io/bash) - diff --git a/vendor/github.com/mattn/go-colorable/LICENSE b/vendor/github.com/mattn/go-colorable/LICENSE deleted file mode 100644 index 91b5cef30..000000000 --- a/vendor/github.com/mattn/go-colorable/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Yasuhiro Matsumoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/mattn/go-colorable/README.md b/vendor/github.com/mattn/go-colorable/README.md deleted file mode 100644 index e055952b6..000000000 --- a/vendor/github.com/mattn/go-colorable/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# go-colorable - -[![Build Status](https://travis-ci.org/mattn/go-colorable.svg?branch=master)](https://travis-ci.org/mattn/go-colorable) -[![Codecov](https://codecov.io/gh/mattn/go-colorable/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-colorable) -[![GoDoc](https://godoc.org/github.com/mattn/go-colorable?status.svg)](http://godoc.org/github.com/mattn/go-colorable) -[![Go Report Card](https://goreportcard.com/badge/mattn/go-colorable)](https://goreportcard.com/report/mattn/go-colorable) - -Colorable writer for windows. - -For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.) -This package is possible to handle escape sequence for ansi color on windows. - -## Too Bad! - -![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png) - - -## So Good! - -![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png) - -## Usage - -```go -logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true}) -logrus.SetOutput(colorable.NewColorableStdout()) - -logrus.Info("succeeded") -logrus.Warn("not correct") -logrus.Error("something error") -logrus.Fatal("panic") -``` - -You can compile above code on non-windows OSs. - -## Installation - -``` -$ go get github.com/mattn/go-colorable -``` - -# License - -MIT - -# Author - -Yasuhiro Matsumoto (a.k.a mattn) diff --git a/vendor/github.com/mattn/go-colorable/colorable_appengine.go b/vendor/github.com/mattn/go-colorable/colorable_appengine.go deleted file mode 100644 index 1f7806fe1..000000000 --- a/vendor/github.com/mattn/go-colorable/colorable_appengine.go +++ /dev/null @@ -1,37 +0,0 @@ -// +build appengine - -package colorable - -import ( - "io" - "os" - - _ "github.com/mattn/go-isatty" -) - -// NewColorable returns new instance of Writer which handles escape sequence. -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - return file -} - -// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout. -func NewColorableStdout() io.Writer { - return os.Stdout -} - -// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr. -func NewColorableStderr() io.Writer { - return os.Stderr -} - -// EnableColorsStdout enable colors if possible. -func EnableColorsStdout(enabled *bool) func() { - if enabled != nil { - *enabled = true - } - return func() {} -} diff --git a/vendor/github.com/mattn/go-colorable/colorable_others.go b/vendor/github.com/mattn/go-colorable/colorable_others.go deleted file mode 100644 index 08cbd1e0f..000000000 --- a/vendor/github.com/mattn/go-colorable/colorable_others.go +++ /dev/null @@ -1,38 +0,0 @@ -// +build !windows -// +build !appengine - -package colorable - -import ( - "io" - "os" - - _ "github.com/mattn/go-isatty" -) - -// NewColorable returns new instance of Writer which handles escape sequence. -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - return file -} - -// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout. -func NewColorableStdout() io.Writer { - return os.Stdout -} - -// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr. -func NewColorableStderr() io.Writer { - return os.Stderr -} - -// EnableColorsStdout enable colors if possible. -func EnableColorsStdout(enabled *bool) func() { - if enabled != nil { - *enabled = true - } - return func() {} -} diff --git a/vendor/github.com/mattn/go-colorable/colorable_windows.go b/vendor/github.com/mattn/go-colorable/colorable_windows.go deleted file mode 100644 index 41215d7fc..000000000 --- a/vendor/github.com/mattn/go-colorable/colorable_windows.go +++ /dev/null @@ -1,1043 +0,0 @@ -// +build windows -// +build !appengine - -package colorable - -import ( - "bytes" - "io" - "math" - "os" - "strconv" - "strings" - "sync" - "syscall" - "unsafe" - - "github.com/mattn/go-isatty" -) - -const ( - foregroundBlue = 0x1 - foregroundGreen = 0x2 - foregroundRed = 0x4 - foregroundIntensity = 0x8 - foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity) - backgroundBlue = 0x10 - backgroundGreen = 0x20 - backgroundRed = 0x40 - backgroundIntensity = 0x80 - backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity) - commonLvbUnderscore = 0x8000 - - cENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4 -) - -const ( - genericRead = 0x80000000 - genericWrite = 0x40000000 -) - -const ( - consoleTextmodeBuffer = 0x1 -) - -type wchar uint16 -type short int16 -type dword uint32 -type word uint16 - -type coord struct { - x short - y short -} - -type smallRect struct { - left short - top short - right short - bottom short -} - -type consoleScreenBufferInfo struct { - size coord - cursorPosition coord - attributes word - window smallRect - maximumWindowSize coord -} - -type consoleCursorInfo struct { - size dword - visible int32 -} - -var ( - kernel32 = syscall.NewLazyDLL("kernel32.dll") - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") - procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") - procSetConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition") - procFillConsoleOutputCharacter = kernel32.NewProc("FillConsoleOutputCharacterW") - procFillConsoleOutputAttribute = kernel32.NewProc("FillConsoleOutputAttribute") - procGetConsoleCursorInfo = kernel32.NewProc("GetConsoleCursorInfo") - procSetConsoleCursorInfo = kernel32.NewProc("SetConsoleCursorInfo") - procSetConsoleTitle = kernel32.NewProc("SetConsoleTitleW") - procGetConsoleMode = kernel32.NewProc("GetConsoleMode") - procSetConsoleMode = kernel32.NewProc("SetConsoleMode") - procCreateConsoleScreenBuffer = kernel32.NewProc("CreateConsoleScreenBuffer") -) - -// Writer provides colorable Writer to the console -type Writer struct { - out io.Writer - handle syscall.Handle - althandle syscall.Handle - oldattr word - oldpos coord - rest bytes.Buffer - mutex sync.Mutex -} - -// NewColorable returns new instance of Writer which handles escape sequence from File. -func NewColorable(file *os.File) io.Writer { - if file == nil { - panic("nil passed instead of *os.File to NewColorable()") - } - - if isatty.IsTerminal(file.Fd()) { - var mode uint32 - if r, _, _ := procGetConsoleMode.Call(file.Fd(), uintptr(unsafe.Pointer(&mode))); r != 0 && mode&cENABLE_VIRTUAL_TERMINAL_PROCESSING != 0 { - return file - } - var csbi consoleScreenBufferInfo - handle := syscall.Handle(file.Fd()) - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - return &Writer{out: file, handle: handle, oldattr: csbi.attributes, oldpos: coord{0, 0}} - } - return file -} - -// NewColorableStdout returns new instance of Writer which handles escape sequence for stdout. -func NewColorableStdout() io.Writer { - return NewColorable(os.Stdout) -} - -// NewColorableStderr returns new instance of Writer which handles escape sequence for stderr. -func NewColorableStderr() io.Writer { - return NewColorable(os.Stderr) -} - -var color256 = map[int]int{ - 0: 0x000000, - 1: 0x800000, - 2: 0x008000, - 3: 0x808000, - 4: 0x000080, - 5: 0x800080, - 6: 0x008080, - 7: 0xc0c0c0, - 8: 0x808080, - 9: 0xff0000, - 10: 0x00ff00, - 11: 0xffff00, - 12: 0x0000ff, - 13: 0xff00ff, - 14: 0x00ffff, - 15: 0xffffff, - 16: 0x000000, - 17: 0x00005f, - 18: 0x000087, - 19: 0x0000af, - 20: 0x0000d7, - 21: 0x0000ff, - 22: 0x005f00, - 23: 0x005f5f, - 24: 0x005f87, - 25: 0x005faf, - 26: 0x005fd7, - 27: 0x005fff, - 28: 0x008700, - 29: 0x00875f, - 30: 0x008787, - 31: 0x0087af, - 32: 0x0087d7, - 33: 0x0087ff, - 34: 0x00af00, - 35: 0x00af5f, - 36: 0x00af87, - 37: 0x00afaf, - 38: 0x00afd7, - 39: 0x00afff, - 40: 0x00d700, - 41: 0x00d75f, - 42: 0x00d787, - 43: 0x00d7af, - 44: 0x00d7d7, - 45: 0x00d7ff, - 46: 0x00ff00, - 47: 0x00ff5f, - 48: 0x00ff87, - 49: 0x00ffaf, - 50: 0x00ffd7, - 51: 0x00ffff, - 52: 0x5f0000, - 53: 0x5f005f, - 54: 0x5f0087, - 55: 0x5f00af, - 56: 0x5f00d7, - 57: 0x5f00ff, - 58: 0x5f5f00, - 59: 0x5f5f5f, - 60: 0x5f5f87, - 61: 0x5f5faf, - 62: 0x5f5fd7, - 63: 0x5f5fff, - 64: 0x5f8700, - 65: 0x5f875f, - 66: 0x5f8787, - 67: 0x5f87af, - 68: 0x5f87d7, - 69: 0x5f87ff, - 70: 0x5faf00, - 71: 0x5faf5f, - 72: 0x5faf87, - 73: 0x5fafaf, - 74: 0x5fafd7, - 75: 0x5fafff, - 76: 0x5fd700, - 77: 0x5fd75f, - 78: 0x5fd787, - 79: 0x5fd7af, - 80: 0x5fd7d7, - 81: 0x5fd7ff, - 82: 0x5fff00, - 83: 0x5fff5f, - 84: 0x5fff87, - 85: 0x5fffaf, - 86: 0x5fffd7, - 87: 0x5fffff, - 88: 0x870000, - 89: 0x87005f, - 90: 0x870087, - 91: 0x8700af, - 92: 0x8700d7, - 93: 0x8700ff, - 94: 0x875f00, - 95: 0x875f5f, - 96: 0x875f87, - 97: 0x875faf, - 98: 0x875fd7, - 99: 0x875fff, - 100: 0x878700, - 101: 0x87875f, - 102: 0x878787, - 103: 0x8787af, - 104: 0x8787d7, - 105: 0x8787ff, - 106: 0x87af00, - 107: 0x87af5f, - 108: 0x87af87, - 109: 0x87afaf, - 110: 0x87afd7, - 111: 0x87afff, - 112: 0x87d700, - 113: 0x87d75f, - 114: 0x87d787, - 115: 0x87d7af, - 116: 0x87d7d7, - 117: 0x87d7ff, - 118: 0x87ff00, - 119: 0x87ff5f, - 120: 0x87ff87, - 121: 0x87ffaf, - 122: 0x87ffd7, - 123: 0x87ffff, - 124: 0xaf0000, - 125: 0xaf005f, - 126: 0xaf0087, - 127: 0xaf00af, - 128: 0xaf00d7, - 129: 0xaf00ff, - 130: 0xaf5f00, - 131: 0xaf5f5f, - 132: 0xaf5f87, - 133: 0xaf5faf, - 134: 0xaf5fd7, - 135: 0xaf5fff, - 136: 0xaf8700, - 137: 0xaf875f, - 138: 0xaf8787, - 139: 0xaf87af, - 140: 0xaf87d7, - 141: 0xaf87ff, - 142: 0xafaf00, - 143: 0xafaf5f, - 144: 0xafaf87, - 145: 0xafafaf, - 146: 0xafafd7, - 147: 0xafafff, - 148: 0xafd700, - 149: 0xafd75f, - 150: 0xafd787, - 151: 0xafd7af, - 152: 0xafd7d7, - 153: 0xafd7ff, - 154: 0xafff00, - 155: 0xafff5f, - 156: 0xafff87, - 157: 0xafffaf, - 158: 0xafffd7, - 159: 0xafffff, - 160: 0xd70000, - 161: 0xd7005f, - 162: 0xd70087, - 163: 0xd700af, - 164: 0xd700d7, - 165: 0xd700ff, - 166: 0xd75f00, - 167: 0xd75f5f, - 168: 0xd75f87, - 169: 0xd75faf, - 170: 0xd75fd7, - 171: 0xd75fff, - 172: 0xd78700, - 173: 0xd7875f, - 174: 0xd78787, - 175: 0xd787af, - 176: 0xd787d7, - 177: 0xd787ff, - 178: 0xd7af00, - 179: 0xd7af5f, - 180: 0xd7af87, - 181: 0xd7afaf, - 182: 0xd7afd7, - 183: 0xd7afff, - 184: 0xd7d700, - 185: 0xd7d75f, - 186: 0xd7d787, - 187: 0xd7d7af, - 188: 0xd7d7d7, - 189: 0xd7d7ff, - 190: 0xd7ff00, - 191: 0xd7ff5f, - 192: 0xd7ff87, - 193: 0xd7ffaf, - 194: 0xd7ffd7, - 195: 0xd7ffff, - 196: 0xff0000, - 197: 0xff005f, - 198: 0xff0087, - 199: 0xff00af, - 200: 0xff00d7, - 201: 0xff00ff, - 202: 0xff5f00, - 203: 0xff5f5f, - 204: 0xff5f87, - 205: 0xff5faf, - 206: 0xff5fd7, - 207: 0xff5fff, - 208: 0xff8700, - 209: 0xff875f, - 210: 0xff8787, - 211: 0xff87af, - 212: 0xff87d7, - 213: 0xff87ff, - 214: 0xffaf00, - 215: 0xffaf5f, - 216: 0xffaf87, - 217: 0xffafaf, - 218: 0xffafd7, - 219: 0xffafff, - 220: 0xffd700, - 221: 0xffd75f, - 222: 0xffd787, - 223: 0xffd7af, - 224: 0xffd7d7, - 225: 0xffd7ff, - 226: 0xffff00, - 227: 0xffff5f, - 228: 0xffff87, - 229: 0xffffaf, - 230: 0xffffd7, - 231: 0xffffff, - 232: 0x080808, - 233: 0x121212, - 234: 0x1c1c1c, - 235: 0x262626, - 236: 0x303030, - 237: 0x3a3a3a, - 238: 0x444444, - 239: 0x4e4e4e, - 240: 0x585858, - 241: 0x626262, - 242: 0x6c6c6c, - 243: 0x767676, - 244: 0x808080, - 245: 0x8a8a8a, - 246: 0x949494, - 247: 0x9e9e9e, - 248: 0xa8a8a8, - 249: 0xb2b2b2, - 250: 0xbcbcbc, - 251: 0xc6c6c6, - 252: 0xd0d0d0, - 253: 0xdadada, - 254: 0xe4e4e4, - 255: 0xeeeeee, -} - -// `\033]0;TITLESTR\007` -func doTitleSequence(er *bytes.Reader) error { - var c byte - var err error - - c, err = er.ReadByte() - if err != nil { - return err - } - if c != '0' && c != '2' { - return nil - } - c, err = er.ReadByte() - if err != nil { - return err - } - if c != ';' { - return nil - } - title := make([]byte, 0, 80) - for { - c, err = er.ReadByte() - if err != nil { - return err - } - if c == 0x07 || c == '\n' { - break - } - title = append(title, c) - } - if len(title) > 0 { - title8, err := syscall.UTF16PtrFromString(string(title)) - if err == nil { - procSetConsoleTitle.Call(uintptr(unsafe.Pointer(title8))) - } - } - return nil -} - -// returns Atoi(s) unless s == "" in which case it returns def -func atoiWithDefault(s string, def int) (int, error) { - if s == "" { - return def, nil - } - return strconv.Atoi(s) -} - -// Write writes data on console -func (w *Writer) Write(data []byte) (n int, err error) { - w.mutex.Lock() - defer w.mutex.Unlock() - var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - - handle := w.handle - - var er *bytes.Reader - if w.rest.Len() > 0 { - var rest bytes.Buffer - w.rest.WriteTo(&rest) - w.rest.Reset() - rest.Write(data) - er = bytes.NewReader(rest.Bytes()) - } else { - er = bytes.NewReader(data) - } - var bw [1]byte -loop: - for { - c1, err := er.ReadByte() - if err != nil { - break loop - } - if c1 != 0x1b { - bw[0] = c1 - w.out.Write(bw[:]) - continue - } - c2, err := er.ReadByte() - if err != nil { - break loop - } - - switch c2 { - case '>': - continue - case ']': - w.rest.WriteByte(c1) - w.rest.WriteByte(c2) - er.WriteTo(&w.rest) - if bytes.IndexByte(w.rest.Bytes(), 0x07) == -1 { - break loop - } - er = bytes.NewReader(w.rest.Bytes()[2:]) - err := doTitleSequence(er) - if err != nil { - break loop - } - w.rest.Reset() - continue - // https://github.com/mattn/go-colorable/issues/27 - case '7': - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - w.oldpos = csbi.cursorPosition - continue - case '8': - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos))) - continue - case 0x5b: - // execute part after switch - default: - continue - } - - w.rest.WriteByte(c1) - w.rest.WriteByte(c2) - er.WriteTo(&w.rest) - - var buf bytes.Buffer - var m byte - for i, c := range w.rest.Bytes()[2:] { - if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { - m = c - er = bytes.NewReader(w.rest.Bytes()[2+i+1:]) - w.rest.Reset() - break - } - buf.Write([]byte(string(c))) - } - if m == 0 { - break loop - } - - switch m { - case 'A': - n, err = atoiWithDefault(buf.String(), 1) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.y -= short(n) - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'B': - n, err = atoiWithDefault(buf.String(), 1) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.y += short(n) - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'C': - n, err = atoiWithDefault(buf.String(), 1) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x += short(n) - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'D': - n, err = atoiWithDefault(buf.String(), 1) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x -= short(n) - if csbi.cursorPosition.x < 0 { - csbi.cursorPosition.x = 0 - } - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'E': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = 0 - csbi.cursorPosition.y += short(n) - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'F': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = 0 - csbi.cursorPosition.y -= short(n) - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'G': - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - if n < 1 { - n = 1 - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - csbi.cursorPosition.x = short(n - 1) - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'H', 'f': - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - if buf.Len() > 0 { - token := strings.Split(buf.String(), ";") - switch len(token) { - case 1: - n1, err := strconv.Atoi(token[0]) - if err != nil { - continue - } - csbi.cursorPosition.y = short(n1 - 1) - case 2: - n1, err := strconv.Atoi(token[0]) - if err != nil { - continue - } - n2, err := strconv.Atoi(token[1]) - if err != nil { - continue - } - csbi.cursorPosition.x = short(n2 - 1) - csbi.cursorPosition.y = short(n1 - 1) - } - } else { - csbi.cursorPosition.y = 0 - } - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&csbi.cursorPosition))) - case 'J': - n := 0 - if buf.Len() > 0 { - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - } - var count, written dword - var cursor coord - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - switch n { - case 0: - cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} - count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x) - case 1: - cursor = coord{x: csbi.window.left, y: csbi.window.top} - count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.window.top-csbi.cursorPosition.y)*dword(csbi.size.x) - case 2: - cursor = coord{x: csbi.window.left, y: csbi.window.top} - count = dword(csbi.size.x) - dword(csbi.cursorPosition.x) + dword(csbi.size.y-csbi.cursorPosition.y)*dword(csbi.size.x) - } - procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - case 'K': - n := 0 - if buf.Len() > 0 { - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - var cursor coord - var count, written dword - switch n { - case 0: - cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} - count = dword(csbi.size.x - csbi.cursorPosition.x) - case 1: - cursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y} - count = dword(csbi.size.x - csbi.cursorPosition.x) - case 2: - cursor = coord{x: csbi.window.left, y: csbi.cursorPosition.y} - count = dword(csbi.size.x) - } - procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(count), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - case 'X': - n := 0 - if buf.Len() > 0 { - n, err = strconv.Atoi(buf.String()) - if err != nil { - continue - } - } - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - var cursor coord - var written dword - cursor = coord{x: csbi.cursorPosition.x, y: csbi.cursorPosition.y} - procFillConsoleOutputCharacter.Call(uintptr(handle), uintptr(' '), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - procFillConsoleOutputAttribute.Call(uintptr(handle), uintptr(csbi.attributes), uintptr(n), *(*uintptr)(unsafe.Pointer(&cursor)), uintptr(unsafe.Pointer(&written))) - case 'm': - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - attr := csbi.attributes - cs := buf.String() - if cs == "" { - procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(w.oldattr)) - continue - } - token := strings.Split(cs, ";") - for i := 0; i < len(token); i++ { - ns := token[i] - if n, err = strconv.Atoi(ns); err == nil { - switch { - case n == 0 || n == 100: - attr = w.oldattr - case n == 4: - attr |= commonLvbUnderscore - case (1 <= n && n <= 3) || n == 5: - attr |= foregroundIntensity - case n == 7 || n == 27: - attr = - (attr &^ (foregroundMask | backgroundMask)) | - ((attr & foregroundMask) << 4) | - ((attr & backgroundMask) >> 4) - case n == 22: - attr &^= foregroundIntensity - case n == 24: - attr &^= commonLvbUnderscore - case 30 <= n && n <= 37: - attr &= backgroundMask - if (n-30)&1 != 0 { - attr |= foregroundRed - } - if (n-30)&2 != 0 { - attr |= foregroundGreen - } - if (n-30)&4 != 0 { - attr |= foregroundBlue - } - case n == 38: // set foreground color. - if i < len(token)-2 && (token[i+1] == "5" || token[i+1] == "05") { - if n256, err := strconv.Atoi(token[i+2]); err == nil { - if n256foreAttr == nil { - n256setup() - } - attr &= backgroundMask - attr |= n256foreAttr[n256%len(n256foreAttr)] - i += 2 - } - } else if len(token) == 5 && token[i+1] == "2" { - var r, g, b int - r, _ = strconv.Atoi(token[i+2]) - g, _ = strconv.Atoi(token[i+3]) - b, _ = strconv.Atoi(token[i+4]) - i += 4 - if r > 127 { - attr |= foregroundRed - } - if g > 127 { - attr |= foregroundGreen - } - if b > 127 { - attr |= foregroundBlue - } - } else { - attr = attr & (w.oldattr & backgroundMask) - } - case n == 39: // reset foreground color. - attr &= backgroundMask - attr |= w.oldattr & foregroundMask - case 40 <= n && n <= 47: - attr &= foregroundMask - if (n-40)&1 != 0 { - attr |= backgroundRed - } - if (n-40)&2 != 0 { - attr |= backgroundGreen - } - if (n-40)&4 != 0 { - attr |= backgroundBlue - } - case n == 48: // set background color. - if i < len(token)-2 && token[i+1] == "5" { - if n256, err := strconv.Atoi(token[i+2]); err == nil { - if n256backAttr == nil { - n256setup() - } - attr &= foregroundMask - attr |= n256backAttr[n256%len(n256backAttr)] - i += 2 - } - } else if len(token) == 5 && token[i+1] == "2" { - var r, g, b int - r, _ = strconv.Atoi(token[i+2]) - g, _ = strconv.Atoi(token[i+3]) - b, _ = strconv.Atoi(token[i+4]) - i += 4 - if r > 127 { - attr |= backgroundRed - } - if g > 127 { - attr |= backgroundGreen - } - if b > 127 { - attr |= backgroundBlue - } - } else { - attr = attr & (w.oldattr & foregroundMask) - } - case n == 49: // reset foreground color. - attr &= foregroundMask - attr |= w.oldattr & backgroundMask - case 90 <= n && n <= 97: - attr = (attr & backgroundMask) - attr |= foregroundIntensity - if (n-90)&1 != 0 { - attr |= foregroundRed - } - if (n-90)&2 != 0 { - attr |= foregroundGreen - } - if (n-90)&4 != 0 { - attr |= foregroundBlue - } - case 100 <= n && n <= 107: - attr = (attr & foregroundMask) - attr |= backgroundIntensity - if (n-100)&1 != 0 { - attr |= backgroundRed - } - if (n-100)&2 != 0 { - attr |= backgroundGreen - } - if (n-100)&4 != 0 { - attr |= backgroundBlue - } - } - procSetConsoleTextAttribute.Call(uintptr(handle), uintptr(attr)) - } - } - case 'h': - var ci consoleCursorInfo - cs := buf.String() - if cs == "5>" { - procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 0 - procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - } else if cs == "?25" { - procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 1 - procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - } else if cs == "?1049" { - if w.althandle == 0 { - h, _, _ := procCreateConsoleScreenBuffer.Call(uintptr(genericRead|genericWrite), 0, 0, uintptr(consoleTextmodeBuffer), 0, 0) - w.althandle = syscall.Handle(h) - if w.althandle != 0 { - handle = w.althandle - } - } - } - case 'l': - var ci consoleCursorInfo - cs := buf.String() - if cs == "5>" { - procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 1 - procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - } else if cs == "?25" { - procGetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - ci.visible = 0 - procSetConsoleCursorInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&ci))) - } else if cs == "?1049" { - if w.althandle != 0 { - syscall.CloseHandle(w.althandle) - w.althandle = 0 - handle = w.handle - } - } - case 's': - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - w.oldpos = csbi.cursorPosition - case 'u': - procSetConsoleCursorPosition.Call(uintptr(handle), *(*uintptr)(unsafe.Pointer(&w.oldpos))) - } - } - - return len(data), nil -} - -type consoleColor struct { - rgb int - red bool - green bool - blue bool - intensity bool -} - -func (c consoleColor) foregroundAttr() (attr word) { - if c.red { - attr |= foregroundRed - } - if c.green { - attr |= foregroundGreen - } - if c.blue { - attr |= foregroundBlue - } - if c.intensity { - attr |= foregroundIntensity - } - return -} - -func (c consoleColor) backgroundAttr() (attr word) { - if c.red { - attr |= backgroundRed - } - if c.green { - attr |= backgroundGreen - } - if c.blue { - attr |= backgroundBlue - } - if c.intensity { - attr |= backgroundIntensity - } - return -} - -var color16 = []consoleColor{ - {0x000000, false, false, false, false}, - {0x000080, false, false, true, false}, - {0x008000, false, true, false, false}, - {0x008080, false, true, true, false}, - {0x800000, true, false, false, false}, - {0x800080, true, false, true, false}, - {0x808000, true, true, false, false}, - {0xc0c0c0, true, true, true, false}, - {0x808080, false, false, false, true}, - {0x0000ff, false, false, true, true}, - {0x00ff00, false, true, false, true}, - {0x00ffff, false, true, true, true}, - {0xff0000, true, false, false, true}, - {0xff00ff, true, false, true, true}, - {0xffff00, true, true, false, true}, - {0xffffff, true, true, true, true}, -} - -type hsv struct { - h, s, v float32 -} - -func (a hsv) dist(b hsv) float32 { - dh := a.h - b.h - switch { - case dh > 0.5: - dh = 1 - dh - case dh < -0.5: - dh = -1 - dh - } - ds := a.s - b.s - dv := a.v - b.v - return float32(math.Sqrt(float64(dh*dh + ds*ds + dv*dv))) -} - -func toHSV(rgb int) hsv { - r, g, b := float32((rgb&0xFF0000)>>16)/256.0, - float32((rgb&0x00FF00)>>8)/256.0, - float32(rgb&0x0000FF)/256.0 - min, max := minmax3f(r, g, b) - h := max - min - if h > 0 { - if max == r { - h = (g - b) / h - if h < 0 { - h += 6 - } - } else if max == g { - h = 2 + (b-r)/h - } else { - h = 4 + (r-g)/h - } - } - h /= 6.0 - s := max - min - if max != 0 { - s /= max - } - v := max - return hsv{h: h, s: s, v: v} -} - -type hsvTable []hsv - -func toHSVTable(rgbTable []consoleColor) hsvTable { - t := make(hsvTable, len(rgbTable)) - for i, c := range rgbTable { - t[i] = toHSV(c.rgb) - } - return t -} - -func (t hsvTable) find(rgb int) consoleColor { - hsv := toHSV(rgb) - n := 7 - l := float32(5.0) - for i, p := range t { - d := hsv.dist(p) - if d < l { - l, n = d, i - } - } - return color16[n] -} - -func minmax3f(a, b, c float32) (min, max float32) { - if a < b { - if b < c { - return a, c - } else if a < c { - return a, b - } else { - return c, b - } - } else { - if a < c { - return b, c - } else if b < c { - return b, a - } else { - return c, a - } - } -} - -var n256foreAttr []word -var n256backAttr []word - -func n256setup() { - n256foreAttr = make([]word, 256) - n256backAttr = make([]word, 256) - t := toHSVTable(color16) - for i, rgb := range color256 { - c := t.find(rgb) - n256foreAttr[i] = c.foregroundAttr() - n256backAttr[i] = c.backgroundAttr() - } -} - -// EnableColorsStdout enable colors if possible. -func EnableColorsStdout(enabled *bool) func() { - var mode uint32 - h := os.Stdout.Fd() - if r, _, _ := procGetConsoleMode.Call(h, uintptr(unsafe.Pointer(&mode))); r != 0 { - if r, _, _ = procSetConsoleMode.Call(h, uintptr(mode|cENABLE_VIRTUAL_TERMINAL_PROCESSING)); r != 0 { - if enabled != nil { - *enabled = true - } - return func() { - procSetConsoleMode.Call(h, uintptr(mode)) - } - } - } - if enabled != nil { - *enabled = true - } - return func() {} -} diff --git a/vendor/github.com/mattn/go-colorable/go.mod b/vendor/github.com/mattn/go-colorable/go.mod deleted file mode 100644 index 1e590b819..000000000 --- a/vendor/github.com/mattn/go-colorable/go.mod +++ /dev/null @@ -1,8 +0,0 @@ -module github.com/mattn/go-colorable - -require ( - github.com/mattn/go-isatty v0.0.12 - golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae // indirect -) - -go 1.13 diff --git a/vendor/github.com/mattn/go-colorable/go.sum b/vendor/github.com/mattn/go-colorable/go.sum deleted file mode 100644 index cf5b95d97..000000000 --- a/vendor/github.com/mattn/go-colorable/go.sum +++ /dev/null @@ -1,5 +0,0 @@ -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/vendor/github.com/mattn/go-colorable/go.test.sh b/vendor/github.com/mattn/go-colorable/go.test.sh deleted file mode 100644 index 012162b07..000000000 --- a/vendor/github.com/mattn/go-colorable/go.test.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -e -echo "" > coverage.txt - -for d in $(go list ./... | grep -v vendor); do - go test -race -coverprofile=profile.out -covermode=atomic "$d" - if [ -f profile.out ]; then - cat profile.out >> coverage.txt - rm profile.out - fi -done diff --git a/vendor/github.com/mattn/go-colorable/noncolorable.go b/vendor/github.com/mattn/go-colorable/noncolorable.go deleted file mode 100644 index 95f2c6be2..000000000 --- a/vendor/github.com/mattn/go-colorable/noncolorable.go +++ /dev/null @@ -1,55 +0,0 @@ -package colorable - -import ( - "bytes" - "io" -) - -// NonColorable holds writer but removes escape sequence. -type NonColorable struct { - out io.Writer -} - -// NewNonColorable returns new instance of Writer which removes escape sequence from Writer. -func NewNonColorable(w io.Writer) io.Writer { - return &NonColorable{out: w} -} - -// Write writes data on console -func (w *NonColorable) Write(data []byte) (n int, err error) { - er := bytes.NewReader(data) - var bw [1]byte -loop: - for { - c1, err := er.ReadByte() - if err != nil { - break loop - } - if c1 != 0x1b { - bw[0] = c1 - w.out.Write(bw[:]) - continue - } - c2, err := er.ReadByte() - if err != nil { - break loop - } - if c2 != 0x5b { - continue - } - - var buf bytes.Buffer - for { - c, err := er.ReadByte() - if err != nil { - break loop - } - if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { - break - } - buf.Write([]byte(string(c))) - } - } - - return len(data), nil -} diff --git a/vendor/github.com/moby/sys/mountinfo/go.mod b/vendor/github.com/moby/sys/mountinfo/go.mod index 9749ea96d..1cc3efcf7 100644 --- a/vendor/github.com/moby/sys/mountinfo/go.mod +++ b/vendor/github.com/moby/sys/mountinfo/go.mod @@ -1,5 +1,5 @@ module github.com/moby/sys/mountinfo -go 1.14 +go 1.16 -require golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 +require golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 diff --git a/vendor/github.com/moby/sys/mountinfo/go.sum b/vendor/github.com/moby/sys/mountinfo/go.sum index 2a5be7ea8..c257a6a29 100644 --- a/vendor/github.com/moby/sys/mountinfo/go.sum +++ b/vendor/github.com/moby/sys/mountinfo/go.sum @@ -1,2 +1,2 @@ -golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM= -golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359 h1:2B5p2L5IfGiD7+b9BOoRMC6DgObAVZV+Fsp050NqXik= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/vendor/github.com/moby/sys/mountinfo/mounted_linux.go b/vendor/github.com/moby/sys/mountinfo/mounted_linux.go index bc9f6b2ad..5c9e3e30e 100644 --- a/vendor/github.com/moby/sys/mountinfo/mounted_linux.go +++ b/vendor/github.com/moby/sys/mountinfo/mounted_linux.go @@ -16,9 +16,6 @@ func mountedByOpenat2(path string) (bool, error) { Flags: unix.O_PATH | unix.O_CLOEXEC, }) if err != nil { - if err == unix.ENOENT { // not a mount - return false, nil - } return false, &os.PathError{Op: "openat2", Path: dir, Err: err} } fd, err := unix.Openat2(dirfd, last, &unix.OpenHow{ @@ -26,20 +23,22 @@ func mountedByOpenat2(path string) (bool, error) { Resolve: unix.RESOLVE_NO_XDEV, }) _ = unix.Close(dirfd) - switch err { + switch err { //nolint:errorlint // unix errors are bare case nil: // definitely not a mount _ = unix.Close(fd) return false, nil case unix.EXDEV: // definitely a mount return true, nil - case unix.ENOENT: // not a mount - return false, nil } // not sure return false, &os.PathError{Op: "openat2", Path: path, Err: err} } func mounted(path string) (bool, error) { + path, err := normalizePath(path) + if err != nil { + return false, err + } // Try a fast path, using openat2() with RESOLVE_NO_XDEV. mounted, err := mountedByOpenat2(path) if err == nil { diff --git a/vendor/github.com/moby/sys/mountinfo/mounted_unix.go b/vendor/github.com/moby/sys/mountinfo/mounted_unix.go index efb03978b..45ddad236 100644 --- a/vendor/github.com/moby/sys/mountinfo/mounted_unix.go +++ b/vendor/github.com/moby/sys/mountinfo/mounted_unix.go @@ -1,9 +1,9 @@ -// +build linux freebsd,cgo openbsd,cgo +//go:build linux || (freebsd && cgo) || (openbsd && cgo) || (darwin && cgo) +// +build linux freebsd,cgo openbsd,cgo darwin,cgo package mountinfo import ( - "errors" "fmt" "os" "path/filepath" @@ -15,10 +15,6 @@ func mountedByStat(path string) (bool, error) { var st unix.Stat_t if err := unix.Lstat(path, &st); err != nil { - if err == unix.ENOENT { - // Treat ENOENT as "not mounted". - return false, nil - } return false, &os.PathError{Op: "stat", Path: path, Err: err} } dev := st.Dev @@ -49,14 +45,6 @@ func normalizePath(path string) (realPath string, err error) { } func mountedByMountinfo(path string) (bool, error) { - path, err := normalizePath(path) - if err != nil { - if errors.Is(err, unix.ENOENT) { - // treat ENOENT as "not mounted" - return false, nil - } - return false, err - } entries, err := GetMounts(SingleEntryFilter(path)) if err != nil { return false, err diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo.go b/vendor/github.com/moby/sys/mountinfo/mountinfo.go index 403a89331..9867a66dd 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo.go @@ -10,11 +10,12 @@ func GetMounts(f FilterFunc) ([]*Info, error) { return parseMountTable(f) } -// Mounted determines if a specified path is a mount point. +// Mounted determines if a specified path is a mount point. In case of any +// error, false (and an error) is returned. // -// The argument must be an absolute path, with all symlinks resolved, and clean. -// One way to ensure it is to process the path using filepath.Abs followed by -// filepath.EvalSymlinks before calling this function. +// The non-existent path returns an error. If a caller is not interested +// in this particular error, it should handle it separately using e.g. +// errors.Is(err, os.ErrNotExist). func Mounted(path string) (bool, error) { // root is always mounted if path == string(os.PathSeparator) { diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_bsd.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_bsd.go index b1c12d02b..d5513a26d 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo_bsd.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_bsd.go @@ -1,4 +1,5 @@ -// +build freebsd,cgo openbsd,cgo +//go:build (freebsd && cgo) || (openbsd && cgo) || (darwin && cgo) +// +build freebsd,cgo openbsd,cgo darwin,cgo package mountinfo @@ -21,7 +22,7 @@ func parseMountTable(filter FilterFunc) ([]*Info, error) { count := int(C.getmntinfo(&rawEntries, C.MNT_WAIT)) if count == 0 { - return nil, fmt.Errorf("Failed to call getmntinfo") + return nil, fmt.Errorf("failed to call getmntinfo") } var entries []C.struct_statfs @@ -55,6 +56,10 @@ func parseMountTable(filter FilterFunc) ([]*Info, error) { } func mounted(path string) (bool, error) { + path, err := normalizePath(path) + if err != nil { + return false, err + } // Fast path: compare st.st_dev fields. // This should always work for FreeBSD and OpenBSD. mounted, err := mountedByStat(path) diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go index f09a70fa0..59332b07b 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_linux.go @@ -52,7 +52,7 @@ func GetMountsFromReader(r io.Reader, filter FilterFunc) ([]*Info, error) { numFields := len(fields) if numFields < 10 { // should be at least 10 fields - return nil, fmt.Errorf("Parsing '%s' failed: not enough fields (%d)", text, numFields) + return nil, fmt.Errorf("parsing '%s' failed: not enough fields (%d)", text, numFields) } // separator field @@ -67,7 +67,7 @@ func GetMountsFromReader(r io.Reader, filter FilterFunc) ([]*Info, error) { for fields[sepIdx] != "-" { sepIdx-- if sepIdx == 5 { - return nil, fmt.Errorf("Parsing '%s' failed: missing - separator", text) + return nil, fmt.Errorf("parsing '%s' failed: missing - separator", text) } } @@ -75,46 +75,39 @@ func GetMountsFromReader(r io.Reader, filter FilterFunc) ([]*Info, error) { p.Mountpoint, err = unescape(fields[4]) if err != nil { - return nil, fmt.Errorf("Parsing '%s' failed: mount point: %w", fields[4], err) + return nil, fmt.Errorf("parsing '%s' failed: mount point: %w", fields[4], err) } p.FSType, err = unescape(fields[sepIdx+1]) if err != nil { - return nil, fmt.Errorf("Parsing '%s' failed: fstype: %w", fields[sepIdx+1], err) + return nil, fmt.Errorf("parsing '%s' failed: fstype: %w", fields[sepIdx+1], err) } p.Source, err = unescape(fields[sepIdx+2]) if err != nil { - return nil, fmt.Errorf("Parsing '%s' failed: source: %w", fields[sepIdx+2], err) + return nil, fmt.Errorf("parsing '%s' failed: source: %w", fields[sepIdx+2], err) } p.VFSOptions = fields[sepIdx+3] // ignore any numbers parsing errors, as there should not be any p.ID, _ = strconv.Atoi(fields[0]) p.Parent, _ = strconv.Atoi(fields[1]) - mm := strings.Split(fields[2], ":") + mm := strings.SplitN(fields[2], ":", 3) if len(mm) != 2 { - return nil, fmt.Errorf("Parsing '%s' failed: unexpected minor:major pair %s", text, mm) + return nil, fmt.Errorf("parsing '%s' failed: unexpected major:minor pair %s", text, mm) } p.Major, _ = strconv.Atoi(mm[0]) p.Minor, _ = strconv.Atoi(mm[1]) p.Root, err = unescape(fields[3]) if err != nil { - return nil, fmt.Errorf("Parsing '%s' failed: root: %w", fields[3], err) + return nil, fmt.Errorf("parsing '%s' failed: root: %w", fields[3], err) } p.Options = fields[5] // zero or more optional fields - switch { - case sepIdx == 6: - // zero, do nothing - case sepIdx == 7: - p.Optional = fields[6] - default: - p.Optional = strings.Join(fields[6:sepIdx-1], " ") - } + p.Optional = strings.Join(fields[6:sepIdx], " ") - // Run the filter after parsing all of the fields. + // Run the filter after parsing all fields. var skip, stop bool if filter != nil { skip, stop = filter(p) diff --git a/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go b/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go index d33ebca09..95769a76d 100644 --- a/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go +++ b/vendor/github.com/moby/sys/mountinfo/mountinfo_unsupported.go @@ -1,4 +1,5 @@ -// +build !windows,!linux,!freebsd,!openbsd freebsd,!cgo openbsd,!cgo +//go:build (!windows && !linux && !freebsd && !openbsd && !darwin) || (freebsd && !cgo) || (openbsd && !cgo) || (darwin && !cgo) +// +build !windows,!linux,!freebsd,!openbsd,!darwin freebsd,!cgo openbsd,!cgo darwin,!cgo package mountinfo diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go index cad467507..5a59d151f 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go @@ -61,16 +61,30 @@ func ClassIndex(class string) (int, error) { return classIndex(class) } -// SetFileLabel sets the SELinux label for this path or returns an error. +// SetFileLabel sets the SELinux label for this path, following symlinks, +// or returns an error. func SetFileLabel(fpath string, label string) error { return setFileLabel(fpath, label) } -// FileLabel returns the SELinux label for this path or returns an error. +// LsetFileLabel sets the SELinux label for this path, not following symlinks, +// or returns an error. +func LsetFileLabel(fpath string, label string) error { + return lSetFileLabel(fpath, label) +} + +// FileLabel returns the SELinux label for this path, following symlinks, +// or returns an error. func FileLabel(fpath string) (string, error) { return fileLabel(fpath) } +// LfileLabel returns the SELinux label for this path, not following symlinks, +// or returns an error. +func LfileLabel(fpath string) (string, error) { + return lFileLabel(fpath) +} + // SetFSCreateLabel tells the kernel what label to use for all file system objects // created by this task. // Set the label to an empty string to return to the default label. Calls to SetFSCreateLabel diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go index b045843ad..ee602ab96 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go @@ -316,8 +316,9 @@ func classIndex(class string) (int, error) { return index, nil } -// setFileLabel sets the SELinux label for this path or returns an error. -func setFileLabel(fpath string, label string) error { +// lSetFileLabel sets the SELinux label for this path, not following symlinks, +// or returns an error. +func lSetFileLabel(fpath string, label string) error { if fpath == "" { return ErrEmptyPath } @@ -334,12 +335,50 @@ func setFileLabel(fpath string, label string) error { return nil } -// fileLabel returns the SELinux label for this path or returns an error. +// setFileLabel sets the SELinux label for this path, following symlinks, +// or returns an error. +func setFileLabel(fpath string, label string) error { + if fpath == "" { + return ErrEmptyPath + } + for { + err := unix.Setxattr(fpath, xattrNameSelinux, []byte(label), 0) + if err == nil { + break + } + if err != unix.EINTR { //nolint:errorlint // unix errors are bare + return &os.PathError{Op: "setxattr", Path: fpath, Err: err} + } + } + + return nil +} + +// fileLabel returns the SELinux label for this path, following symlinks, +// or returns an error. func fileLabel(fpath string) (string, error) { if fpath == "" { return "", ErrEmptyPath } + label, err := getxattr(fpath, xattrNameSelinux) + if err != nil { + return "", &os.PathError{Op: "getxattr", Path: fpath, Err: err} + } + // Trim the NUL byte at the end of the byte buffer, if present. + if len(label) > 0 && label[len(label)-1] == '\x00' { + label = label[:len(label)-1] + } + return string(label), nil +} + +// lFileLabel returns the SELinux label for this path, not following symlinks, +// or returns an error. +func lFileLabel(fpath string) (string, error) { + if fpath == "" { + return "", ErrEmptyPath + } + label, err := lgetxattr(fpath, xattrNameSelinux) if err != nil { return "", &os.PathError{Op: "lgetxattr", Path: fpath, Err: err} diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go index 42657759c..78743b020 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go @@ -17,10 +17,18 @@ func setFileLabel(fpath string, label string) error { return nil } +func lSetFileLabel(fpath string, label string) error { + return nil +} + func fileLabel(fpath string) (string, error) { return "", nil } +func lFileLabel(fpath string) (string, error) { + return "", nil +} + func setFSCreateLabel(label string) error { return nil } diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/xattrs_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/xattrs_linux.go index c6b0a7f26..9e473ca16 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/xattrs_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/xattrs_linux.go @@ -36,3 +36,36 @@ func doLgetxattr(path, attr string, dest []byte) (int, error) { } } } + +// getxattr returns a []byte slice containing the value of +// an extended attribute attr set for path. +func getxattr(path, attr string) ([]byte, error) { + // Start with a 128 length byte array + dest := make([]byte, 128) + sz, errno := dogetxattr(path, attr, dest) + for errno == unix.ERANGE { //nolint:errorlint // unix errors are bare + // Buffer too small, use zero-sized buffer to get the actual size + sz, errno = dogetxattr(path, attr, []byte{}) + if errno != nil { + return nil, errno + } + + dest = make([]byte, sz) + sz, errno = dogetxattr(path, attr, dest) + } + if errno != nil { + return nil, errno + } + + return dest[:sz], nil +} + +// dogetxattr is a wrapper that retries on EINTR +func dogetxattr(path, attr string, dest []byte) (int, error) { + for { + sz, err := unix.Getxattr(path, attr, dest) + if err != unix.EINTR { //nolint:errorlint // unix errors are bare + return sz, err + } + } +} diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/msgutil/msgutil.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/msgutil/msgutil.go index a0a0c94c6..74caa9a49 100644 --- a/vendor/github.com/rootless-containers/rootlesskit/pkg/msgutil/msgutil.go +++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/msgutil/msgutil.go @@ -5,9 +5,8 @@ import ( "bytes" "encoding/binary" "encoding/json" + "fmt" "io" - - "github.com/pkg/errors" ) const ( @@ -20,7 +19,7 @@ func MarshalToWriter(w io.Writer, x interface{}) (int, error) { return 0, err } if len(b) > maxLength { - return 0, errors.Errorf("bad message length: %d (max: %d)", len(b), maxLength) + return 0, fmt.Errorf("bad message length: %d (max: %d)", len(b), maxLength) } h := make([]byte, 4) binary.LittleEndian.PutUint32(h, uint32(len(b))) @@ -34,11 +33,11 @@ func UnmarshalFromReader(r io.Reader, x interface{}) (int, error) { return n, err } if n != 4 { - return n, errors.Errorf("read %d bytes, expected 4 bytes", n) + return n, fmt.Errorf("read %d bytes, expected 4 bytes", n) } bLen := binary.LittleEndian.Uint32(hdr) if bLen > maxLength || bLen < 1 { - return n, errors.Errorf("bad message length: %d (max: %d)", bLen, maxLength) + return n, fmt.Errorf("bad message length: %d (max: %d)", bLen, maxLength) } b := make([]byte, bLen) n, err = r.Read(b) @@ -46,7 +45,7 @@ func UnmarshalFromReader(r io.Reader, x interface{}) (int, error) { return 4 + n, err } if n != int(bLen) { - return 4 + n, errors.Errorf("read %d bytes, expected %d bytes", n, bLen) + return 4 + n, fmt.Errorf("read %d bytes, expected %d bytes", n, bLen) } return 4 + n, json.Unmarshal(b, x) } @@ -60,7 +59,7 @@ func Marshal(x interface{}) ([]byte, error) { func Unmarshal(b []byte, x interface{}) error { n, err := UnmarshalFromReader(bytes.NewReader(b), x) if n != len(b) { - return errors.Errorf("read %d bytes, expected %d bytes", n, len(b)) + return fmt.Errorf("read %d bytes, expected %d bytes", n, len(b)) } return err } diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/child/child.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/child/child.go index 05dc0303c..5d1f33f08 100644 --- a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/child/child.go +++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/child/child.go @@ -1,13 +1,14 @@ package child import ( + "errors" + "fmt" "io" "net" "os" "strconv" "strings" - "github.com/pkg/errors" "golang.org/x/sys/unix" "github.com/rootless-containers/rootlesskit/pkg/msgutil" @@ -76,7 +77,6 @@ func (d *childDriver) RunChildDriver(opaque map[string]string, quit <-chan struc c.Close() }() } - return nil } func (d *childDriver) routine(c *net.UnixConn) error { @@ -90,7 +90,7 @@ func (d *childDriver) routine(c *net.UnixConn) error { case msg.RequestTypeConnect: return d.handleConnectRequest(c, &req) default: - return errors.Errorf("unknown request type %q", req.Type) + return fmt.Errorf("unknown request type %q", req.Type) } } @@ -108,7 +108,7 @@ func (d *childDriver) handleConnectRequest(c *net.UnixConn, req *msg.Request) er case "udp4": case "udp6": default: - return errors.Errorf("unknown proto: %q", req.Proto) + return fmt.Errorf("unknown proto: %q", req.Proto) } // dialProto does not need "4", "6" suffix dialProto := strings.TrimSuffix(strings.TrimSuffix(req.Proto, "6"), "4") @@ -119,7 +119,7 @@ func (d *childDriver) handleConnectRequest(c *net.UnixConn, req *msg.Request) er } else { p := net.ParseIP(ip) if p == nil { - return errors.Errorf("invalid IP: %q", ip) + return fmt.Errorf("invalid IP: %q", ip) } ip = p.String() } @@ -130,7 +130,7 @@ func (d *childDriver) handleConnectRequest(c *net.UnixConn, req *msg.Request) er defer targetConn.Close() // no effect on duplicated FD targetConnFiler, ok := targetConn.(filer) if !ok { - return errors.Errorf("unknown target connection: %+v", targetConn) + return fmt.Errorf("unknown target connection: %+v", targetConn) } targetConnFile, err := targetConnFiler.File() if err != nil { diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg/msg.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg/msg.go index a60d99bd9..31080609a 100644 --- a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg/msg.go +++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg/msg.go @@ -1,10 +1,11 @@ package msg import ( + "errors" + "fmt" "net" "time" - "github.com/pkg/errors" "golang.org/x/sys/unix" "github.com/rootless-containers/rootlesskit/pkg/msgutil" @@ -78,7 +79,7 @@ func ConnectToChild(c *net.UnixConn, spec port.Spec) (int, error) { return 0, err } if oobN != oobSpace { - return 0, errors.Errorf("expected OOB space %d, got %d", oobSpace, oobN) + return 0, fmt.Errorf("expected OOB space %d, got %d", oobSpace, oobN) } oob = oob[:oobN] fd, err := parseFDFromOOB(oob) @@ -126,7 +127,7 @@ func parseFDFromOOB(oob []byte) (int, error) { return 0, err } if len(scms) != 1 { - return 0, errors.Errorf("unexpected scms: %v", scms) + return 0, fmt.Errorf("unexpected scms: %v", scms) } scm := scms[0] fds, err := unix.ParseUnixRights(&scm) @@ -134,7 +135,7 @@ func parseFDFromOOB(oob []byte) (int, error) { return 0, err } if len(fds) != 1 { - return 0, errors.Errorf("unexpected fds: %v", fds) + return 0, fmt.Errorf("unexpected fds: %v", fds) } return fds[0], nil } diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/parent.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/parent.go index c6eecc826..1c53e26a6 100644 --- a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/parent.go +++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/parent.go @@ -2,9 +2,9 @@ package parent import ( "context" + "errors" "fmt" "io" - "io/ioutil" "net" "os" "path/filepath" @@ -14,8 +14,6 @@ import ( "syscall" "time" - "github.com/pkg/errors" - "github.com/rootless-containers/rootlesskit/pkg/api" "github.com/rootless-containers/rootlesskit/pkg/port" "github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg" @@ -32,10 +30,10 @@ func NewDriver(logWriter io.Writer, stateDir string) (port.ParentDriver, error) childReadyPipePath := filepath.Join(stateDir, ".bp-ready.pipe") // remove the path just in case the previous rootlesskit instance crashed if err := os.RemoveAll(childReadyPipePath); err != nil { - return nil, errors.Wrapf(err, "cannot remove %s", childReadyPipePath) + return nil, fmt.Errorf("cannot remove %s: %w", childReadyPipePath, err) } if err := syscall.Mkfifo(childReadyPipePath, 0600); err != nil { - return nil, errors.Wrapf(err, "cannot mkfifo %s", childReadyPipePath) + return nil, fmt.Errorf("cannot mkfifo %s: %w", childReadyPipePath, err) } d := driver{ logWriter: logWriter, @@ -79,7 +77,7 @@ func (d *driver) RunParentDriver(initComplete chan struct{}, quit <-chan struct{ if err != nil { return err } - if _, err = ioutil.ReadAll(childReadyPipeR); err != nil { + if _, err = io.ReadAll(childReadyPipeR); err != nil { return err } childReadyPipeR.Close() @@ -110,7 +108,7 @@ func annotateEPERM(origErr error, spec port.Spec) error { // Read "net.ipv4.ip_unprivileged_port_start" value (typically 1024) // TODO: what for IPv6? // NOTE: sync.Once should not be used here - b, e := ioutil.ReadFile("/proc/sys/net/ipv4/ip_unprivileged_port_start") + b, e := os.ReadFile("/proc/sys/net/ipv4/ip_unprivileged_port_start") if e != nil { return origErr } @@ -129,7 +127,7 @@ func annotateEPERM(origErr error, spec port.Spec) error { text += ", or set CAP_NET_BIND_SERVICE on rootlesskit binary" } text += fmt.Sprintf(", or choose a larger port number (>= %d)", start) - return errors.Wrap(origErr, text) + return fmt.Errorf(text+": %w", origErr) } func (d *driver) AddPort(ctx context.Context, spec port.Spec) (*port.Status, error) { @@ -152,7 +150,7 @@ func (d *driver) AddPort(ctx context.Context, spec port.Spec) (*port.Status, err } return errors.New("routineStoppedCh was closed without sending data?") case <-ctx.Done(): - return errors.Wrap(err, "timed out while waiting for routineStoppedCh after closing routineStopCh") + return fmt.Errorf("timed out while waiting for routineStoppedCh after closing routineStopCh: %w", err) } } switch spec.Proto { @@ -198,7 +196,7 @@ func (d *driver) RemovePort(ctx context.Context, id int) error { defer d.mu.Unlock() stop, ok := d.stoppers[id] if !ok { - return errors.Errorf("unknown id: %d", id) + return fmt.Errorf("unknown id: %d", id) } if _, ok := ctx.Deadline(); !ok { var cancel context.CancelFunc diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udp.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udp.go index 67062117a..47f3a6461 100644 --- a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udp.go +++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udp.go @@ -1,13 +1,12 @@ package udp import ( + "fmt" "io" "net" "os" "strconv" - "github.com/pkg/errors" - "github.com/rootless-containers/rootlesskit/pkg/port" "github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg" "github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udpproxy" @@ -39,7 +38,7 @@ func Run(socketPath string, spec port.Spec, stopCh <-chan struct{}, stoppedCh ch } uc, ok := fc.(*net.UDPConn) if !ok { - return nil, errors.Errorf("file conn doesn't implement *net.UDPConn: %+v", fc) + return nil, fmt.Errorf("file conn doesn't implement *net.UDPConn: %+v", fc) } return uc, nil }, diff --git a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/portutil/portutil.go b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/portutil/portutil.go index 937932642..a1e649ab7 100644 --- a/vendor/github.com/rootless-containers/rootlesskit/pkg/port/portutil/portutil.go +++ b/vendor/github.com/rootless-containers/rootlesskit/pkg/port/portutil/portutil.go @@ -1,13 +1,12 @@ package portutil import ( + "fmt" "net" "strconv" "strings" "text/scanner" - "github.com/pkg/errors" - "github.com/rootless-containers/rootlesskit/pkg/port" ) @@ -49,18 +48,18 @@ func ParsePortSpec(portSpec string) (*port.Spec, error) { // Get the proto protoPos := strings.LastIndex(portSpec, "/") if protoPos < 0 { - return nil, errors.Errorf("missing proto in PortSpec string: %q", portSpec) + return nil, fmt.Errorf("missing proto in PortSpec string: %q", portSpec) } parts[proto] = portSpec[protoPos+1:] err = validateProto(parts[proto]) if err != nil { - return nil, errors.Wrapf(err, "invalid PortSpec string: %q", portSpec) + return nil, fmt.Errorf("invalid PortSpec string: %q: %w", portSpec, err) } // Get the parent port portPos := strings.LastIndex(portSpec, ":") if portPos < 0 { - return nil, errors.Errorf("unexpected PortSpec string: %q", portSpec) + return nil, fmt.Errorf("unexpected PortSpec string: %q", portSpec) } parts[childPort] = portSpec[portPos+1 : protoPos] @@ -69,7 +68,7 @@ func ParsePortSpec(portSpec string) (*port.Spec, error) { for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() { if index > childPort { - return nil, errors.Errorf("unexpected PortSpec string: %q", portSpec) + return nil, fmt.Errorf("unexpected PortSpec string: %q", portSpec) } switch tok { @@ -92,10 +91,10 @@ func ParsePortSpec(portSpec string) (*port.Spec, error) { } if parts[parentIP] != "" && net.ParseIP(parts[parentIP]) == nil { - return nil, errors.Errorf("unexpected ParentIP in PortSpec string: %q", portSpec) + return nil, fmt.Errorf("unexpected ParentIP in PortSpec string: %q", portSpec) } if parts[childIP] != "" && net.ParseIP(parts[childIP]) == nil { - return nil, errors.Errorf("unexpected ParentIP in PortSpec string: %q", portSpec) + return nil, fmt.Errorf("unexpected ParentIP in PortSpec string: %q", portSpec) } ps := &port.Spec{ @@ -106,12 +105,12 @@ func ParsePortSpec(portSpec string) (*port.Spec, error) { ps.ParentPort, err = strconv.Atoi(parts[parentPort]) if err != nil { - return nil, errors.Wrapf(err, "unexpected ChildPort in PortSpec string: %q", portSpec) + return nil, fmt.Errorf("unexpected ChildPort in PortSpec string: %q: %w", portSpec, err) } ps.ChildPort, err = strconv.Atoi(parts[childPort]) if err != nil { - return nil, errors.Wrapf(err, "unexpected ParentPort in PortSpec string: %q", portSpec) + return nil, fmt.Errorf("unexpected ParentPort in PortSpec string: %q: %w", portSpec, err) } return ps, nil @@ -125,26 +124,26 @@ func ValidatePortSpec(spec port.Spec, existingPorts map[int]*port.Status) error } if spec.ParentIP != "" { if net.ParseIP(spec.ParentIP) == nil { - return errors.Errorf("invalid ParentIP: %q", spec.ParentIP) + return fmt.Errorf("invalid ParentIP: %q", spec.ParentIP) } } if spec.ChildIP != "" { if net.ParseIP(spec.ChildIP) == nil { - return errors.Errorf("invalid ChildIP: %q", spec.ChildIP) + return fmt.Errorf("invalid ChildIP: %q", spec.ChildIP) } } if spec.ParentPort <= 0 || spec.ParentPort > 65535 { - return errors.Errorf("invalid ParentPort: %q", spec.ParentPort) + return fmt.Errorf("invalid ParentPort: %q", spec.ParentPort) } if spec.ChildPort <= 0 || spec.ChildPort > 65535 { - return errors.Errorf("invalid ChildPort: %q", spec.ChildPort) + return fmt.Errorf("invalid ChildPort: %q", spec.ChildPort) } for id, p := range existingPorts { sp := p.Spec sameProto := sp.Proto == spec.Proto sameParent := sp.ParentIP == spec.ParentIP && sp.ParentPort == spec.ParentPort if sameProto && sameParent { - return errors.Errorf("conflict with ID %d", id) + return fmt.Errorf("conflict with ID %d", id) } } return nil @@ -158,6 +157,6 @@ func validateProto(proto string) error { "sctp", "sctp4", "sctp6": return nil default: - return errors.Errorf("unknown proto: %q", proto) + return fmt.Errorf("unknown proto: %q", proto) } } |