1
1
package ebutil
2
2
3
3
import (
4
+ "errors"
4
5
"fmt"
5
6
"os"
6
7
"path/filepath"
@@ -44,15 +45,36 @@ func tempRemount(m mounter, logf func(notcodersdk.LogLevel, string, ...any), bas
44
45
return func () error { return nil }, fmt .Errorf ("get mounts: %w" , err )
45
46
}
46
47
48
+ libDir , err := libraryDirectoryPath (m )
49
+ if err != nil {
50
+ return func () error { return nil }, fmt .Errorf ("get lib directory: %w" , err )
51
+ }
52
+
53
+ libsSymlinks , err := libraryDirectorySymlinks (m , libDir )
54
+ if err != nil && ! errors .Is (err , os .ErrNotExist ) {
55
+ return func () error { return nil }, fmt .Errorf ("read lib symlinks: %w" , err )
56
+ }
57
+
47
58
// temp move of all ro mounts
48
59
mounts := map [string ]string {}
49
60
var restoreOnce sync.Once
50
61
var merr error
51
62
// closer to attempt to restore original mount points
52
63
restore = func () error {
53
64
restoreOnce .Do (func () {
65
+ if len (mounts ) == 0 {
66
+ return
67
+ }
68
+
69
+ newLibDir , err := libraryDirectoryPath (m )
70
+ if err != nil {
71
+ merr = multierror .Append (merr , fmt .Errorf ("get new lib directory: %w" , err ))
72
+ return
73
+ }
74
+
54
75
for orig , moved := range mounts {
55
- if err := remount (m , moved , orig ); err != nil {
76
+ logf (notcodersdk .LogLevelTrace , "restore mount %s" , orig )
77
+ if err := remount (m , moved , orig , newLibDir , libsSymlinks ); err != nil {
56
78
merr = multierror .Append (merr , fmt .Errorf ("restore mount: %w" , err ))
57
79
}
58
80
}
77
99
78
100
src := mountInfo .MountPoint
79
101
dest := filepath .Join (base , src )
80
- if err := remount (m , src , dest ); err != nil {
102
+ logf (notcodersdk .LogLevelTrace , "temp remount %s" , src )
103
+ if err := remount (m , src , dest , libDir , libsSymlinks ); err != nil {
81
104
return restore , fmt .Errorf ("temp remount: %w" , err )
82
105
}
83
106
@@ -87,30 +110,48 @@ outer:
87
110
return restore , nil
88
111
}
89
112
90
- func remount (m mounter , src , dest string ) error {
113
+ func remount (m mounter , src , dest , libDir string , libsSymlinks map [ string ][] string ) error {
91
114
stat , err := m .Stat (src )
92
115
if err != nil {
93
116
return fmt .Errorf ("stat %s: %w" , src , err )
94
117
}
118
+
95
119
var destDir string
96
120
if stat .IsDir () {
97
121
destDir = dest
98
122
} else {
99
123
destDir = filepath .Dir (dest )
124
+ if destDir == usrLibDir || destDir == usrLibMultiarchDir {
125
+ // Restore mount to libDir
126
+ destDir = libDir
127
+ dest = filepath .Join (destDir , stat .Name ())
128
+ }
100
129
}
130
+
101
131
if err := m .MkdirAll (destDir , 0o750 ); err != nil {
102
132
return fmt .Errorf ("ensure path: %w" , err )
103
133
}
134
+
104
135
if ! stat .IsDir () {
105
136
f , err := m .OpenFile (dest , os .O_CREATE , 0o640 )
106
137
if err != nil {
107
138
return fmt .Errorf ("ensure file path: %w" , err )
108
139
}
109
- defer f .Close ()
140
+ // This ensure the file is created, it will not be used. It can be closed immediately.
141
+ f .Close ()
142
+
143
+ if symlinks , ok := libsSymlinks [stat .Name ()]; ok {
144
+ srcDir := filepath .Dir (src )
145
+ if err := moveLibSymlinks (m , symlinks , srcDir , destDir ); err != nil {
146
+ return err
147
+ }
148
+ }
110
149
}
150
+
111
151
if err := m .Mount (src , dest , "bind" , syscall .MS_BIND , "" ); err != nil {
112
152
return fmt .Errorf ("bind mount %s => %s: %w" , src , dest , err )
113
153
}
154
+
114
155
if err := m .Unmount (src , 0 ); err != nil {
115
156
return fmt .Errorf ("unmount orig src %s: %w" , src , err )
116
157
}
@@ -131,6 +172,12 @@ type mounter interface {
131
172
Mount (string , string , string , uintptr , string ) error
132
173
// Unmount wraps syscall.Unmount
133
174
Unmount (string , int ) error
175
+ // ReadDir wraps os.ReadDir
176
+ ReadDir (string ) ([]os.DirEntry , error )
177
+ // EvalSymlinks wraps filepath.EvalSymlinks
178
+ EvalSymlinks (string ) (string , error )
179
+ // Rename wraps os.Rename
180
+ Rename (string , string ) error
134
181
}
135
182
136
183
// realMounter implements mounter and actually does the thing.
@@ -161,3 +208,15 @@ func (m *realMounter) OpenFile(name string, flag int, perm os.FileMode) (*os.Fil
161
208
func (m * realMounter ) Stat (path string ) (os.FileInfo , error ) {
162
209
return os .Stat (path )
163
210
}
211
+
212
+ func (m * realMounter ) ReadDir (name string ) ([]os.DirEntry , error ) {
213
+ return os .ReadDir (name )
214
+ }
215
+
216
+ func (m * realMounter ) EvalSymlinks (path string ) (string , error ) {
217
+ return filepath .EvalSymlinks (path )
218
+ }
219
+
220
+ func (m * realMounter ) Rename (oldpath , newpath string ) error {
221
+ return os .Rename (oldpath , newpath )
222
+ }
0 commit comments