package xrootd

import "go-hep.org/x/hep/xrootd"

Package xrootd implements the XRootD protocol from

http://xrootd.org

Package xrootd provides a Client and a Server.

The NewClient function connects to a server:

ctx := context.Background()

client, err := xrootd.NewClient(ctx, addr, username)
if err != nil {
	// handle error
}

// ...

if err := client.Close(); err != nil {
	// handle error
}

The NewServer function creates a server:

srv := xrootd.NewServer(xrootd.Default(), nil)
err := srv.Serve(listener)

Index

Examples

Variables

var ErrServerClosed = errors.New("xrootd: server closed")

ErrServerClosed is returned by the Server's Serve method after a call to Shutdown.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

A Client to xrootd server which allows to send requests and receive responses. Concurrent requests are supported. Zero value is invalid, Client should be instantiated using NewClient.

Example (Chmod)

Code:

{
	ctx := context.Background()
	const username = "gopher"
	client, err := NewClient(ctx, "ccxrootdgotest.in2p3.fr:9001", username)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	if err := client.FS().Chmod(ctx, "/tmp/test.txt", xrdfs.OpenModeOwnerRead|xrdfs.OpenModeOwnerWrite); err != nil {
		log.Fatal(err)
	}

	if err := client.Close(); err != nil {
		log.Fatal(err)
	}
}
Example (Dirlist)

Code:

{
	ctx := context.Background()
	const username = "gopher"
	client, err := NewClient(ctx, "ccxrootdgotest.in2p3.fr:9001", username)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	entries, err := client.FS().Dirlist(ctx, "/tmp/dir1")
	if err != nil {
		log.Fatal(err)
	}
	for _, entry := range entries {
		fmt.Printf("Name: %s, size: %d\n", entry.Name(), entry.Size())
	}

	if err := client.Close(); err != nil {
		log.Fatal(err)
	}

	// Output:
	// Name: file1.txt, size: 0
}

Output:

Name: file1.txt, size: 0
Example (Mkdir)

Code:

{
	ctx := context.Background()
	const username = "gopher"
	client, err := NewClient(ctx, "ccxrootdgotest.in2p3.fr:9001", username)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	if err := client.FS().Mkdir(ctx, "/tmp/testdir", xrdfs.OpenModeOwnerRead|xrdfs.OpenModeOwnerWrite); err != nil {
		log.Fatal(err)
	}

	if err := client.Close(); err != nil {
		log.Fatal(err)
	}
}
Example (MkdirAll)

Code:

{
	ctx := context.Background()
	const username = "gopher"
	client, err := NewClient(ctx, "ccxrootdgotest.in2p3.fr:9001", username)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	if err := client.FS().MkdirAll(ctx, "/tmp/testdir/subdir", xrdfs.OpenModeOwnerRead|xrdfs.OpenModeOwnerWrite); err != nil {
		log.Fatal(err)
	}

	if err := client.Close(); err != nil {
		log.Fatal(err)
	}
}
Example (Open)

Code:

{
	ctx := context.Background()
	const username = "gopher"
	client, err := NewClient(ctx, "ccxrootdgotest.in2p3.fr:9001", username)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	file, err := client.FS().Open(ctx, "/tmp/test.txt", xrdfs.OpenModeOwnerRead, xrdfs.OpenOptionsOpenRead)
	if err != nil {
		log.Fatal(err)
	}

	if err := file.Close(ctx); err != nil {
		log.Fatal(err)
	}

	if err := client.Close(); err != nil {
		log.Fatal(err)
	}
}
Example (Read)

Code:

{
	ctx := context.Background()
	const username = "gopher"
	client, err := NewClient(ctx, "ccxrootdgotest.in2p3.fr:9001", username)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	file, err := client.FS().Open(ctx, "/tmp/test.txt", xrdfs.OpenModeOwnerRead, xrdfs.OpenOptionsOpenRead)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close(ctx)

	data := make([]byte, 10)
	n, err := file.ReadAt(data, 0)
	if err != nil {
		log.Fatal(err)
	}

	data = data[:n]
	fmt.Printf("%s\n", data)

	if err := file.Close(ctx); err != nil {
		log.Fatal(err)
	}

	if err := client.Close(); err != nil {
		log.Fatal(err)
	}

	// Output:
	// test
}

Output:

test
Example (RemoveAll)

Code:

