Skip to content

Commit c6c1064

Browse files
swordqiuQiu Jian
andauthored
fix: host compat with ovs in container (#23944)
Co-authored-by: Qiu Jian <[email protected]>
1 parent d394a5f commit c6c1064

File tree

9 files changed

+109
-21
lines changed

9 files changed

+109
-21
lines changed

pkg/hostman/hostinfo/hostbridge/ovs.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package hostbridge
1717
import (
1818
"fmt"
1919
"strings"
20+
"time"
2021

2122
"yunion.io/x/log"
2223
"yunion.io/x/pkg/errors"
@@ -281,8 +282,29 @@ func (o *SOVSBridgeDriver) WarmupConfig() error {
281282

282283
func OVSPrepare() error {
283284
ovs := system_service.GetService("openvswitch")
284-
if !ovs.IsInstalled() {
285-
return fmt.Errorf("Service openvswitch not installed!")
285+
if !ovs.IsInstalled() || !ovs.IsActive() {
286+
// no openvswitch service found, first try load openvswitch kernel modules, then try ovs-vsctl command, if success, return nil
287+
err := procutils.NewRemoteCommandAsFarAsPossible("modprobe", "openvswitch").Run()
288+
if err != nil {
289+
return errors.Wrap(err, "Failed to load openvswitch kernel modules")
290+
}
291+
// wait for the ovs-vswitchd to start
292+
startProbe := time.Now()
293+
const waitSeconds = 60 * 2 // wait ovs-vswitch running for 2 minutes
294+
for time.Since(startProbe) < time.Duration(waitSeconds)*time.Second {
295+
err := procutils.NewCommand("ovs-vsctl", "show").Run()
296+
if err != nil {
297+
time.Sleep(2 * time.Second)
298+
} else {
299+
return nil
300+
}
301+
}
302+
// ovs service start timeout
303+
if !ovs.IsInstalled() {
304+
// ovs service not installed, return error
305+
return fmt.Errorf("service openvswitch not installed and wait ovs service timeout, please check ovs service status")
306+
}
307+
// ovs service installed but not running, continue to start the service
286308
}
287309
if ovs.IsEnabled() {
288310
err := ovs.Disable()

pkg/hostman/hostinfo/hostinfo.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,6 @@ func (h *SHostInfo) detectHostInfo() error {
623623
if err = h.GetNodeHugepages(); err != nil {
624624
return errors.Wrap(err, "GetNodeHugepages")
625625
}
626-
system_service.Init()
627626
if options.HostOptions.CheckSystemServices {
628627
if err := h.checkSystemServices(); err != nil {
629628
return err

pkg/hostman/system_service/system_service.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ package system_service
1717
import (
1818
"fmt"
1919
"strings"
20+
"sync"
2021

2122
"yunion.io/x/log"
2223

@@ -43,8 +44,15 @@ type ISystemService interface {
4344
type NewServiceFunc func()
4445

4546
var serviceMap map[string]ISystemService
47+
var serviceMapLock *sync.Mutex = &sync.Mutex{}
4648

47-
func Init() {
49+
func initServiceMap() {
50+
serviceMapLock.Lock()
51+
defer serviceMapLock.Unlock()
52+
53+
if serviceMap != nil {
54+
return
55+
}
4856
serviceMap = map[string]ISystemService{
4957
"ntpd": NewNtpdService(),
5058
"telegraf": NewTelegrafService(),
@@ -60,6 +68,7 @@ func Init() {
6068
}
6169

6270
func GetService(name string) ISystemService {
71+
initServiceMap()
6372
if service, ok := serviceMap[name]; ok {
6473
return service
6574
} else {

pkg/lbagent/haproxy.go

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
"bytes"
1919
"context"
2020
"fmt"
21-
"io/ioutil"
21+
"io"
2222
"os"
2323
"os/exec"
2424
"path/filepath"
@@ -65,9 +65,6 @@ func NewHaproxyHelper(opts *Options, lbagentId string) (*HaproxyHelper, error) {
6565
return nil, fmt.Errorf("sysctl: %s", err)
6666
}
6767
}
68-
69-
system_service.Init()
70-
7168
return helper, nil
7269
}
7370

@@ -199,7 +196,7 @@ func (h *HaproxyHelper) handleUseCorpusCmd(ctx context.Context, cmd *LbagentCmd)
199196
if err == nil {
200197
d := buf.Bytes()
201198
p := filepath.Join(dir, "telegraf.conf")
202-
err := ioutil.WriteFile(p, d, agentutils.FileModeFile)
199+
err := os.WriteFile(p, d, agentutils.FileModeFile)
203200
if err == nil {
204201
err := h.reloadTelegraf(ctx, agentParams)
205202
if err != nil {
@@ -590,16 +587,21 @@ func (h *HaproxyHelper) reloadKeepalived(ctx context.Context) error {
590587
"--vrrp_pid", vrrpPidFile.Path,
591588
"--checkers_pid", checkersPidFile.Path,
592589
"--use-file", h.keepalivedConf(),
593-
"-D",
594-
"-d",
595-
"-S",
596-
"0",
590+
"--log-detail",
591+
"--no-syslog",
592+
"--dump-conf",
593+
"--log-console",
594+
"--dont-fork",
595+
}
596+
err := h.runService(args)
597+
if err != nil {
598+
return errors.Wrapf(err, "run service %s", strings.Join(args, " "))
597599
}
598-
return h.runCmd(args)
600+
return nil
599601
}
600602

601603
func (h *HaproxyHelper) runCmd(args []string) error {
602-
log.Debugf("run command %s", args)
604+
log.Infof("run command %s", strings.Join(args, " "))
603605

604606
name := args[0]
605607
args = args[1:]
@@ -619,6 +621,8 @@ func (h *HaproxyHelper) runCmd(args []string) error {
619621
}
620622

621623
func (h *HaproxyHelper) startCmd(args []string) (*exec.Cmd, error) {
624+
log.Infof("start command %s", strings.Join(args, " "))
625+
622626
name := args[0]
623627
args = args[1:]
624628
cmd := exec.Command(name, args...)
@@ -629,3 +633,51 @@ func (h *HaproxyHelper) startCmd(args []string) (*exec.Cmd, error) {
629633
}
630634
return cmd, nil
631635
}
636+
637+
func (h *HaproxyHelper) runService(args []string) error {
638+
log.Infof("run service %s", strings.Join(args, " "))
639+
640+
name := args[0]
641+
args = args[1:]
642+
cmd := exec.Command(name, args...)
643+
644+
stdout, err := cmd.StdoutPipe()
645+
if err != nil {
646+
log.Errorf("service %s stdout pipe error: %s", cmd.String(), err)
647+
return errors.Wrapf(err, "service %s stdout pipe error", cmd.String())
648+
}
649+
stderr, err := cmd.StderrPipe()
650+
if err != nil {
651+
log.Errorf("service %s stderr pipe error: %s", cmd.String(), err)
652+
return errors.Wrapf(err, "service %s stderr pipe error", cmd.String())
653+
}
654+
drain := func(out io.ReadCloser, isErr bool) {
655+
defer out.Close()
656+
buf := make([]byte, 1024)
657+
for {
658+
n, err := stdout.Read(buf)
659+
if err != nil {
660+
log.Errorf("read pipe error: %s", err)
661+
return
662+
}
663+
if isErr {
664+
log.Errorln(string(buf[:n]))
665+
} else {
666+
log.Infoln(string(buf[:n]))
667+
}
668+
}
669+
}
670+
err = cmd.Start()
671+
if err != nil {
672+
return errors.Wrapf(err, "start service %s", cmd.String())
673+
}
674+
go func(cmd *exec.Cmd) {
675+
err := cmd.Wait()
676+
if err != nil {
677+
log.Errorf("service %s exited with error: %s", cmd.String(), err)
678+
}
679+
}(cmd)
680+
go drain(stdout, false)
681+
go drain(stderr, true)
682+
return nil
683+
}

pkg/lbagent/hastate.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ const (
3838
HA_STATE_SCRIPT_NAME = "ha_state.sh"
3939
HA_STATE_SCRIPT_CONTENT = `
4040
#!/bin/bash
41+
42+
echo "keepalived notify $@" > /proc/1/fd/1
4143
echo "$@" >%s
4244
`
4345
HA_STATE_FILENAME = "ha_state"

pkg/lbagent/models/haproxy.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func (b *LoadbalancerCorpus) GenHaproxyConfigs(dir string, opts *AgentParams) (*
6969
"",
7070
}
7171
s := strings.Join(lines, "\n")
72-
err := ioutil.WriteFile(p, []byte(s), agentutils.FileModeFile)
72+
err := os.WriteFile(p, []byte(s), agentutils.FileModeFile)
7373
if err != nil {
7474
return nil, fmt.Errorf("write 01-haproxy.cfg: %s", err)
7575
}
@@ -82,7 +82,7 @@ func (b *LoadbalancerCorpus) GenHaproxyConfigs(dir string, opts *AgentParams) (*
8282
d = append(d, []byte(lbcert.PrivateKey)...)
8383
fn := fmt.Sprintf("%s.pem", lbcert.Id)
8484
p := filepath.Join(certsBase, fn)
85-
err := ioutil.WriteFile(p, d, agentutils.FileModeFileSensitive)
85+
err := os.WriteFile(p, d, agentutils.FileModeFileSensitive)
8686
if err != nil {
8787
return nil, fmt.Errorf("write cert %s: %s", lbcert.Id, err)
8888
}

pkg/lbagent/models/keepalived.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ package models
1616

1717
import (
1818
"bytes"
19-
"io/ioutil"
19+
"os"
2020
"path/filepath"
2121
"text/template"
2222

@@ -67,7 +67,7 @@ func (b *LoadbalancerCorpus) GenKeepalivedConfigs(dir string, opts *GenKeepalive
6767
// write keepalived.conf
6868
d := buf.Bytes()
6969
p := filepath.Join(dir, "keepalived.conf")
70-
err := ioutil.WriteFile(p, d, agentutils.FileModeFile)
70+
err := os.WriteFile(p, d, agentutils.FileModeFile)
7171
if err != nil {
7272
return err
7373
}

pkg/lbagent/service.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828

2929
app_common "yunion.io/x/onecloud/pkg/cloudcommon/app"
3030
common_options "yunion.io/x/onecloud/pkg/cloudcommon/options"
31+
"yunion.io/x/onecloud/pkg/hostman/hostinfo/hostbridge"
3132
"yunion.io/x/onecloud/pkg/util/fileutils2"
3233
"yunion.io/x/onecloud/pkg/util/ovnutils"
3334
"yunion.io/x/onecloud/pkg/util/procutils"
@@ -72,7 +73,11 @@ func StartService() {
7273
}
7374

7475
if !opts.DisableLocalVpc {
75-
err := ovnutils.InitOvn(opts.SOvnOptions)
76+
err := hostbridge.OVSPrepare()
77+
if err != nil {
78+
log.Fatalf("ovs prepare fail: %s", err)
79+
}
80+
err = ovnutils.InitOvn(opts.SOvnOptions)
7681
if err != nil {
7782
log.Fatalf("ovn init fail: %s", err)
7883
}

pkg/util/ovnutils/ovnutils.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ func InitOvn(opts SOvnOptions) (err error) {
134134
err = panicVal.(error)
135135
}
136136
}()
137-
system_service.Init()
138137
mustPrepOvsdbConfig(opts)
139138
configBridgeMtu(opts)
140139
if _, ok := ovnContainerImageTag(); !ok {

0 commit comments

Comments
 (0)