mirror of
https://github.com/containers/podman.git
synced 2025-07-02 00:30:00 +08:00
Merge pull request #22262 from Luap99/rootlesskit-v2
update github.com/rootless-containers/rootlesskit to v2
This commit is contained in:
@ -17,9 +17,9 @@ import (
|
|||||||
"github.com/containernetworking/plugins/pkg/ns"
|
"github.com/containernetworking/plugins/pkg/ns"
|
||||||
"github.com/containers/common/libnetwork/types"
|
"github.com/containers/common/libnetwork/types"
|
||||||
"github.com/containers/common/pkg/rootlessport"
|
"github.com/containers/common/pkg/rootlessport"
|
||||||
rkport "github.com/rootless-containers/rootlesskit/pkg/port"
|
rkport "github.com/rootless-containers/rootlesskit/v2/pkg/port"
|
||||||
rkbuiltin "github.com/rootless-containers/rootlesskit/pkg/port/builtin"
|
rkbuiltin "github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin"
|
||||||
rkportutil "github.com/rootless-containers/rootlesskit/pkg/port/portutil"
|
rkportutil "github.com/rootless-containers/rootlesskit/v2/pkg/port/portutil"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
@ -343,7 +343,7 @@ func child() error {
|
|||||||
errCh := make(chan error)
|
errCh := make(chan error)
|
||||||
go func() {
|
go func() {
|
||||||
d := rkbuiltin.NewChildDriver(os.Stderr)
|
d := rkbuiltin.NewChildDriver(os.Stderr)
|
||||||
dErr := d.RunChildDriver(opaque, quit)
|
dErr := d.RunChildDriver(opaque, quit, "")
|
||||||
errCh <- dErr
|
errCh <- dErr
|
||||||
}()
|
}()
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/machine"
|
"github.com/containers/common/pkg/machine"
|
||||||
rkport "github.com/rootless-containers/rootlesskit/pkg/port"
|
rkport "github.com/rootless-containers/rootlesskit/v2/pkg/port"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WSL machines do not relay ipv4 traffic to dual-stack ports, simulate instead
|
// WSL machines do not relay ipv4 traffic to dual-stack ports, simulate instead
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/containers/common/pkg/machine"
|
"github.com/containers/common/pkg/machine"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
2
go.mod
2
go.mod
@ -73,7 +73,7 @@ require (
|
|||||||
github.com/opencontainers/runtime-tools v0.9.1-0.20230914150019-408c51e934dc
|
github.com/opencontainers/runtime-tools v0.9.1-0.20230914150019-408c51e934dc
|
||||||
github.com/opencontainers/selinux v1.11.0
|
github.com/opencontainers/selinux v1.11.0
|
||||||
github.com/openshift/imagebuilder v1.2.7
|
github.com/openshift/imagebuilder v1.2.7
|
||||||
github.com/rootless-containers/rootlesskit v1.1.1
|
github.com/rootless-containers/rootlesskit/v2 v2.0.2
|
||||||
github.com/shirou/gopsutil/v3 v3.24.3
|
github.com/shirou/gopsutil/v3 v3.24.3
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
github.com/spf13/cobra v1.8.0
|
github.com/spf13/cobra v1.8.0
|
||||||
|
4
go.sum
4
go.sum
@ -499,8 +499,8 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
|||||||
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||||
github.com/rootless-containers/rootlesskit v1.1.1 h1:F5psKWoWY9/VjZ3ifVcaosjvFZJOagX85U22M0/EQZE=
|
github.com/rootless-containers/rootlesskit/v2 v2.0.2 h1:wztWcDYFlk+EVAUuPJwlNMFXZIk1G14T45lv47WWGuA=
|
||||||
github.com/rootless-containers/rootlesskit v1.1.1/go.mod h1:UD5GoA3dqKCJrnvnhVgQQnweMF2qZnf9KLw8EewcMZI=
|
github.com/rootless-containers/rootlesskit/v2 v2.0.2/go.mod h1:hE+ztevrQxNi+tdZyPKumzDk7VKDAf0E4seOzlOyBsY=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y=
|
github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y=
|
||||||
github.com/seccomp/libseccomp-golang v0.10.0 h1:aA4bp+/Zzi0BnWZ2F1wgNBs5gTpm+na2rWM6M9YjLpY=
|
github.com/seccomp/libseccomp-golang v0.10.0 h1:aA4bp+/Zzi0BnWZ2F1wgNBs5gTpm+na2rWM6M9YjLpY=
|
||||||
|
@ -8,11 +8,6 @@ const (
|
|||||||
Version = "1.1.1"
|
Version = "1.1.1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrorJSON is returned with "application/json" content type and non-2XX status code
|
|
||||||
type ErrorJSON struct {
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Info is the structure returned by `GET /info`
|
// Info is the structure returned by `GET /info`
|
||||||
type Info struct {
|
type Info struct {
|
||||||
APIVersion string `json:"apiVersion"` // REST API version
|
APIVersion string `json:"apiVersion"` // REST API version
|
@ -1,5 +1,5 @@
|
|||||||
// Package msgutil provides utility for JSON message with uint32le header
|
// Package lowlevelmsgutil provides utility for JSON message with uint32le header
|
||||||
package msgutil
|
package lowlevelmsgutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
@ -3,9 +3,9 @@ package builtin
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port/builtin/child"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/child"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/parent"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
@ -11,10 +11,11 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/msgutil"
|
"github.com/containernetworking/plugins/pkg/ns"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/lowlevelmsgutil"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port"
|
||||||
opaquepkg "github.com/rootless-containers/rootlesskit/pkg/port/builtin/opaque"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/msg"
|
||||||
|
opaquepkg "github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/opaque"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewDriver(logWriter io.Writer) port.ChildDriver {
|
func NewDriver(logWriter io.Writer) port.ChildDriver {
|
||||||
@ -27,7 +28,7 @@ type childDriver struct {
|
|||||||
logWriter io.Writer
|
logWriter io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *childDriver) RunChildDriver(opaque map[string]string, quit <-chan struct{}) error {
|
func (d *childDriver) RunChildDriver(opaque map[string]string, quit <-chan struct{}, detachedNetNSPath string) error {
|
||||||
socketPath := opaque[opaquepkg.SocketPath]
|
socketPath := opaque[opaquepkg.SocketPath]
|
||||||
if socketPath == "" {
|
if socketPath == "" {
|
||||||
return errors.New("socket path not set")
|
return errors.New("socket path not set")
|
||||||
@ -68,34 +69,40 @@ func (d *childDriver) RunChildDriver(opaque map[string]string, quit <-chan struc
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
if rerr := d.routine(c); rerr != nil {
|
if rerr := d.routine(c, detachedNetNSPath); rerr != nil {
|
||||||
rep := msg.Reply{
|
rep := msg.Reply{
|
||||||
Error: rerr.Error(),
|
Error: rerr.Error(),
|
||||||
}
|
}
|
||||||
msgutil.MarshalToWriter(c, &rep)
|
lowlevelmsgutil.MarshalToWriter(c, &rep)
|
||||||
}
|
}
|
||||||
c.Close()
|
c.Close()
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *childDriver) routine(c *net.UnixConn) error {
|
func (d *childDriver) routine(c *net.UnixConn, detachedNetNSPath string) error {
|
||||||
var req msg.Request
|
var req msg.Request
|
||||||
if _, err := msgutil.UnmarshalFromReader(c, &req); err != nil {
|
if _, err := lowlevelmsgutil.UnmarshalFromReader(c, &req); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
switch req.Type {
|
switch req.Type {
|
||||||
case msg.RequestTypeInit:
|
case msg.RequestTypeInit:
|
||||||
return d.handleConnectInit(c, &req)
|
return d.handleConnectInit(c, &req)
|
||||||
case msg.RequestTypeConnect:
|
case msg.RequestTypeConnect:
|
||||||
|
if detachedNetNSPath == "" {
|
||||||
return d.handleConnectRequest(c, &req)
|
return d.handleConnectRequest(c, &req)
|
||||||
|
} else {
|
||||||
|
return ns.WithNetNSPath(detachedNetNSPath, func(_ ns.NetNS) error {
|
||||||
|
return d.handleConnectRequest(c, &req)
|
||||||
|
})
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unknown request type %q", req.Type)
|
return fmt.Errorf("unknown request type %q", req.Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *childDriver) handleConnectInit(c *net.UnixConn, req *msg.Request) error {
|
func (d *childDriver) handleConnectInit(c *net.UnixConn, req *msg.Request) error {
|
||||||
_, err := msgutil.MarshalToWriter(c, nil)
|
_, err := lowlevelmsgutil.MarshalToWriter(c, nil)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -8,8 +8,8 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/msgutil"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/lowlevelmsgutil"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -35,14 +35,14 @@ func Initiate(c *net.UnixConn) error {
|
|||||||
req := Request{
|
req := Request{
|
||||||
Type: RequestTypeInit,
|
Type: RequestTypeInit,
|
||||||
}
|
}
|
||||||
if _, err := msgutil.MarshalToWriter(c, &req); err != nil {
|
if _, err := lowlevelmsgutil.MarshalToWriter(c, &req); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := c.CloseWrite(); err != nil {
|
if err := c.CloseWrite(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var rep Reply
|
var rep Reply
|
||||||
if _, err := msgutil.UnmarshalFromReader(c, &rep); err != nil {
|
if _, err := lowlevelmsgutil.UnmarshalFromReader(c, &rep); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return c.CloseRead()
|
return c.CloseRead()
|
||||||
@ -57,7 +57,7 @@ func ConnectToChild(c *net.UnixConn, spec port.Spec) (int, error) {
|
|||||||
Port: spec.ChildPort,
|
Port: spec.ChildPort,
|
||||||
IP: spec.ChildIP,
|
IP: spec.ChildIP,
|
||||||
}
|
}
|
||||||
if _, err := msgutil.MarshalToWriter(c, &req); err != nil {
|
if _, err := lowlevelmsgutil.MarshalToWriter(c, &req); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if err := c.CloseWrite(); err != nil {
|
if err := c.CloseWrite(); err != nil {
|
@ -14,13 +14,13 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/api"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/api"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/msg"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port/builtin/opaque"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/opaque"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/tcp"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/parent/tcp"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/parent/udp"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port/portutil"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port/portutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewDriver for builtin driver.
|
// NewDriver for builtin driver.
|
@ -8,8 +8,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/msg"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Run(socketPath string, spec port.Spec, stopCh <-chan struct{}, stoppedCh chan error, logWriter io.Writer) error {
|
func Run(socketPath string, spec port.Spec, stopCh <-chan struct{}, stoppedCh chan error, logWriter io.Writer) error {
|
@ -7,9 +7,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/msg"
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udpproxy"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/parent/udp/udpproxy"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Run(socketPath string, spec port.Spec, stopCh <-chan struct{}, stoppedCh chan error, logWriter io.Writer) error {
|
func Run(socketPath string, spec port.Spec, stopCh <-chan struct{}, stoppedCh chan error, logWriter io.Writer) error {
|
@ -4,7 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/api"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Spec struct {
|
type Spec struct {
|
||||||
@ -35,8 +35,6 @@ type Manager interface {
|
|||||||
|
|
||||||
// ChildContext is used for RunParentDriver
|
// ChildContext is used for RunParentDriver
|
||||||
type ChildContext struct {
|
type ChildContext struct {
|
||||||
// PID of the child, can be used for ns-entering to the child namespaces.
|
|
||||||
PID int
|
|
||||||
// IP of the tap device
|
// IP of the tap device
|
||||||
IP net.IP
|
IP net.IP
|
||||||
}
|
}
|
||||||
@ -57,5 +55,6 @@ type ParentDriver interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ChildDriver interface {
|
type ChildDriver interface {
|
||||||
RunChildDriver(opaque map[string]string, quit <-chan struct{}) error
|
// RunChildDriver is executed in the child's namespaces, excluding detached-netns.
|
||||||
|
RunChildDriver(opaque map[string]string, quit <-chan struct{}, detachedNetNSPath string) error
|
||||||
}
|
}
|
@ -7,7 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"text/scanner"
|
"text/scanner"
|
||||||
|
|
||||||
"github.com/rootless-containers/rootlesskit/pkg/port"
|
"github.com/rootless-containers/rootlesskit/v2/pkg/port"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ParsePortSpec parses a Docker-like representation of PortSpec, but with
|
// ParsePortSpec parses a Docker-like representation of PortSpec, but with
|
26
vendor/modules.txt
vendored
26
vendor/modules.txt
vendored
@ -949,20 +949,20 @@ github.com/proglottis/gpgme
|
|||||||
# github.com/rivo/uniseg v0.4.7
|
# github.com/rivo/uniseg v0.4.7
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
github.com/rivo/uniseg
|
github.com/rivo/uniseg
|
||||||
# github.com/rootless-containers/rootlesskit v1.1.1
|
# github.com/rootless-containers/rootlesskit/v2 v2.0.2
|
||||||
## explicit; go 1.19
|
## explicit; go 1.19
|
||||||
github.com/rootless-containers/rootlesskit/pkg/api
|
github.com/rootless-containers/rootlesskit/v2/pkg/api
|
||||||
github.com/rootless-containers/rootlesskit/pkg/msgutil
|
github.com/rootless-containers/rootlesskit/v2/pkg/lowlevelmsgutil
|
||||||
github.com/rootless-containers/rootlesskit/pkg/port
|
github.com/rootless-containers/rootlesskit/v2/pkg/port
|
||||||
github.com/rootless-containers/rootlesskit/pkg/port/builtin
|
github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin
|
||||||
github.com/rootless-containers/rootlesskit/pkg/port/builtin/child
|
github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/child
|
||||||
github.com/rootless-containers/rootlesskit/pkg/port/builtin/msg
|
github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/msg
|
||||||
github.com/rootless-containers/rootlesskit/pkg/port/builtin/opaque
|
github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/opaque
|
||||||
github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent
|
github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/parent
|
||||||
github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/tcp
|
github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/parent/tcp
|
||||||
github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp
|
github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/parent/udp
|
||||||
github.com/rootless-containers/rootlesskit/pkg/port/builtin/parent/udp/udpproxy
|
github.com/rootless-containers/rootlesskit/v2/pkg/port/builtin/parent/udp/udpproxy
|
||||||
github.com/rootless-containers/rootlesskit/pkg/port/portutil
|
github.com/rootless-containers/rootlesskit/v2/pkg/port/portutil
|
||||||
# github.com/seccomp/libseccomp-golang v0.10.0
|
# github.com/seccomp/libseccomp-golang v0.10.0
|
||||||
## explicit; go 1.14
|
## explicit; go 1.14
|
||||||
github.com/seccomp/libseccomp-golang
|
github.com/seccomp/libseccomp-golang
|
||||||
|
Reference in New Issue
Block a user