Skip to content

Commit 532ee3d

Browse files
authored
custom x11 config feature (#123)
* move version string code to re-usable method * remove unnecessary todo comment * add possibility to use custom x11 config template, #114, #42 * add permission check for custom x11 template and print warning * update github actions
1 parent ef54519 commit 532ee3d

File tree

10 files changed

+113
-58
lines changed

10 files changed

+113
-58
lines changed

.github/workflows/aur-release.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
steps:
2323

2424
- name: Checkout
25-
uses: actions/checkout@v2
25+
uses: actions/checkout@v4
2626

2727
- name: Download binary
2828
uses: actions/[email protected]
@@ -37,13 +37,13 @@ jobs:
3737
run: ./.ci/generate-pkgbuild.sh ${{ inputs.version }} ${{ env.SHA256 }}
3838

3939
- name: Upload egpu-switcher PKGBUILD
40-
uses: actions/upload-artifact@v3
40+
uses: actions/upload-artifact@v4
4141
with:
4242
name: egpu-switcher-PKGBUILD
4343
path: ./.pkgbuild/egpu-switcher/*
4444

4545
- name: Upload egpu-switcher-bin PKGBUILD
46-
uses: actions/upload-artifact@v3
46+
uses: actions/upload-artifact@v4
4747
with:
4848
name: egpu-switcher-bin-PKGBUILD
4949
path: ./.pkgbuild/egpu-switcher-bin/*

.github/workflows/github-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
steps:
1616

1717
- name: Checkout
18-
uses: actions/checkout@v2
18+
uses: actions/checkout@v4
1919

2020
- uses: actions/[email protected]
2121
with:

.github/workflows/go-build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ jobs:
2525
steps:
2626

2727
- name: Checkout
28-
uses: actions/checkout@v2
28+
uses: actions/checkout@v4
2929
with:
3030
# without that 'git describe --tags' may result
3131
# in 'fatal: No names found, cannot describe anything.'
3232
# see https://stackoverflow.com/a/71721059/2726733
3333
fetch-depth: 0
3434

3535
- name: Setup go
36-
uses: actions/setup-go@v3
36+
uses: actions/setup-go@v5
3737
with:
3838
go-version: ${{ inputs.go-version }}
3939
cache: true
@@ -45,7 +45,7 @@ jobs:
4545
run: sha256sum ./bin/${{ env.BINARY_NAME }} > ./bin/sha256sum.txt || exit $?
4646

4747
- name: Upload binary
48-
uses: actions/upload-artifact@v3
48+
uses: actions/upload-artifact@v4
4949
with:
5050
name: ${{ env.BINARY_NAME }}
5151
path: ./bin/*

.github/workflows/go-test.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ jobs:
1515
steps:
1616

1717
- name: Checkout
18-
uses: actions/checkout@v2
18+
uses: actions/checkout@v4
1919

2020
- name: Setup go
21-
uses: actions/setup-go@v3
21+
uses: actions/setup-go@v5
2222
with:
2323
go-version: ${{ inputs.go-version }}
2424
cache: true
@@ -32,10 +32,10 @@ jobs:
3232
steps:
3333

3434
- name: Checkout
35-
uses: actions/checkout@v2
35+
uses: actions/checkout@v4
3636

3737
- name: Setup go
38-
uses: actions/setup-go@v3
38+
uses: actions/setup-go@v5
3939
with:
4040
go-version: ${{ inputs.go-version }}
4141
cache: true

.github/workflows/new-issue.yml

Lines changed: 0 additions & 19 deletions
This file was deleted.

cmd/enable.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ var setupCommand = &cobra.Command{
2828
return err
2929
}
3030

31-
// todo: trigger config if no config exists (unless --no-prompt is used)
31+
// trigger config if no config exists (unless --no-prompt is used)
3232
egpuId := viper.GetInt("egpu.id")
3333
if egpuId == 0 {
3434
logger.Info("no eGPU has been configured yet")

cmd/switch.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,15 +143,22 @@ func switchEgpu(gpu *pci.GPU) error {
143143
}
144144

145145
nomodesetting = nomodesetting || viper.GetBool("egpu.nomodesetting")
146-
conf := xorg.RenderConf("Device0", driver, gpu.XorgPCIString(), !nomodesetting)
146+
147+
conf, _, err := xorg.RenderConf("Device0", driver, gpu.XorgPCIString(), !nomodesetting, verbose)
148+
if err != nil {
149+
return err
150+
}
151+
147152
if err := xorg.CreateEgpuFile(x11ConfPath, conf, verbose); err != nil {
148153
return err
149154
}
155+
150156
if post := viper.GetString("hooks.egpu"); post != "" {
151157
if err := runHook(post); err != nil {
152158
logger.Error("egpu hook error: %s", err)
153159
}
154160
}
161+
155162
return nil
156163
}
157164

cmd/version.go

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,7 @@ var versionCmd = &cobra.Command{
1313
Use: "version",
1414
Short: "Print version information",
1515
RunE: func(cmd *cobra.Command, args []string) error {
16-
17-
version := buildinfo.Version
18-
if version == "" {
19-
version = "unknown"
20-
}
21-
22-
if full {
23-
buildtime := buildinfo.BuildTime
24-
if buildtime == "" {
25-
buildtime = "unknown"
26-
}
27-
origin := buildinfo.Origin
28-
if origin == "" {
29-
origin = "unknown"
30-
}
31-
fmt.Printf("%s_%s_%s\n", version, buildtime, origin)
32-
return nil
33-
}
34-
35-
fmt.Println(version)
16+
fmt.Println(buildinfo.VersionString(full))
3617
return nil
3718
},
3819
}

internal/buildinfo/version.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package buildinfo
2+
3+
import "fmt"
4+
5+
func VersionString(full bool) string {
6+
version := Version
7+
if version == "" {
8+
version = "unknown"
9+
}
10+
11+
if full {
12+
buildtime := BuildTime
13+
if buildtime == "" {
14+
buildtime = "unknown"
15+
}
16+
origin := Origin
17+
if origin == "" {
18+
origin = "unknown"
19+
}
20+
return fmt.Sprintf("%s_%s_%s", version, buildtime, origin)
21+
}
22+
23+
return version
24+
}

internal/xorg/conf.go

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@ package xorg
33
import (
44
"bytes"
55
_ "embed"
6+
"errors"
67
"fmt"
7-
"html/template"
8+
"io"
89
"os"
10+
"syscall"
11+
"text/template"
912

1013
"github.com/hertg/egpu-switcher/internal/logger"
1114
)
1215

1316
//go:embed conf.template
14-
var confTemplate string
17+
var embeddedTemplate string
18+
var templatePath = "/usr/share/egpu-switcher/x11-template.conf"
1519

1620
func RemoveEgpuFile(path string, verbose bool) error {
1721
f, _ := os.Stat(path)
@@ -44,7 +48,7 @@ func CreateEgpuFile(path string, contents string, verbose bool) error {
4448
return nil
4549
}
4650

47-
func RenderConf(id string, driver string, busid string, modesetting bool) string {
51+
func RenderConf(id string, driver string, busid string, modesetting bool, verbose bool) (string, bool, error) {
4852

4953
type conf struct {
5054
Id string
@@ -60,12 +64,70 @@ func RenderConf(id string, driver string, busid string, modesetting bool) string
6064
Modesetting: modesetting,
6165
}
6266

63-
buf := bytes.NewBuffer(nil)
67+
customTemplatePermissionCheck()
68+
69+
confTemplate, isCustom := templateString(verbose)
6470
t := template.Must(template.New("conf").Parse(confTemplate))
71+
buf := bytes.NewBuffer(nil)
6572
err := t.Execute(buf, c)
6673
if err != nil {
67-
panic(err)
74+
return "", isCustom, err
75+
}
76+
77+
return buf.String(), isCustom, nil
78+
}
79+
80+
func templateString(verbose bool) (string, bool) {
81+
var confTemplate string
82+
templateFile, err := os.OpenFile(templatePath, os.O_RDONLY, 0644)
83+
isCustom := false
84+
if err != nil {
85+
if !errors.Is(err, os.ErrNotExist) {
86+
// if we get an error, other than "not exists", print an error
87+
// the "not exists" error is an expected outcome when the config file is not customized
88+
logger.Error("unable to open custom x11 config template, using default template instead")
89+
}
90+
if verbose {
91+
logger.Debug("using default template for x11 conf")
92+
}
93+
confTemplate = embeddedTemplate
94+
} else {
95+
if verbose {
96+
logger.Debug("using custom template at '%s' for x11 conf", templatePath)
97+
}
98+
var buf bytes.Buffer
99+
io.Copy(&buf, templateFile)
100+
confTemplate = buf.String()
101+
isCustom = true
102+
}
103+
return confTemplate, isCustom
104+
}
105+
106+
func customTemplatePermissionCheck() {
107+
logWarn := false
108+
info, err := os.Stat(templatePath)
109+
if err != nil {
110+
logger.Error("%s", err)
111+
return
68112
}
113+
if stat, ok := info.Sys().(*syscall.Stat_t); ok {
114+
if stat.Uid != 0 {
115+
logger.Warn("the custom x11 config template is not owned by root user")
116+
logWarn = true
117+
}
118+
if stat.Gid != 0 {
119+
logger.Warn("the custom x11 config template is not owned by root group")
120+
logWarn = true
121+
}
69122

70-
return buf.String()
123+
otherPerm := info.Mode().Perm() & 0x007
124+
if otherPerm&0x2 != 0 {
125+
logger.Warn("the custom x11 config template is writable by other")
126+
logWarn = true
127+
}
128+
}
129+
if logWarn {
130+
logger.Warn("ensure that the custom x11 config template at '%s' is not writable by unauthorized users."+
131+
"this could pose a security risk. file should be owned by root:root and have a file permission of 644", templatePath)
132+
}
71133
}

0 commit comments

Comments
 (0)