mirror of
https://github.com/mudler/luet.git
synced 2025-09-13 13:50:26 +00:00
⬆️ Bump helm.sh/helm/v3 from 3.3.4 to 3.6.1 (#280)
Bumps [helm.sh/helm/v3](https://github.com/helm/helm) from 3.3.4 to 3.6.1. - [Release notes](https://github.com/helm/helm/releases) - [Commits](https://github.com/helm/helm/compare/v3.3.4...v3.6.1) --- updated-dependencies: - dependency-name: helm.sh/helm/v3 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
30
vendor/github.com/moby/term/.gitignore
generated
vendored
30
vendor/github.com/moby/term/.gitignore
generated
vendored
@@ -1,24 +1,8 @@
|
||||
# Docker project generated files to ignore
|
||||
# if you want to ignore files created by your editor/tools,
|
||||
# please consider a global .gitignore https://help.github.com/articles/ignoring-files
|
||||
*.exe
|
||||
*.exe~
|
||||
*.gz
|
||||
*.orig
|
||||
test.main
|
||||
.*.swp
|
||||
.DS_Store
|
||||
# a .bashrc may be added to customize the build environment
|
||||
.bashrc
|
||||
.editorconfig
|
||||
.gopath/
|
||||
.go-pkg-cache/
|
||||
.idea/
|
||||
autogen/
|
||||
bundles/
|
||||
cmd/dockerd/dockerd
|
||||
contrib/builder/rpm/*/changelog
|
||||
vendor/pkg/
|
||||
go-test-report.json
|
||||
# if you want to ignore files created by your editor/tools, consider using a
|
||||
# global .gitignore or .git/info/exclude see https://help.github.com/articles/ignoring-files
|
||||
.*
|
||||
!.github
|
||||
!.gitignore
|
||||
profile.out
|
||||
junit-report.xml
|
||||
# support running go modules in vendor mode for local development
|
||||
vendor/
|
||||
|
36
vendor/github.com/moby/term/README.md
generated
vendored
Normal file
36
vendor/github.com/moby/term/README.md
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
# term - utilities for dealing with terminals
|
||||
|
||||
 [](https://godoc.org/github.com/moby/term) [](https://goreportcard.com/report/github.com/moby/term)
|
||||
|
||||
term provides structures and helper functions to work with terminal (state, sizes).
|
||||
|
||||
#### Using term
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/moby/term"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fd := os.Stdin.Fd()
|
||||
if term.IsTerminal(fd) {
|
||||
ws, err := term.GetWinsize(fd)
|
||||
if err != nil {
|
||||
log.Fatalf("term.GetWinsize: %s", err)
|
||||
}
|
||||
log.Printf("%d:%d\n", ws.Height, ws.Width)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Want to hack on term? [Docker's contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md) apply.
|
||||
|
||||
## Copyright and license
|
||||
Code and documentation copyright 2015 Docker, inc. Code released under the Apache 2.0 license. Docs released under Creative commons.
|
2
vendor/github.com/moby/term/ascii.go
generated
vendored
2
vendor/github.com/moby/term/ascii.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
package term // import "github.com/moby/term"
|
||||
package term
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
9
vendor/github.com/moby/term/go.mod
generated
vendored
9
vendor/github.com/moby/term/go.mod
generated
vendored
@@ -4,10 +4,9 @@ go 1.13
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78
|
||||
github.com/google/go-cmp v0.3.1
|
||||
github.com/creack/pty v1.1.11
|
||||
github.com/google/go-cmp v0.4.0
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527
|
||||
gotest.tools v2.2.0+incompatible
|
||||
gotest.tools/v3 v3.0.2 // indirect
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a
|
||||
gotest.tools/v3 v3.0.2
|
||||
)
|
||||
|
28
vendor/github.com/moby/term/go.sum
generated
vendored
28
vendor/github.com/moby/term/go.sum
generated
vendored
@@ -1,33 +1,23 @@
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a h1:i47hUS795cOydZI4AwJQCKXOr4BvxzvikwDoDtHhP2Y=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gotest.tools/v3 v3.0.2 h1:kG1BFyqVHuQoVQiR1bWGnfz/fmHvvuiSPIV7rvl360E=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
|
94
vendor/github.com/moby/term/proxy.go
generated
vendored
94
vendor/github.com/moby/term/proxy.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
package term // import "github.com/moby/term"
|
||||
package term
|
||||
|
||||
import (
|
||||
"io"
|
||||
@@ -19,6 +19,7 @@ type escapeProxy struct {
|
||||
escapeKeys []byte
|
||||
escapeKeyPos int
|
||||
r io.Reader
|
||||
buf []byte
|
||||
}
|
||||
|
||||
// NewEscapeProxy returns a new TTY proxy reader which wraps the given reader
|
||||
@@ -31,48 +32,57 @@ func NewEscapeProxy(r io.Reader, escapeKeys []byte) io.Reader {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *escapeProxy) Read(buf []byte) (int, error) {
|
||||
nr, err := r.r.Read(buf)
|
||||
|
||||
if len(r.escapeKeys) == 0 {
|
||||
return nr, err
|
||||
}
|
||||
|
||||
preserve := func() {
|
||||
// this preserves the original key presses in the passed in buffer
|
||||
nr += r.escapeKeyPos
|
||||
preserve := make([]byte, 0, r.escapeKeyPos+len(buf))
|
||||
preserve = append(preserve, r.escapeKeys[:r.escapeKeyPos]...)
|
||||
preserve = append(preserve, buf...)
|
||||
r.escapeKeyPos = 0
|
||||
copy(buf[0:nr], preserve)
|
||||
}
|
||||
|
||||
if nr != 1 || err != nil {
|
||||
if r.escapeKeyPos > 0 {
|
||||
preserve()
|
||||
}
|
||||
return nr, err
|
||||
}
|
||||
|
||||
if buf[0] != r.escapeKeys[r.escapeKeyPos] {
|
||||
if r.escapeKeyPos > 0 {
|
||||
preserve()
|
||||
}
|
||||
return nr, nil
|
||||
}
|
||||
|
||||
if r.escapeKeyPos == len(r.escapeKeys)-1 {
|
||||
func (r *escapeProxy) Read(buf []byte) (n int, err error) {
|
||||
if len(r.escapeKeys) > 0 && r.escapeKeyPos == len(r.escapeKeys) {
|
||||
return 0, EscapeError{}
|
||||
}
|
||||
|
||||
// Looks like we've got an escape key, but we need to match again on the next
|
||||
// read.
|
||||
// Store the current escape key we found so we can look for the next one on
|
||||
// the next read.
|
||||
// Since this is an escape key, make sure we don't let the caller read it
|
||||
// If later on we find that this is not the escape sequence, we'll add the
|
||||
// keys back
|
||||
r.escapeKeyPos++
|
||||
return nr - r.escapeKeyPos, nil
|
||||
if len(r.buf) > 0 {
|
||||
n = copy(buf, r.buf)
|
||||
r.buf = r.buf[n:]
|
||||
}
|
||||
|
||||
nr, err := r.r.Read(buf[n:])
|
||||
n += nr
|
||||
if len(r.escapeKeys) == 0 {
|
||||
return n, err
|
||||
}
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
if buf[i] == r.escapeKeys[r.escapeKeyPos] {
|
||||
r.escapeKeyPos++
|
||||
|
||||
// Check if the full escape sequence is matched.
|
||||
if r.escapeKeyPos == len(r.escapeKeys) {
|
||||
n = i + 1 - r.escapeKeyPos
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
return n, EscapeError{}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// If we need to prepend a partial escape sequence from the previous
|
||||
// read, make sure the new buffer size doesn't exceed len(buf).
|
||||
// Otherwise, preserve any extra data in a buffer for the next read.
|
||||
if i < r.escapeKeyPos {
|
||||
preserve := make([]byte, 0, r.escapeKeyPos+n)
|
||||
preserve = append(preserve, r.escapeKeys[:r.escapeKeyPos]...)
|
||||
preserve = append(preserve, buf[:n]...)
|
||||
n = copy(buf, preserve)
|
||||
i += r.escapeKeyPos
|
||||
r.buf = append(r.buf, preserve[n:]...)
|
||||
}
|
||||
r.escapeKeyPos = 0
|
||||
}
|
||||
|
||||
// If we're in the middle of reading an escape sequence, make sure we don't
|
||||
// let the caller read it. If later on we find that this is not the escape
|
||||
// sequence, we'll prepend it back to buf.
|
||||
n -= r.escapeKeyPos
|
||||
if n < 0 {
|
||||
n = 0
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
19
vendor/github.com/moby/term/tc.go
generated
vendored
19
vendor/github.com/moby/term/tc.go
generated
vendored
@@ -1,20 +1,19 @@
|
||||
// +build !windows
|
||||
|
||||
package term // import "github.com/moby/term"
|
||||
package term
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func tcget(fd uintptr, p *Termios) syscall.Errno {
|
||||
_, _, err := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(p)))
|
||||
return err
|
||||
func tcget(fd uintptr) (*Termios, error) {
|
||||
p, err := unix.IoctlGetTermios(int(fd), getTermios)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func tcset(fd uintptr, p *Termios) syscall.Errno {
|
||||
_, _, err := unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(p)))
|
||||
return err
|
||||
func tcset(fd uintptr, p *Termios) error {
|
||||
return unix.IoctlSetTermios(int(fd), setTermios, p)
|
||||
}
|
||||
|
20
vendor/github.com/moby/term/term.go
generated
vendored
20
vendor/github.com/moby/term/term.go
generated
vendored
@@ -2,7 +2,7 @@
|
||||
|
||||
// Package term provides structures and helper functions to work with
|
||||
// terminal (state, sizes).
|
||||
package term // import "github.com/moby/term"
|
||||
package term
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -50,8 +50,8 @@ func GetFdInfo(in interface{}) (uintptr, bool) {
|
||||
|
||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
var termios Termios
|
||||
return tcget(fd, &termios) == 0
|
||||
_, err := tcget(fd)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// RestoreTerminal restores the terminal connected to the given file descriptor
|
||||
@@ -60,20 +60,16 @@ func RestoreTerminal(fd uintptr, state *State) error {
|
||||
if state == nil {
|
||||
return ErrInvalidState
|
||||
}
|
||||
if err := tcset(fd, &state.termios); err != 0 {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return tcset(fd, &state.termios)
|
||||
}
|
||||
|
||||
// SaveState saves the state of the terminal connected to the given file descriptor.
|
||||
func SaveState(fd uintptr) (*State, error) {
|
||||
var oldState State
|
||||
if err := tcget(fd, &oldState.termios); err != 0 {
|
||||
termios, err := tcget(fd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &oldState, nil
|
||||
return &State{termios: *termios}, nil
|
||||
}
|
||||
|
||||
// DisableEcho applies the specified state to the terminal connected to the file
|
||||
@@ -82,7 +78,7 @@ func DisableEcho(fd uintptr, state *State) error {
|
||||
newState := state.termios
|
||||
newState.Lflag &^= unix.ECHO
|
||||
|
||||
if err := tcset(fd, &newState); err != 0 {
|
||||
if err := tcset(fd, &newState); err != nil {
|
||||
return err
|
||||
}
|
||||
handleInterrupt(fd, state)
|
||||
|
92
vendor/github.com/moby/term/term_windows.go
generated
vendored
92
vendor/github.com/moby/term/term_windows.go
generated
vendored
@@ -1,13 +1,12 @@
|
||||
package term // import "github.com/moby/term"
|
||||
package term
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall" // used for STD_INPUT_HANDLE, STD_OUTPUT_HANDLE and STD_ERROR_HANDLE
|
||||
|
||||
"github.com/Azure/go-ansiterm/winterm"
|
||||
windowsconsole "github.com/moby/term/windows"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// State holds the console mode for the terminal.
|
||||
@@ -28,37 +27,42 @@ var vtInputSupported bool
|
||||
func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
|
||||
// Turn on VT handling on all std handles, if possible. This might
|
||||
// fail, in which case we will fall back to terminal emulation.
|
||||
var emulateStdin, emulateStdout, emulateStderr bool
|
||||
fd := os.Stdin.Fd()
|
||||
if mode, err := winterm.GetConsoleMode(fd); err == nil {
|
||||
var (
|
||||
emulateStdin, emulateStdout, emulateStderr bool
|
||||
|
||||
mode uint32
|
||||
)
|
||||
|
||||
fd := windows.Handle(os.Stdin.Fd())
|
||||
if err := windows.GetConsoleMode(fd, &mode); err == nil {
|
||||
// Validate that winterm.ENABLE_VIRTUAL_TERMINAL_INPUT is supported, but do not set it.
|
||||
if err = winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_INPUT); err != nil {
|
||||
if err = windows.SetConsoleMode(fd, mode|windows.ENABLE_VIRTUAL_TERMINAL_INPUT); err != nil {
|
||||
emulateStdin = true
|
||||
} else {
|
||||
vtInputSupported = true
|
||||
}
|
||||
// Unconditionally set the console mode back even on failure because SetConsoleMode
|
||||
// remembers invalid bits on input handles.
|
||||
winterm.SetConsoleMode(fd, mode)
|
||||
_ = windows.SetConsoleMode(fd, mode)
|
||||
}
|
||||
|
||||
fd = os.Stdout.Fd()
|
||||
if mode, err := winterm.GetConsoleMode(fd); err == nil {
|
||||
fd = windows.Handle(os.Stdout.Fd())
|
||||
if err := windows.GetConsoleMode(fd, &mode); err == nil {
|
||||
// Validate winterm.DISABLE_NEWLINE_AUTO_RETURN is supported, but do not set it.
|
||||
if err = winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING|winterm.DISABLE_NEWLINE_AUTO_RETURN); err != nil {
|
||||
if err = windows.SetConsoleMode(fd, mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING|windows.DISABLE_NEWLINE_AUTO_RETURN); err != nil {
|
||||
emulateStdout = true
|
||||
} else {
|
||||
winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING)
|
||||
_ = windows.SetConsoleMode(fd, mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING)
|
||||
}
|
||||
}
|
||||
|
||||
fd = os.Stderr.Fd()
|
||||
if mode, err := winterm.GetConsoleMode(fd); err == nil {
|
||||
fd = windows.Handle(os.Stderr.Fd())
|
||||
if err := windows.GetConsoleMode(fd, &mode); err == nil {
|
||||
// Validate winterm.DISABLE_NEWLINE_AUTO_RETURN is supported, but do not set it.
|
||||
if err = winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING|winterm.DISABLE_NEWLINE_AUTO_RETURN); err != nil {
|
||||
if err = windows.SetConsoleMode(fd, mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING|windows.DISABLE_NEWLINE_AUTO_RETURN); err != nil {
|
||||
emulateStderr = true
|
||||
} else {
|
||||
winterm.SetConsoleMode(fd, mode|winterm.ENABLE_VIRTUAL_TERMINAL_PROCESSING)
|
||||
_ = windows.SetConsoleMode(fd, mode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,19 +71,22 @@ func StdStreams() (stdIn io.ReadCloser, stdOut, stdErr io.Writer) {
|
||||
// go-ansiterm hasn't switch to x/sys/windows.
|
||||
// TODO: switch back to x/sys/windows once go-ansiterm has switched
|
||||
if emulateStdin {
|
||||
stdIn = windowsconsole.NewAnsiReader(syscall.STD_INPUT_HANDLE)
|
||||
h := uint32(windows.STD_INPUT_HANDLE)
|
||||
stdIn = windowsconsole.NewAnsiReader(int(h))
|
||||
} else {
|
||||
stdIn = os.Stdin
|
||||
}
|
||||
|
||||
if emulateStdout {
|
||||
stdOut = windowsconsole.NewAnsiWriter(syscall.STD_OUTPUT_HANDLE)
|
||||
h := uint32(windows.STD_OUTPUT_HANDLE)
|
||||
stdOut = windowsconsole.NewAnsiWriter(int(h))
|
||||
} else {
|
||||
stdOut = os.Stdout
|
||||
}
|
||||
|
||||
if emulateStderr {
|
||||
stdErr = windowsconsole.NewAnsiWriter(syscall.STD_ERROR_HANDLE)
|
||||
h := uint32(windows.STD_ERROR_HANDLE)
|
||||
stdErr = windowsconsole.NewAnsiWriter(int(h))
|
||||
} else {
|
||||
stdErr = os.Stderr
|
||||
}
|
||||
@@ -94,8 +101,8 @@ func GetFdInfo(in interface{}) (uintptr, bool) {
|
||||
|
||||
// GetWinsize returns the window size based on the specified file descriptor.
|
||||
func GetWinsize(fd uintptr) (*Winsize, error) {
|
||||
info, err := winterm.GetConsoleScreenBufferInfo(fd)
|
||||
if err != nil {
|
||||
var info windows.ConsoleScreenBufferInfo
|
||||
if err := windows.GetConsoleScreenBufferInfo(windows.Handle(fd), &info); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -109,20 +116,23 @@ func GetWinsize(fd uintptr) (*Winsize, error) {
|
||||
|
||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
return windowsconsole.IsConsole(fd)
|
||||
var mode uint32
|
||||
err := windows.GetConsoleMode(windows.Handle(fd), &mode)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// RestoreTerminal restores the terminal connected to the given file descriptor
|
||||
// to a previous state.
|
||||
func RestoreTerminal(fd uintptr, state *State) error {
|
||||
return winterm.SetConsoleMode(fd, state.mode)
|
||||
return windows.SetConsoleMode(windows.Handle(fd), state.mode)
|
||||
}
|
||||
|
||||
// SaveState saves the state of the terminal connected to the given file descriptor.
|
||||
func SaveState(fd uintptr) (*State, error) {
|
||||
mode, e := winterm.GetConsoleMode(fd)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
var mode uint32
|
||||
|
||||
if err := windows.GetConsoleMode(windows.Handle(fd), &mode); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &State{mode: mode}, nil
|
||||
@@ -132,9 +142,9 @@ func SaveState(fd uintptr) (*State, error) {
|
||||
// -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx
|
||||
func DisableEcho(fd uintptr, state *State) error {
|
||||
mode := state.mode
|
||||
mode &^= winterm.ENABLE_ECHO_INPUT
|
||||
mode |= winterm.ENABLE_PROCESSED_INPUT | winterm.ENABLE_LINE_INPUT
|
||||
err := winterm.SetConsoleMode(fd, mode)
|
||||
mode &^= windows.ENABLE_ECHO_INPUT
|
||||
mode |= windows.ENABLE_PROCESSED_INPUT | windows.ENABLE_LINE_INPUT
|
||||
err := windows.SetConsoleMode(windows.Handle(fd), mode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -169,7 +179,7 @@ func SetRawTerminalOutput(fd uintptr) (*State, error) {
|
||||
|
||||
// Ignore failures, since winterm.DISABLE_NEWLINE_AUTO_RETURN might not be supported on this
|
||||
// version of Windows.
|
||||
winterm.SetConsoleMode(fd, state.mode|winterm.DISABLE_NEWLINE_AUTO_RETURN)
|
||||
_ = windows.SetConsoleMode(windows.Handle(fd), state.mode|windows.DISABLE_NEWLINE_AUTO_RETURN)
|
||||
return state, err
|
||||
}
|
||||
|
||||
@@ -188,21 +198,21 @@ func MakeRaw(fd uintptr) (*State, error) {
|
||||
// -- https://msdn.microsoft.com/en-us/library/windows/desktop/ms683462(v=vs.85).aspx
|
||||
|
||||
// Disable these modes
|
||||
mode &^= winterm.ENABLE_ECHO_INPUT
|
||||
mode &^= winterm.ENABLE_LINE_INPUT
|
||||
mode &^= winterm.ENABLE_MOUSE_INPUT
|
||||
mode &^= winterm.ENABLE_WINDOW_INPUT
|
||||
mode &^= winterm.ENABLE_PROCESSED_INPUT
|
||||
mode &^= windows.ENABLE_ECHO_INPUT
|
||||
mode &^= windows.ENABLE_LINE_INPUT
|
||||
mode &^= windows.ENABLE_MOUSE_INPUT
|
||||
mode &^= windows.ENABLE_WINDOW_INPUT
|
||||
mode &^= windows.ENABLE_PROCESSED_INPUT
|
||||
|
||||
// Enable these modes
|
||||
mode |= winterm.ENABLE_EXTENDED_FLAGS
|
||||
mode |= winterm.ENABLE_INSERT_MODE
|
||||
mode |= winterm.ENABLE_QUICK_EDIT_MODE
|
||||
mode |= windows.ENABLE_EXTENDED_FLAGS
|
||||
mode |= windows.ENABLE_INSERT_MODE
|
||||
mode |= windows.ENABLE_QUICK_EDIT_MODE
|
||||
if vtInputSupported {
|
||||
mode |= winterm.ENABLE_VIRTUAL_TERMINAL_INPUT
|
||||
mode |= windows.ENABLE_VIRTUAL_TERMINAL_INPUT
|
||||
}
|
||||
|
||||
err = winterm.SetConsoleMode(fd, mode)
|
||||
err = windows.SetConsoleMode(windows.Handle(fd), mode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -215,7 +225,7 @@ func restoreAtInterrupt(fd uintptr, state *State) {
|
||||
|
||||
go func() {
|
||||
_ = <-sigchan
|
||||
RestoreTerminal(fd, state)
|
||||
_ = RestoreTerminal(fd, state)
|
||||
os.Exit(0)
|
||||
}()
|
||||
}
|
||||
|
20
vendor/github.com/moby/term/termios_linux.go → vendor/github.com/moby/term/termios.go
generated
vendored
20
vendor/github.com/moby/term/termios_linux.go → vendor/github.com/moby/term/termios.go
generated
vendored
@@ -1,28 +1,24 @@
|
||||
package term // import "github.com/moby/term"
|
||||
// +build !windows
|
||||
|
||||
package term
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
getTermios = unix.TCGETS
|
||||
setTermios = unix.TCSETS
|
||||
)
|
||||
|
||||
// Termios is the Unix API for terminal I/O.
|
||||
type Termios unix.Termios
|
||||
type Termios = unix.Termios
|
||||
|
||||
// MakeRaw put the terminal connected to the given file descriptor into raw
|
||||
// MakeRaw puts the terminal connected to the given file descriptor into raw
|
||||
// mode and returns the previous state of the terminal so that it can be
|
||||
// restored.
|
||||
func MakeRaw(fd uintptr) (*State, error) {
|
||||
termios, err := unix.IoctlGetTermios(int(fd), getTermios)
|
||||
termios, err := tcget(fd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var oldState State
|
||||
oldState.termios = Termios(*termios)
|
||||
oldState := State{termios: *termios}
|
||||
|
||||
termios.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON)
|
||||
termios.Oflag &^= unix.OPOST
|
||||
@@ -32,7 +28,7 @@ func MakeRaw(fd uintptr) (*State, error) {
|
||||
termios.Cc[unix.VMIN] = 1
|
||||
termios.Cc[unix.VTIME] = 0
|
||||
|
||||
if err := unix.IoctlSetTermios(int(fd), setTermios, termios); err != nil {
|
||||
if err := tcset(fd, termios); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &oldState, nil
|
32
vendor/github.com/moby/term/termios_bsd.go
generated
vendored
32
vendor/github.com/moby/term/termios_bsd.go
generated
vendored
@@ -1,10 +1,8 @@
|
||||
// +build darwin freebsd openbsd netbsd
|
||||
|
||||
package term // import "github.com/moby/term"
|
||||
package term
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
@@ -12,31 +10,3 @@ const (
|
||||
getTermios = unix.TIOCGETA
|
||||
setTermios = unix.TIOCSETA
|
||||
)
|
||||
|
||||
// Termios is the Unix API for terminal I/O.
|
||||
type Termios unix.Termios
|
||||
|
||||
// MakeRaw put the terminal connected to the given file descriptor into raw
|
||||
// mode and returns the previous state of the terminal so that it can be
|
||||
// restored.
|
||||
func MakeRaw(fd uintptr) (*State, error) {
|
||||
var oldState State
|
||||
if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newState := oldState.termios
|
||||
newState.Iflag &^= (unix.IGNBRK | unix.BRKINT | unix.PARMRK | unix.ISTRIP | unix.INLCR | unix.IGNCR | unix.ICRNL | unix.IXON)
|
||||
newState.Oflag &^= unix.OPOST
|
||||
newState.Lflag &^= (unix.ECHO | unix.ECHONL | unix.ICANON | unix.ISIG | unix.IEXTEN)
|
||||
newState.Cflag &^= (unix.CSIZE | unix.PARENB)
|
||||
newState.Cflag |= unix.CS8
|
||||
newState.Cc[unix.VMIN] = 1
|
||||
newState.Cc[unix.VTIME] = 0
|
||||
|
||||
if _, _, err := unix.Syscall(unix.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &oldState, nil
|
||||
}
|
||||
|
12
vendor/github.com/moby/term/termios_nonbsd.go
generated
vendored
Normal file
12
vendor/github.com/moby/term/termios_nonbsd.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
//+build !darwin,!freebsd,!netbsd,!openbsd,!windows
|
||||
|
||||
package term
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
getTermios = unix.TCGETS
|
||||
setTermios = unix.TCSETS
|
||||
)
|
21
vendor/github.com/moby/term/windows/ansi_reader.go
generated
vendored
21
vendor/github.com/moby/term/windows/ansi_reader.go
generated
vendored
@@ -1,6 +1,6 @@
|
||||
// +build windows
|
||||
|
||||
package windowsconsole // import "github.com/moby/term/windows"
|
||||
package windowsconsole
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -31,7 +31,6 @@ type ansiReader struct {
|
||||
// NewAnsiReader returns an io.ReadCloser that provides VT100 terminal emulation on top of a
|
||||
// Windows console input handle.
|
||||
func NewAnsiReader(nFile int) io.ReadCloser {
|
||||
initLogger()
|
||||
file, fd := winterm.GetStdFile(nFile)
|
||||
return &ansiReader{
|
||||
file: file,
|
||||
@@ -59,8 +58,6 @@ func (ar *ansiReader) Read(p []byte) (int, error) {
|
||||
|
||||
// Previously read bytes exist, read as much as we can and return
|
||||
if len(ar.buffer) > 0 {
|
||||
logger.Debugf("Reading previously cached bytes")
|
||||
|
||||
originalLength := len(ar.buffer)
|
||||
copiedLength := copy(p, ar.buffer)
|
||||
|
||||
@@ -70,16 +67,14 @@ func (ar *ansiReader) Read(p []byte) (int, error) {
|
||||
ar.buffer = ar.buffer[copiedLength:]
|
||||
}
|
||||
|
||||
logger.Debugf("Read from cache p[%d]: % x", copiedLength, p)
|
||||
return copiedLength, nil
|
||||
}
|
||||
|
||||
// Read and translate key events
|
||||
events, err := readInputEvents(ar.fd, len(p))
|
||||
events, err := readInputEvents(ar, len(p))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
} else if len(events) == 0 {
|
||||
logger.Debug("No input events detected")
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
@@ -87,11 +82,9 @@ func (ar *ansiReader) Read(p []byte) (int, error) {
|
||||
|
||||
// Save excess bytes and right-size keyBytes
|
||||
if len(keyBytes) > len(p) {
|
||||
logger.Debugf("Received %d keyBytes, only room for %d bytes", len(keyBytes), len(p))
|
||||
ar.buffer = keyBytes[len(p):]
|
||||
keyBytes = keyBytes[:len(p)]
|
||||
} else if len(keyBytes) == 0 {
|
||||
logger.Debug("No key bytes returned from the translator")
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
@@ -100,13 +93,11 @@ func (ar *ansiReader) Read(p []byte) (int, error) {
|
||||
return 0, errors.New("unexpected copy length encountered")
|
||||
}
|
||||
|
||||
logger.Debugf("Read p[%d]: % x", copiedLength, p)
|
||||
logger.Debugf("Read keyBytes[%d]: % x", copiedLength, keyBytes)
|
||||
return copiedLength, nil
|
||||
}
|
||||
|
||||
// readInputEvents polls until at least one event is available.
|
||||
func readInputEvents(fd uintptr, maxBytes int) ([]winterm.INPUT_RECORD, error) {
|
||||
func readInputEvents(ar *ansiReader, maxBytes int) ([]winterm.INPUT_RECORD, error) {
|
||||
// Determine the maximum number of records to retrieve
|
||||
// -- Cast around the type system to obtain the size of a single INPUT_RECORD.
|
||||
// unsafe.Sizeof requires an expression vs. a type-reference; the casting
|
||||
@@ -118,25 +109,23 @@ func readInputEvents(fd uintptr, maxBytes int) ([]winterm.INPUT_RECORD, error) {
|
||||
} else if countRecords == 0 {
|
||||
countRecords = 1
|
||||
}
|
||||
logger.Debugf("[windows] readInputEvents: Reading %v records (buffer size %v, record size %v)", countRecords, maxBytes, recordSize)
|
||||
|
||||
// Wait for and read input events
|
||||
events := make([]winterm.INPUT_RECORD, countRecords)
|
||||
nEvents := uint32(0)
|
||||
eventsExist, err := winterm.WaitForSingleObject(fd, winterm.WAIT_INFINITE)
|
||||
eventsExist, err := winterm.WaitForSingleObject(ar.fd, winterm.WAIT_INFINITE)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if eventsExist {
|
||||
err = winterm.ReadConsoleInput(fd, events, &nEvents)
|
||||
err = winterm.ReadConsoleInput(ar.fd, events, &nEvents)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Return a slice restricted to the number of returned records
|
||||
logger.Debugf("[windows] readInputEvents: Read %v events", nEvents)
|
||||
return events[:nEvents], nil
|
||||
}
|
||||
|
||||
|
12
vendor/github.com/moby/term/windows/ansi_writer.go
generated
vendored
12
vendor/github.com/moby/term/windows/ansi_writer.go
generated
vendored
@@ -1,6 +1,6 @@
|
||||
// +build windows
|
||||
|
||||
package windowsconsole // import "github.com/moby/term/windows"
|
||||
package windowsconsole
|
||||
|
||||
import (
|
||||
"io"
|
||||
@@ -24,7 +24,6 @@ type ansiWriter struct {
|
||||
// NewAnsiWriter returns an io.Writer that provides VT100 terminal emulation on top of a
|
||||
// Windows console output handle.
|
||||
func NewAnsiWriter(nFile int) io.Writer {
|
||||
initLogger()
|
||||
file, fd := winterm.GetStdFile(nFile)
|
||||
info, err := winterm.GetConsoleScreenBufferInfo(fd)
|
||||
if err != nil {
|
||||
@@ -32,9 +31,8 @@ func NewAnsiWriter(nFile int) io.Writer {
|
||||
}
|
||||
|
||||
parser := ansiterm.CreateParser("Ground", winterm.CreateWinEventHandler(fd, file))
|
||||
logger.Infof("newAnsiWriter: parser %p", parser)
|
||||
|
||||
aw := &ansiWriter{
|
||||
return &ansiWriter{
|
||||
file: file,
|
||||
fd: fd,
|
||||
infoReset: info,
|
||||
@@ -42,10 +40,6 @@ func NewAnsiWriter(nFile int) io.Writer {
|
||||
escapeSequence: []byte(ansiterm.KEY_ESC_CSI),
|
||||
parser: parser,
|
||||
}
|
||||
|
||||
logger.Infof("newAnsiWriter: aw.parser %p", aw.parser)
|
||||
logger.Infof("newAnsiWriter: %v", aw)
|
||||
return aw
|
||||
}
|
||||
|
||||
func (aw *ansiWriter) Fd() uintptr {
|
||||
@@ -58,7 +52,5 @@ func (aw *ansiWriter) Write(p []byte) (total int, err error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
logger.Infof("Write: % x", p)
|
||||
logger.Infof("Write: %s", string(p))
|
||||
return aw.parser.Parse(p)
|
||||
}
|
||||
|
16
vendor/github.com/moby/term/windows/console.go
generated
vendored
16
vendor/github.com/moby/term/windows/console.go
generated
vendored
@@ -1,11 +1,11 @@
|
||||
// +build windows
|
||||
|
||||
package windowsconsole // import "github.com/moby/term/windows"
|
||||
package windowsconsole
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/Azure/go-ansiterm/winterm"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// GetHandleInfo returns file descriptor and bool indicating whether the file is a console.
|
||||
@@ -22,14 +22,18 @@ func GetHandleInfo(in interface{}) (uintptr, bool) {
|
||||
|
||||
if file, ok := in.(*os.File); ok {
|
||||
inFd = file.Fd()
|
||||
isTerminal = IsConsole(inFd)
|
||||
isTerminal = isConsole(inFd)
|
||||
}
|
||||
return inFd, isTerminal
|
||||
}
|
||||
|
||||
// IsConsole returns true if the given file descriptor is a Windows Console.
|
||||
// The code assumes that GetConsoleMode will return an error for file descriptors that are not a console.
|
||||
func IsConsole(fd uintptr) bool {
|
||||
_, e := winterm.GetConsoleMode(fd)
|
||||
return e == nil
|
||||
// Deprecated: use golang.org/x/sys/windows.GetConsoleMode() or golang.org/x/term.IsTerminal()
|
||||
var IsConsole = isConsole
|
||||
|
||||
func isConsole(fd uintptr) bool {
|
||||
var mode uint32
|
||||
err := windows.GetConsoleMode(windows.Handle(fd), &mode)
|
||||
return err == nil
|
||||
}
|
||||
|
5
vendor/github.com/moby/term/windows/doc.go
generated
vendored
Normal file
5
vendor/github.com/moby/term/windows/doc.go
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
// These files implement ANSI-aware input and output streams for use by the Docker Windows client.
|
||||
// When asked for the set of standard streams (e.g., stdin, stdout, stderr), the code will create
|
||||
// and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls.
|
||||
|
||||
package windowsconsole
|
34
vendor/github.com/moby/term/windows/windows.go
generated
vendored
34
vendor/github.com/moby/term/windows/windows.go
generated
vendored
@@ -1,34 +0,0 @@
|
||||
// +build windows
|
||||
// These files implement ANSI-aware input and output streams for use by the Docker Windows client.
|
||||
// When asked for the set of standard streams (e.g., stdin, stdout, stderr), the code will create
|
||||
// and return pseudo-streams that convert ANSI sequences to / from Windows Console API calls.
|
||||
|
||||
package windowsconsole // import "github.com/moby/term/windows"
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
ansiterm "github.com/Azure/go-ansiterm"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var logger *logrus.Logger
|
||||
var initOnce sync.Once
|
||||
|
||||
func initLogger() {
|
||||
initOnce.Do(func() {
|
||||
logFile := ioutil.Discard
|
||||
|
||||
if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" {
|
||||
logFile, _ = os.Create("ansiReaderWriter.log")
|
||||
}
|
||||
|
||||
logger = &logrus.Logger{
|
||||
Out: logFile,
|
||||
Formatter: new(logrus.TextFormatter),
|
||||
Level: logrus.DebugLevel,
|
||||
}
|
||||
})
|
||||
}
|
2
vendor/github.com/moby/term/winsize.go
generated
vendored
2
vendor/github.com/moby/term/winsize.go
generated
vendored
@@ -1,6 +1,6 @@
|
||||
// +build !windows
|
||||
|
||||
package term // import "github.com/moby/term"
|
||||
package term
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/unix"
|
||||
|
Reference in New Issue
Block a user