filed

Job queue using FUSE

git clone git://mccd.space/filed

newid.go (1931B)

      1 package main
      2 
      3 import (
      4 	"context"
      5 	"git.sr.ht/~marcc/filed/store"
      6 	"log/slog"
      7 	"math/rand"
      8 	"os"
      9 	"syscall"
     10 	"time"
     11 
     12 	"bazil.org/fuse"
     13 )
     14 
     15 var NewIdName = "new-id"
     16 
     17 // Helper function to get a unique 4 character ID
     18 func randomJobId(store *store.Store, characters int) []byte {
     19 	const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
     20 	rand.New(rand.NewSource(time.Now().UnixNano()))
     21 	result := make([]byte, characters)
     22 	for i := range result {
     23 		result[i] = charset[rand.Intn(len(charset))]
     24 	}
     25 	_, err := store.GetJob(string(result))
     26 	if err == os.ErrNotExist {
     27 		return result
     28 	} else {
     29 		// In the unlikely event
     30 		return randomJobId(store, characters+1)
     31 	}
     32 }
     33 
     34 type NewIdFile struct {
     35 	manager *JobManager
     36 	inode   uint64
     37 }
     38 
     39 func (f NewIdFile) Attr(ctx context.Context, a *fuse.Attr) error {
     40 	fileMeta, err := f.manager.store.GetFileMeta(f.inode)
     41 	if err != nil {
     42 		slog.Error("Could not retrieve file metadata", "error", err)
     43 		return syscall.EIO
     44 	} else if fileMeta != nil {
     45 		slog.Info("Found file meta")
     46 		a.Mode = os.FileMode(fileMeta.Mode)
     47 		a.Gid = fileMeta.GID
     48 		a.Uid = fileMeta.UID
     49 	} else {
     50 		a.Mode = 0o440
     51 		a.Gid = uint32(os.Getgid())
     52 		a.Uid = uint32(os.Getuid())
     53 	}
     54 	a.Inode = f.inode
     55 	a.Size = uint64(16)
     56 
     57 	return nil
     58 }
     59 func (f *NewIdFile) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) error {
     60 	slog.Warn("FUSE: Changing access permissions")
     61 	defaultMode, err := f.manager.store.GetFileMeta(f.inode)
     62 	if err != nil {
     63 		return err
     64 	}
     65 	if defaultMode == nil {
     66 		defaultMode = &store.FileMeta{
     67 			Inode: f.inode,
     68 			Mode:  uint32(0o440),
     69 			UID:   uint32(os.Getgid()),
     70 			GID:   uint32(os.Getuid()),
     71 		}
     72 
     73 	}
     74 	resp.Attr.Size = uint64(4)
     75 	return Setattr(f.manager.store, defaultMode, ctx, req, resp)
     76 }
     77 
     78 func (f *NewIdFile) ReadAll(ctx context.Context) ([]byte, error) {
     79 	slog.Debug("FUSE: Read file content")
     80 	return randomJobId(f.manager.store, 4), nil
     81 }