|
5 | 5 | package grub2
|
6 | 6 |
|
7 | 7 | import (
|
| 8 | + "fmt" |
| 9 | + "github.com/godbus/dbus/v5" |
8 | 10 | "os"
|
9 | 11 | "os/exec"
|
10 | 12 | "strings"
|
11 | 13 | "sync"
|
12 | 14 | "syscall"
|
13 | 15 |
|
14 | 16 | "github.com/linuxdeepin/dde-daemon/grub_common"
|
| 17 | + "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.systemd1" |
15 | 18 | )
|
16 | 19 |
|
17 | 20 | const (
|
@@ -130,38 +133,74 @@ func (m *modifyManager) update(adjustTheme bool, adjustThemeLang string) {
|
130 | 133 | }
|
131 | 134 |
|
132 | 135 | logJobStart(logJobMkConfig)
|
133 |
| - err := runUpdateGrub() |
| 136 | + err := m.runUpdateGrubWithUnit() |
134 | 137 | if err != nil {
|
135 | 138 | logger.Warning("failed to make config:", err)
|
136 | 139 | }
|
137 | 140 | logJobEnd(logJobMkConfig, err)
|
138 | 141 | m.updateEnd()
|
139 | 142 | }
|
140 | 143 |
|
141 |
| -func runUpdateGrub() error { |
142 |
| - updateGrubPath, err := exec.LookPath(updateGrubCmd) |
143 |
| - var cmd *exec.Cmd |
144 |
| - if err == nil { |
145 |
| - cmd = exec.Command(updateGrubPath) |
146 |
| - logger.Debugf("$ %s", updateGrubCmd) |
| 144 | +type execStart struct { |
| 145 | + Path string // the binary path to execute |
| 146 | + Args []string // an array with all arguments to pass to the executed command, starting with argument 0 |
| 147 | + UncleanIsFailure bool // a boolean whether it should be considered a failure if the process exits uncleanly |
| 148 | +} |
| 149 | + |
| 150 | +func (m *modifyManager) runUpdateGrubWithUnit() error { |
| 151 | + var command []string |
| 152 | + serviceName := "dde-update-grub.service" |
| 153 | + path, err := exec.LookPath(updateGrubCmd) |
| 154 | + if err != nil { |
| 155 | + path = grubMkconfigCmd |
| 156 | + command = append(command, updateGrubCmd, "-o", grubScriptFile) |
147 | 157 | } else {
|
148 |
| - // fallback to grub-mkconfig |
149 |
| - cmd = exec.Command(grubMkconfigCmd, "-o", grubScriptFile) |
150 |
| - logger.Debugf("$ %s -o %s", grubMkconfigCmd, grubScriptFile) |
| 158 | + command = append(command, path) |
151 | 159 | }
|
152 | 160 |
|
153 | 161 | locale := getSystemLocale()
|
| 162 | + var language string |
154 | 163 | if locale != "" {
|
155 | 164 | logger.Info("system locale:", locale)
|
156 |
| - language := strings.Split(locale, ".")[0] |
157 |
| - cmd.Env = append(os.Environ(), "LANG="+locale, "LANGUAGE="+language) |
| 165 | + language = strings.Split(locale, ".")[0] |
158 | 166 | } else {
|
159 |
| - logger.Warning("failed to get system locale") |
| 167 | + err = fmt.Errorf("failed to get system locale") |
| 168 | + return err |
| 169 | + } |
| 170 | + conn, err := dbus.SystemBus() |
| 171 | + if err != nil { |
| 172 | + logger.Warning("failed to connect to system bus:", err) |
| 173 | + return err |
160 | 174 | }
|
161 | 175 |
|
162 |
| - cmd.Stdout = os.Stdout |
163 |
| - cmd.Stderr = os.Stderr |
164 |
| - return cmd.Run() |
| 176 | + systemd := systemd1.NewManager(conn) |
| 177 | + var properties []systemd1.Property |
| 178 | + var aux []systemd1.PropertyCollection |
| 179 | + properties = append(properties, systemd1.Property{"Type", dbus.MakeVariant("oneshot")}) |
| 180 | + properties = append(properties, systemd1.Property{"Description", dbus.MakeVariant("Transient Unit Update Grub")}) |
| 181 | + properties = append(properties, systemd1.Property{"Environment", dbus.MakeVariant([]string{"LANG=" + locale, "LANGUAGE=" + language})}) |
| 182 | + properties = append(properties, systemd1.Property{"ExecStart", dbus.MakeVariant([]execStart{{ |
| 183 | + Path: command[0], |
| 184 | + Args: command, |
| 185 | + UncleanIsFailure: false, |
| 186 | + }, |
| 187 | + })}) |
| 188 | + jobPath, err := systemd.StartTransientUnit(0, serviceName, "replace", properties, aux) |
| 189 | + if err != nil { |
| 190 | + logger.Warning("failed to start transient unit:", err) |
| 191 | + return err |
| 192 | + } |
| 193 | + systemd.InitSignalExt(m.g.sysLoop, true) |
| 194 | + logger.Infof("%s started successfully: %v", serviceName, jobPath) |
| 195 | + var wait = make(chan bool) |
| 196 | + systemd.ConnectJobRemoved(func(id uint32, job dbus.ObjectPath, unit string, result string) { |
| 197 | + if job == jobPath { |
| 198 | + wait <- true |
| 199 | + } |
| 200 | + }) |
| 201 | + <-wait |
| 202 | + logger.Infof("%s unit removed: %v", serviceName, path) |
| 203 | + return nil |
165 | 204 | }
|
166 | 205 |
|
167 | 206 | func (m *modifyManager) updateEnd() {
|
|
0 commit comments