{
	ctx := context.Background()
	const username = "gopher"
	client, err := NewClient(ctx, "ccxrootdgotest.in2p3.fr:9001", username)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	if err := client.FS().RemoveAll(ctx, "/tmp/testdir"); err != nil {
		log.Fatal(err)
	}

	if err := client.Close(); err != nil {
		log.Fatal(err)
	}
}
Example (RemoveDir)

Code:

{
	ctx := context.Background()
	const username = "gopher"
	client, err := NewClient(ctx, "ccxrootdgotest.in2p3.fr:9001", username)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	if err := client.FS().RemoveDir(ctx, "/tmp/testdir"); err != nil {
		log.Fatal(err)
	}

	if err := client.Close(); err != nil {
		log.Fatal(err)
	}
}
Example (RemoveFile)

Code:

{
	ctx := context.Background()
	const username = "gopher"
	client, err := NewClient(ctx, "ccxrootdgotest.in2p3.fr:9001", username)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	if err := client.FS().RemoveFile(ctx, "/tmp/test.txt"); err != nil {
		log.Fatal(err)
	}

	if err := client.Close(); err != nil {
		log.Fatal(err)
	}
}
Example (Rename)

Code:

{
	ctx := context.Background()
	const username = "gopher"
	client, err := NewClient(ctx, "ccxrootdgotest.in2p3.fr:9001", username)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	if err := client.FS().Rename(ctx, "/tmp/old.txt", "/tmp/new.txt"); err != nil {
		log.Fatal(err)
	}

	if err := client.Close(); err != nil {
		log.Fatal(err)
	}
}
Example (Stat)

Code:

{
	ctx := context.Background()
	const username = "gopher"
	client, err := NewClient(ctx, "ccxrootdgotest.in2p3.fr:9001", username)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	info, err := client.FS().Stat(ctx, "/tmp/test.txt")
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("Name: %s, size: %d", info.Name(), info.Size())

	if err := client.Close(); err != nil {
		log.Fatal(err)
	}
}
Example (Truncate)

Code:

{
	ctx := context.Background()
	const username = "gopher"
	client, err := NewClient(ctx, "ccxrootdgotest.in2p3.fr:9001", username)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	if err := client.FS().Truncate(ctx, "/tmp/test.txt", 10); err != nil {
		log.Fatal(err)
	}

	if err := client.Close(); err != nil {
		log.Fatal(err)
	}
}
Example (VirtualStat)

Code:

{
	ctx := context.Background()
	const username = "gopher"
	client, err := NewClient(ctx, "ccxrootdgotest.in2p3.fr:9001", username)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	info, err := client.FS().VirtualStat(ctx, "/tmp/")
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("RW: %d%% is free", info.FreeRW)

	if err := client.Close(); err != nil {
		log.Fatal(err)
	}
}
Example (Write)

Code:

{
	ctx := context.Background()
	const username = "gopher"
	client, err := NewClient(ctx, "ccxrootdgotest.in2p3.fr:9001", username)
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	file, err := client.FS().Open(ctx, "/tmp/test.txt", xrdfs.OpenModeOwnerRead|xrdfs.OpenModeOwnerWrite, xrdfs.OpenOptionsOpenUpdate|xrdfs.OpenOptionsNew)
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close(ctx)

	if _, err := file.WriteAt([]byte("test"), 0); err != nil {
		log.Fatal(err)
	}

	if err := file.Sync(ctx); err != nil {
		log.Fatal(err)
	}

	if err := file.Close(ctx); err != nil {
		log.Fatal(err)
	}

	if err := client.Close(); err != nil {
		log.Fatal(err)
	}
}

func NewClient

func NewClient(ctx context.Context, address string, username string, opts ...Option) (*Client, error)

NewClient creates a new xrootd client that connects to the given address using username. Options opts configure the client and are applied in the order they were specified. When the context expires, a response handling is stopped, however, it is necessary to call Cancel to correctly free resources.

func (*Client) Close

func (client *Client) Close() error

Close closes the connection. Any blocked operation will be unblocked and return error.

func (*Client) FS

func (cli *Client) FS() xrdfs.FileSystem

FS returns a xrdfs.FileSystem which uses this client to make requests.

func (*Client) Send

func (client *Client) Send(ctx context.Context, resp xrdproto.Response, req xrdproto.Request) (string, error)

Send sends the request to the server and stores the response inside the resp. If the resp is nil, then no response is stored. Send returns a session id which identifies the server that provided response.

type ErrorHandler

type ErrorHandler func(error)

ErrorHandler is the function which handles occurred error (e.g. logs it).

type Handler

