Skip to content

Commit 93bee6f

Browse files
committed
Merge open PR's
Merge jstaf#402 jstaf#403 jstaf#418 jstaf#420 + version++
1 parent 578dd8f commit 93bee6f

23 files changed

Lines changed: 487 additions & 154 deletions

Dockerfile

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FROM golang:bookworm
2+
3+
ENV DEBIAN_FRONTEND=noninteractive
4+
RUN apt update && apt -y install build-essential fuse
5+
6+
RUN groupadd onedriver
7+
RUN useradd -g onedriver -ms /bin/bash onedriver
8+
RUN mkdir /mount && chown onedriver:onedriver -R /mount
9+
10+
USER onedriver
11+
RUN mkdir -p /home/onedriver/.cache/onedriver
12+
VOLUME [ "/home/onedriver/.cache/onedriver" ]
13+
WORKDIR /build
14+
COPY --chown=onedriver:onedriver . .
15+
RUN make onedriver-headless
16+
17+
ENTRYPOINT [ "/build/onedriver-headless", "--no-browser", "/mount/" ]

cmd/common/common.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
"github.com/rs/zerolog/log"
1313
)
1414

15-
const version = "0.14.1"
15+
const version = "0.14.2"
1616

1717
var commit string
1818

cmd/common/config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"os"
66
"path/filepath"
77

8-
"github.com/imdario/mergo"
8+
"dario.cat/mergo"
99
"github.com/jstaf/onedriver/fs/graph"
1010
"github.com/jstaf/onedriver/ui"
1111
"github.com/rs/zerolog/log"