type Handler interface {
	// Handshake handles the XRootD handshake: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248784.
	Handshake() (xrdproto.Marshaler, xrdproto.ResponseStatus)

	// Login handles the XRootD login request: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248819.
	Login(sessionID [16]byte, request *login.Request) (xrdproto.Marshaler, xrdproto.ResponseStatus)

	// Protocol handles the XRootD protocol request: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248827.
	Protocol(sessionID [16]byte, request *protocol.Request) (xrdproto.Marshaler, xrdproto.ResponseStatus)

	// Ping handles the XRootD ping request: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248825.
	Ping(sessionID [16]byte, request *ping.Request) (xrdproto.Marshaler, xrdproto.ResponseStatus)

	// Dirlist handles the XRootD dirlist request: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248815.
	Dirlist(sessionID [16]byte, request *dirlist.Request) (xrdproto.Marshaler, xrdproto.ResponseStatus)

	// CloseSession handles the aborting of user session. This can be used to free some user-related data.
	CloseSession(sessionID [16]byte) error

	// Open handles the XRootD open request: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248823.
	Open(sessionID [16]byte, request *open.Request) (xrdproto.Marshaler, xrdproto.ResponseStatus)

	// Close handles the XRootD close request: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248813.
	Close(sessionID [16]byte, request *xrdclose.Request) (xrdproto.Marshaler, xrdproto.ResponseStatus)

	// Read handles the XRootD read request: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248841.
	Read(sessionID [16]byte, request *read.Request) (xrdproto.Marshaler, xrdproto.ResponseStatus)

	// Write handles the XRootD write request: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248855.
	Write(sessionID [16]byte, request *write.Request) (xrdproto.Marshaler, xrdproto.ResponseStatus)

	// Stat handles the XRootD stat request: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248850.
	Stat(sessionID [16]byte, request *stat.Request) (xrdproto.Marshaler, xrdproto.ResponseStatus)

	// Sync handles the XRootD sync request: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248852.
	Sync(sessionID [16]byte, request *sync.Request) (xrdproto.Marshaler, xrdproto.ResponseStatus)

	// Truncate handles the XRootD truncate request: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248853.
	Truncate(sessionID [16]byte, request *truncate.Request) (xrdproto.Marshaler, xrdproto.ResponseStatus)

	// Rename handles the XRootD mv request: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248822.
	Rename(sessionID [16]byte, request *mv.Request) (xrdproto.Marshaler, xrdproto.ResponseStatus)

	// Mkdir handles the XRootD mkdir request: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248821.
	Mkdir(sessionID [16]byte, request *mkdir.Request) (xrdproto.Marshaler, xrdproto.ResponseStatus)

	// Remove handles the XRootD rm request: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248843.
	Remove(sessionID [16]byte, request *rm.Request) (xrdproto.Marshaler, xrdproto.ResponseStatus)

	// RemoveDir handles the XRootD rmdir request: http://xrootd.org/doc/dev45/XRdv310.htm#_Toc464248844.
	RemoveDir(sessionID [16]byte, request *rmdir.Request) (xrdproto.Marshaler, xrdproto.ResponseStatus)
}

Handler provides a high-level API for the XRootD server. The Handler receives a parsed request and returns a response together with the status that will be send via Server to the client.

func Default

func Default() Handler

Default returns the defaultHandler implementing Handler with some general functionality added. Any unimplemented request returns InvalidRequest error.

func NewFSHandler

func NewFSHandler(basePath string) Handler

NewFSHandler creates a Handler that passes requests to the backing filesystem at basePath.

type Option

type Option func(*Client) error

Option configures an XRootD client.

func WithAuth

func WithAuth(a auth.Auther) Option

WithAuth adds an authentication mechanism to the XRootD client. If an authentication mechanism was already registered for that provider, it will be silently replaced.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server implements the XRootD server following protocol from http://xrootd.org. The Server uses a Handler to handle incoming requests. To listen for incoming connections, Serve method must be called. It is possible to configure to listen on several ports simultaneously by calling Serve with different net.Listeners.

Example

Code:play 

package main

import (
	"log"
	"net"

	"go-hep.org/x/hep/xrootd"
)

func main() {
	addr := "0.0.0.0:1094"
	listener, err := net.Listen("tcp", addr)
	if err != nil {
		log.Fatalf("could not listen on %q: %v", addr, err)
	}

	srv := xrootd.NewServer(xrootd.Default(), func(err error) {
		log.Printf("an error occured: %v", err)
	})

	log.Printf("listening on %v...", listener.Addr())

	if err = srv.Serve(listener); err != nil {
		log.Fatalf("could not serve: %v", err)
	}
}