cmd/onedriver-launcher/main.go

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,14 @@ func activateCallback(app *gtk.Application, config *common.Config, configPath st
9191

9292
header, _ := gtk.HeaderBarNew()
9393
header.SetShowCloseButton(true)
94-
header.SetTitle("onedriver")
94+
header.SetTitle("OneDriver")
9595
window.SetTitlebar(header)
9696

97+
err := window.SetIconFromFile("/usr/share/icons/onedriver/onedriver.svg")
98+
if err != nil {
99+
log.Error().Err(err).Msg("Could not find logo.")
100+
}
101+
97102
listbox, _ := gtk.ListBoxNew()
98103
window.Add(listbox)
99104

@@ -148,7 +153,7 @@ func activateCallback(app *gtk.Application, config *common.Config, configPath st
148153
settings, _ := gtk.ModelButtonNew()
149154
settings.SetLabel("Settings")
150155
settings.Connect("clicked", func(button *gtk.ModelButton) {
151-
newSettingsWindow(config, configPath)
156+
newSettingsDialog(config, configPath, window)
152157
})
153158
popoverBox.PackStart(settings, false, true, 0)
154159

@@ -157,6 +162,7 @@ func activateCallback(app *gtk.Application, config *common.Config, configPath st
157162
about.SetLabel("About")
158163
about.Connect("clicked", func(button *gtk.ModelButton) {
159164
aboutDialog, _ := gtk.AboutDialogNew()
165+
aboutDialog.SetProgramName("OneDriver Launcher")
160166
aboutDialog.SetAuthors([]string{"Jeff Stafford", "https://github.com/jstaf"})
161167
aboutDialog.SetWebsite("https://github.com/jstaf/onedriver")
162168
aboutDialog.SetWebsiteLabel("github.com/jstaf/onedriver")
@@ -168,6 +174,8 @@ func activateCallback(app *gtk.Application, config *common.Config, configPath st
168174
} else {
169175
aboutDialog.SetLogo(logo.GetPixbuf())
170176
}
177+
aboutDialog.SetTransientFor(window)
178+
aboutDialog.Connect("response", aboutDialog.Destroy)
171179
aboutDialog.Run()
172180
})
173181
popoverBox.PackStart(about, false, true, 0)
@@ -317,7 +325,7 @@ func newMountRow(config common.Config, mount string) (*gtk.ListBoxRow, *gtk.Swit
317325
}
318326
// rename the mount by rewriting the .xdg-volume-info file
319327
renameMountpointEntry, _ := gtk.EntryNew()
320-
renameMountpointEntry.SetTooltipText("Change the label that your file browser uses for this drive")
328+
renameMountpointEntry.SetTooltipText("The label that your file browser uses for this drive")
321329
renameMountpointEntry.SetText(driveName)
322330
// runs on enter
323331
renameMountpointEntry.Connect("activate", func(entry *gtk.Entry) {
@@ -374,7 +382,7 @@ func newMountRow(config common.Config, mount string) (*gtk.ListBoxRow, *gtk.Swit
374382
popoverBox.Add(separator)
375383

376384
// create a button to enable/disable the mountpoint
377-
unitEnabledBtn, _ := gtk.CheckButtonNewWithLabel(" Start drive on login")
385+
unitEnabledBtn, _ := gtk.CheckButtonNewWithLabel("Start Drive on Login")
378386
unitEnabledBtn.SetTooltipText("Start this drive automatically when you login")
379387
enabled, err := systemd.UnitIsEnabled(unitName)
380388
if err == nil {
@@ -401,7 +409,7 @@ func newMountRow(config common.Config, mount string) (*gtk.ListBoxRow, *gtk.Swit
401409

402410
// button to delete the mount
403411
deleteMountpointBtn, _ := gtk.ModelButtonNew()
404-
deleteMountpointBtn.SetLabel("Remove drive")
412+
deleteMountpointBtn.SetLabel("Remove Drive")
405413
deleteMountpointBtn.SetTooltipText("Remove OneDrive account from local computer")
406414
deleteMountpointBtn.Connect("clicked", func(button *gtk.ModelButton) {
407415
log.Trace().
@@ -444,16 +452,16 @@ func newMountRow(config common.Config, mount string) (*gtk.ListBoxRow, *gtk.Swit
444452
return row, mountToggle
445453
}
446454

447-
func newSettingsWindow(config *common.Config, configPath string) {
455+
func newSettingsDialog(config *common.Config, configPath string, parent gtk.IWindow) {
448456
const offset = 15
449457

450-
settingsWindow, _ := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
451-
settingsWindow.SetResizable(false)
452-
settingsWindow.SetTitle("Settings")
458+
settingsDialog, _ := gtk.DialogNew()
459+
settingsDialog.SetResizable(false)
460+
settingsDialog.SetTitle("Settings")
453461

454462
// log level settings
455463
settingsRowLog, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, offset)
456-
logLevelLabel, _ := gtk.LabelNew("Log level")
464+
logLevelLabel, _ := gtk.LabelNew("Log Level")
457465
settingsRowLog.PackStart(logLevelLabel, false, false, 0)
458466

459467
logLevelSelector, _ := gtk.ComboBoxTextNew()
@@ -475,7 +483,7 @@ func newSettingsWindow(config *common.Config, configPath string) {
475483

476484
// cache dir settings
477485
settingsRowCacheDir, _ := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, offset)
478-
cacheDirLabel, _ := gtk.LabelNew("Cache directory")
486+
cacheDirLabel, _ := gtk.LabelNew("Cache Directory")
479487
settingsRowCacheDir.PackStart(cacheDirLabel, false, false, 0)
480488

481489
cacheDirPicker, _ := gtk.ButtonNew()
@@ -485,7 +493,7 @@ func newSettingsWindow(config *common.Config, configPath string) {
485493
oldPath, _ := button.GetLabel()
486494
oldPath = ui.UnescapeHome(oldPath)
487495
path := ui.DirChooser("Select an empty directory to use for storage")
488-
if !ui.CancelDialog(settingsWindow, "Remount all drives?", "") {
496+
if !ui.CancelDialog(settingsDialog, "Remount all drives?", "") {
489497
return
490498
}
491499
log.Warn().
@@ -508,7 +516,7 @@ func newSettingsWindow(config *common.Config, configPath string) {
508516
err := systemd.UnitSetActive(unitName, false)
509517
if err != nil {
510518
ui.Dialog("Could not disable mount: "+err.Error(),
511-
gtk.MESSAGE_ERROR, settingsWindow)
519+
gtk.MESSAGE_ERROR, settingsDialog)
512520
log.Error().
513521
Err(err).
514522
Str("mount", mount).
@@ -520,7 +528,7 @@ func newSettingsWindow(config *common.Config, configPath string) {
520528
err = os.Rename(filepath.Join(oldPath, mount), filepath.Join(path, mount))
521529
if err != nil {
522530
ui.Dialog("Could not move cache for mount: "+err.Error(),
523-
gtk.MESSAGE_ERROR, settingsWindow)
531+
gtk.MESSAGE_ERROR, settingsDialog)
524532
log.Error().
525533
Err(err).
526534
Str("mount", mount).
@@ -549,10 +557,20 @@ func newSettingsWindow(config *common.Config, configPath string) {
549557
settingsRowCacheDir.PackEnd(cacheDirPicker, false, false, 0)
550558

551559
// assemble rows
552-
settingsWindowBox, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, offset)
553-
settingsWindowBox.SetBorderWidth(offset)
554-
settingsWindowBox.PackStart(settingsRowLog, true, true, 0)
555-
settingsWindowBox.PackStart(settingsRowCacheDir, true, true, 0)
556-
settingsWindow.Add(settingsWindowBox)
557-
settingsWindow.ShowAll()
560+
settingsDialogBox, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, offset)
561+
settingsDialogBox.SetBorderWidth(offset)
562+
settingsDialogBox.PackStart(settingsRowLog, true, true, 0)
563+
settingsDialogBox.PackStart(settingsRowCacheDir, true, true, 0)
564+
565+
contentArea, err := settingsDialog.GetContentArea()
566+
if err != nil {
567+
log.Error().Err(err).Msg("Failed to get settings dialog content area.")
568+
return
569+
}
570+
571+
contentArea.Add(settingsDialogBox)
572+
573+
settingsDialog.SetModal(true)
574+
settingsDialog.SetTransientFor(parent)
575+
settingsDialog.ShowAll()
558576
}

cmd/onedriver/main.go

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
package main
22

33
import (
4-
"encoding/json"
54
"fmt"
65
"io/ioutil"
76
"os"
87
"os/signal"
98
"path/filepath"
10-
"strings"
119
"syscall"
1210
"time"
1311

@@ -60,6 +58,10 @@ func main() {
6058
versionFlag := flag.BoolP("version", "v", false, "Display program version.")
6159
debugOn := flag.BoolP("debug", "d", false, "Enable FUSE debug logging. "+
6260
"This logs communication between onedriver and the kernel.")
61+
allowOther := flag.BoolP("allow-other", "", false,
62+
"Allow access to the mount point for other users.")
63+
uid := flag.Uint32P("uid", "", uint32(os.Getuid()), "Owner uid of the mount point.")
64+
gid := flag.Uint32P("gid", "", uint32(os.Getgid()), "Owner gid of the mount point.")
6365
help := flag.BoolP("help", "h", false, "Displays this help message.")
6466
flag.Usage = usage
6567
flag.Parse()
@@ -125,13 +127,15 @@ func main() {
125127
// create the filesystem
126128
log.Info().Msgf("onedriver %s", common.Version())
127129
auth := graph.Authenticate(config.AuthConfig, authPath, *headless)
128-
filesystem := fs.NewFilesystem(auth, cachePath)
129-
go filesystem.DeltaLoop(30 * time.Second)
130+
filesystem := fs.NewFilesystem(auth, cachePath, fs.OptionOwner(*uid, *gid))
131+
go filesystem.DeltaLoop(10 * time.Minute)
130132
xdgVolumeInfo(filesystem, auth)
131133

132134
server, err := fuse.NewServer(filesystem, mountpoint, &fuse.MountOptions{
133135
Name: "onedriver",
134136
FsName: "onedriver",
137+
DirectMount: true,
138+
AllowOther: *allowOther,
135139
DisableXAttrs: true,
136140
MaxBackground: 1024,
137141
Debug: *debugOn,
@@ -153,34 +157,3 @@ func main() {
153157
Msg("Serving filesystem.")
154158
server.Serve()
155159
}
156-
157-
// xdgVolumeInfo createx .xdg-volume-info for a nice little onedrive logo in the
158-
// corner of the mountpoint and shows the account name in the nautilus sidebar
159-
func xdgVolumeInfo(filesystem *fs.Filesystem, auth *graph.Auth) {
160-
if child, _ := filesystem.GetPath("/.xdg-volume-info", auth); child != nil {
161-
return
162-
}
163-
log.Info().Msg("Creating .xdg-volume-info")
164-
user, err := graph.GetUser(auth)
165-
if err != nil {
166-
log.Error().Err(err).Msg("Could not create .xdg-volume-info")
167-
return
168-
}
169-
xdgVolumeInfo := common.TemplateXDGVolumeInfo(user.UserPrincipalName)
170-
171-
// just upload directly and shove it in the cache
172-
// (since the fs isn't mounted yet)
173-
resp, err := graph.Put(
174-
graph.ResourcePath("/.xdg-volume-info")+":/content",
175-
auth,
176-
strings.NewReader(xdgVolumeInfo),
177-
)
178-
if err != nil {
179-
log.Error().Err(err).Msg("Failed to write .xdg-volume-info")
180-
}
181-
root, _ := filesystem.GetPath("/", auth) // cannot fail
182-
inode := fs.NewInode(".xdg-volume-info", 0644, root)
183-
if json.Unmarshal(resp, &inode) == nil {
184-
filesystem.InsertID(inode.ID(), inode)
185-
}
186-
}

cmd/onedriver/xdg.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//go:build linux && cgo
2+
// +build linux,cgo
3+
4+
package main
5+
6+
import (
7+
"encoding/json"
8+
"strings"
9+
10+
"github.com/jstaf/onedriver/fs"
11+
"github.com/jstaf/onedriver/cmd/common"
12+
"github.com/jstaf/onedriver/fs/graph"
13+
"github.com/rs/zerolog/log"
14+
)
15+
16+
// xdgVolumeInfo createx .xdg-volume-info for a nice little onedrive logo in the
17+
// corner of the mountpoint and shows the account name in the nautilus sidebar
18+
func xdgVolumeInfo(filesystem *fs.Filesystem, auth *graph.Auth) {
19+
if child, _ := filesystem.GetPath("/.xdg-volume-info", auth); child != nil {
20+
return
21+
}
22+
log.Info().Msg("Creating .xdg-volume-info")
23+
user, err := graph.GetUser(auth)
24+
if err != nil {
25+
log.Error().Err(err).Msg("Could not create .xdg-volume-info")
26+
return
27+
}
28+
xdgVolumeInfo := common.TemplateXDGVolumeInfo(user.UserPrincipalName)
29+
30+
// just upload directly and shove it in the cache
31+
// (since the fs isn't mounted yet)
32+
resp, err := graph.Put(
33+
graph.ResourcePath("/.xdg-volume-info")+":/content",
34+
auth,
35+
strings.NewReader(xdgVolumeInfo),
36+
)
37+
if err != nil {
38+
log.Error().Err(err).Msg("Failed to write .xdg-volume-info")
39+
}
40+
root, _ := filesystem.GetPath("/", auth) // cannot fail
41+
inode := fs.NewInode(".xdg-volume-info", 0644, root)
42+
if json.Unmarshal(resp, &inode) == nil {
43+
filesystem.InsertID(inode.ID(), inode)
44+
}
45+
}

cmd/onedriver/xdg_headless.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//go:build !linux || !cgo
2+
// +build !linux !cgo
3+
4+
package main
5+
6+
import (
7+
"github.com/jstaf/onedriver/fs"
8+
"github.com/jstaf/onedriver/fs/graph"
9+
)
10+
11+
func xdgVolumeInfo(filesystem *fs.Filesystem, auth *graph.Auth) {
12+
return
13+
}

docker-run.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/env bash
2+
# Build and run in Docker. Run with privileges for FUSE and interactively for login.
3+
# Mount at $MOUNTPOINT on host, defaults to ~/Onedrive
4+
5+
set -e
6+
if [ -z "$(docker images -q onedriver 2> /dev/null)" ]; then
7+
docker build -t onedriver .
8+
fi
9+
MOUNT="${MOUNTPOINT:-"$HOME/Onedrive"}"
10+
echo Mounting at $MOUNT
11+
mkdir -p $MOUNT
12+
docker run -it \
13+
-v $MOUNT:/mount:rw,rshared \
14+
--device /dev/fuse \
15+
--cap-add SYS_ADMIN \
16+
--security-opt apparmor:unconfined \
17+
--restart unless-stopped \
18+
onedriver

0 commit comments

Comments
 (0)