func NewServer

func NewServer(handler Handler, errorHandler ErrorHandler) *Server

NewServer creates a XRootD server which uses specified handler to handle requests and errorHandler to handle errors. If the errorHandler is nil, then a default error handler is used that does nothing.

func (*Server) Serve

func (s *Server) Serve(l net.Listener) error

Serve accepts incoming connections on the Listener l, creating a new service goroutine for each. The service goroutines read requests and then call s.handler to handle them.

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

Shutdown stops Server and closes all listeners and active connections. Shutdown returns the first non nil error while closing listeners and connections.

Source Files

auth.go bind.go client.go default_handler.go file.go filesystem.go fshandler.go handler.go handshake.go login.go ping.go port.go protocol.go server.go session.go xrootd.go

Directories

PathSynopsis
xrootd/cmd
xrootd/cmd/xrd-clientCommand xrd-client provides access to data hosted on XRootD clusters.
xrootd/cmd/xrd-cpCommand xrd-cp copies files and directories from a remote xrootd server to local storage.
xrootd/cmd/xrd-lsCommand xrd-ls lists directory contents on a remote xrootd server.
xrootd/cmd/xrd-srvCommand xrd-srv serves data from a local filesystem over the XRootD protocol.
xrootd/internal
xrootd/xrdfsPackage xrdfs contains structures representing the XRootD-based filesystem.
xrootd/xrdioPackage xrdio provides a File type that implements various interfaces from the io package.
xrootd/xrdprotoPackage protocol contains the XRootD protocol specific types and methods to handle them, such as marshalling and unmarshalling requests.
xrootd/xrdproto/adminPackage admin contains the types related to the admin request.
xrootd/xrdproto/authPackage auth contains the structures describing auth request.
xrootd/xrdproto/auth/hostPackage host contains the implementation for the "host" security provider.
xrootd/xrdproto/auth/krb5Package krb5 contains the implementation of krb5 (Kerberos) security provider.
xrootd/xrdproto/auth/unixPackage unix contains the implementation of unix security provider.
xrootd/xrdproto/bindPackage bind contains the structures describing bind request and response.
xrootd/xrdproto/chmodPackage chmod contains the structures describing chmod request.
xrootd/xrdproto/decryptPackage decrypt contains the types related to the decrypt request.
xrootd/xrdproto/dirlistPackage dirlist contains the structures describing request and response for dirlist request used to obtain the contents of a directory.
xrootd/xrdproto/endsessPackage endsess contains the types related to the endsess request.
xrootd/xrdproto/handshakePackage handshake contains the structures describing request and response for handshake request (see XRootD specification).
xrootd/xrdproto/locatePackage locate contains the types related to the locate request.
xrootd/xrdproto/loginPackage login contains the structures describing request and response for login request.
xrootd/xrdproto/mkdirPackage mkdir contains the structures describing mkdir request.
xrootd/xrdproto/mvPackage mv contains the structures describing mv request.
xrootd/xrdproto/openPackage open contains the structures describing request and response for open request.
xrootd/xrdproto/pingPackage ping contains the structures describing ping request.
xrootd/xrdproto/preparePackage prepare contains the types related to the prepare request.
xrootd/xrdproto/protocolPackage protocol contains the structures describing request and response for protocol request (see XRootD specification).
xrootd/xrdproto/queryPackage query contains the types related to the query request.
xrootd/xrdproto/readPackage read contains the structures describing request and response for read request.
xrootd/xrdproto/rmPackage rm contains the structures describing rm request.
xrootd/xrdproto/rmdirPackage rmdir contains the structures describing rmdir request.
xrootd/xrdproto/signingPackage signing contains implementation of a way to check if request should be signed according to XRootD protocol specification v.
xrootd/xrdproto/sigverPackage sigver contains the structures describing sigver request.
xrootd/xrdproto/statPackage stat contains the structures describing request and response for stat request.
xrootd/xrdproto/statxPackage statx contains the structures describing request and response for statx request.
xrootd/xrdproto/syncPackage sync contains the structures describing sync request.
xrootd/xrdproto/truncatePackage truncate contains the structures describing truncate request.
xrootd/xrdproto/verifywPackage verifyw contains the structures describing verifyw request.
xrootd/xrdproto/writePackage write contains the structures describing write request.
xrootd/xrdproto/xrdclosePackage xrdclose contains the structures describing request and response for close request.
Version
v0.36.0 (latest)
Published
Nov 15, 2024
Platform
linux/amd64
Imports
44 packages
Last checked
1 day ago

Tools for package owners.