mirror of
https://github.com/openshift/installer.git
synced 2026-02-05 06:46:36 +01:00
Fix issue CORS-4275 Add Windows support
This PR improves cross-platform compatibility. It solves two main issues: 1. inconsistent line endings 2. inconsistent path separators Path separators, in installer, needs to target two different environments: 1. the OS where the installer runs 2. the OS where the injected files been used This PR unified path separators used in 2 to be UNIX path separators, while in 1 to be platform-dependant. Ref: https://forum.golangbridge.org/t/filepath-join-or-path-join/13479 Known issues: The spawn processes, including etcd.exe, kube-apiserver.exe, and openshift-installer.exe, will not exit once installation aborted or completed. Users need to manually terminate those processes in task manager.
This commit is contained in:
6
.gitattributes
vendored
Normal file
6
.gitattributes
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
# the following files will be injected into the bootstrap node (CoreOS) as-is,
|
||||
# which must be in Unix line endings (LF)
|
||||
data/data/bootstrap/systemd/**/*.service text eol=lf
|
||||
data/data/bootstrap/systemd/**/*.socket text eol=lf
|
||||
data/data/bootstrap/systemd/**/*.conf text eol=lf
|
||||
data/data/bootstrap/files/** text eol=lf
|
||||
@@ -316,14 +316,14 @@ func (a *Ignition) Generate(ctx context.Context, dependencies asset.Parents) err
|
||||
|
||||
// add ZTP manifests to manifestPath
|
||||
for _, file := range agentManifests.FileList {
|
||||
manifestFile := ignition.FileFromBytes(filepath.Join(manifestPath, filepath.Base(file.Filename)),
|
||||
manifestFile := ignition.FileFromBytes(path.Join(manifestPath, filepath.Base(file.Filename)),
|
||||
"root", 0600, file.Data)
|
||||
config.Storage.Files = append(config.Storage.Files, manifestFile)
|
||||
}
|
||||
|
||||
// add AgentConfig if provided
|
||||
if agentConfigAsset.Config != nil {
|
||||
agentConfigFile := ignition.FileFromBytes(filepath.Join(manifestPath, filepath.Base(agentConfigAsset.File.Filename)),
|
||||
agentConfigFile := ignition.FileFromBytes(path.Join(manifestPath, filepath.Base(agentConfigAsset.File.Filename)),
|
||||
"root", 0600, agentConfigAsset.File.Data)
|
||||
config.Storage.Files = append(config.Storage.Files, agentConfigFile)
|
||||
}
|
||||
@@ -588,7 +588,7 @@ func addMacAddressToHostnameMappings(
|
||||
}
|
||||
for _, host := range agentHostsAsset.Hosts {
|
||||
if host.Hostname != "" {
|
||||
file := ignition.FileFromBytes(filepath.Join(hostnamesPath,
|
||||
file := ignition.FileFromBytes(path.Join(hostnamesPath,
|
||||
strings.ToLower(filepath.Base(host.Interfaces[0].MacAddress))),
|
||||
"root", 0600, []byte(host.Hostname))
|
||||
config.Storage.Files = append(config.Storage.Files, file)
|
||||
@@ -602,8 +602,8 @@ func addHostConfig(config *igntypes.Config, agentHosts *agentconfig.AgentHosts)
|
||||
return err
|
||||
}
|
||||
|
||||
for path, content := range confs {
|
||||
hostConfigFile := ignition.FileFromBytes(filepath.Join("/etc/assisted/hostconfig", path), "root", 0644, content)
|
||||
for pathName, content := range confs {
|
||||
hostConfigFile := ignition.FileFromBytes(path.Join("/etc/assisted/hostconfig", pathName), "root", 0644, content)
|
||||
config.Storage.Files = append(config.Storage.Files, hostConfigFile)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -236,7 +237,7 @@ func (a *UnconfiguredIgnition) Generate(_ context.Context, dependencies asset.Pa
|
||||
}
|
||||
|
||||
for _, file := range ztpManifestsToInclude {
|
||||
manifestFile := ignition.FileFromBytes(filepath.Join(manifestPath, filepath.Base(file.Filename)),
|
||||
manifestFile := ignition.FileFromBytes(path.Join(manifestPath, filepath.Base(file.Filename)),
|
||||
"root", 0600, file.Data)
|
||||
config.Storage.Files = append(config.Storage.Files, manifestFile)
|
||||
}
|
||||
|
||||
@@ -684,7 +684,7 @@ func (a *Common) addParentFiles(dependencies asset.Parents) {
|
||||
|
||||
rootCA := &tls.RootCA{}
|
||||
dependencies.Get(rootCA)
|
||||
a.Config.Storage.Files = replaceOrAppend(a.Config.Storage.Files, ignition.FileFromBytes(filepath.Join(rootDir, rootCA.CertFile().Filename), "root", 0644, rootCA.Cert()))
|
||||
a.Config.Storage.Files = replaceOrAppend(a.Config.Storage.Files, ignition.FileFromBytes(path.Join(rootDir, rootCA.CertFile().Filename), "root", 0644, rootCA.Cert()))
|
||||
}
|
||||
|
||||
func replaceOrAppend(files []igntypes.File, file igntypes.File) []igntypes.File {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -18,10 +19,8 @@ import (
|
||||
|
||||
var (
|
||||
_ asset.WritableAsset = (*CVOIgnore)(nil)
|
||||
)
|
||||
|
||||
const (
|
||||
cvoOverridesFilename = "manifests/cvo-overrides.yaml"
|
||||
cvoOverridesFilename = path.Join("manifests", "cvo-overrides.yaml")
|
||||
originalOverridesFilename = "original_cvo_overrides.patch"
|
||||
)
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package ignition
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/clarketm/json"
|
||||
@@ -30,7 +31,10 @@ func Marshal(input interface{}) ([]byte, error) {
|
||||
func FilesFromAsset(pathPrefix string, username string, mode int, asset asset.WritableAsset) []igntypes.File {
|
||||
var files []igntypes.File
|
||||
for _, f := range asset.Files() {
|
||||
files = append(files, FileFromBytes(filepath.Join(pathPrefix, f.Filename), username, mode, f.Data))
|
||||
// f.Filename is using platform-specific path separators
|
||||
// while its used in CoreOS, thus we need to convert it to Unix path separators
|
||||
normalizedFilename := path.Join(pathPrefix, filepath.ToSlash(f.Filename))
|
||||
files = append(files, FileFromBytes(normalizedFilename, username, mode, f.Data))
|
||||
}
|
||||
return files
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
additionalTrustBundleConfigFileName = filepath.Join(manifestDir, "user-ca-bundle-config.yaml")
|
||||
additionalTrustBundleConfigFileName = path.Join(manifestDir, "user-ca-bundle-config.yaml")
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"path"
|
||||
|
||||
"github.com/IBM/vpc-go-sdk/vpcv1"
|
||||
"github.com/pkg/errors"
|
||||
@@ -43,7 +43,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
cloudProviderConfigFileName = filepath.Join(manifestDir, "cloud-provider-config.yaml")
|
||||
cloudProviderConfigFileName = path.Join(manifestDir, "cloud-provider-config.yaml")
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -2,7 +2,7 @@ package manifests
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"path"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
clusterCSIDriverConfigFileName = filepath.Join(manifestDir, "cluster-csi-driver-config.yaml")
|
||||
clusterCSIDriverConfigFileName = path.Join(manifestDir, "cluster-csi-driver-config.yaml")
|
||||
)
|
||||
|
||||
// ClusterCSIDriverConfig generates the cluster-csi-driver-config.yaml file.
|
||||
|
||||
@@ -3,7 +3,7 @@ package manifests
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -35,7 +35,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
dnsCfgFilename = filepath.Join(manifestDir, "cluster-dns-02-config.yml")
|
||||
dnsCfgFilename = path.Join(manifestDir, "cluster-dns-02-config.yml")
|
||||
|
||||
combineGCPZoneInfo = func(project, zoneName string) string {
|
||||
return fmt.Sprintf("project/%s/managedZones/%s", project, zoneName)
|
||||
|
||||
@@ -2,7 +2,7 @@ package manifests
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"path"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/openshift/installer/pkg/types/featuregates"
|
||||
)
|
||||
|
||||
var fgFileName = filepath.Join(openshiftManifestDir, "99_feature-gate.yaml")
|
||||
var fgFileName = path.Join(openshiftManifestDir, "99_feature-gate.yaml")
|
||||
|
||||
// FeatureGate generates the feature gate manifest.
|
||||
type FeatureGate struct {
|
||||
|
||||
@@ -2,7 +2,7 @@ package manifests
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"path"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -49,7 +49,7 @@ func (p *ImageDigestMirrorSet) Generate(_ context.Context, dependencies asset.Pa
|
||||
return errors.Wrapf(err, "failed to marshal ImageDigestMirrorSet")
|
||||
}
|
||||
p.File = &asset.File{
|
||||
Filename: filepath.Join(manifestDir, imageDigestMirrorSetFilename),
|
||||
Filename: path.Join(manifestDir, imageDigestMirrorSetFilename),
|
||||
Data: policyData,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package manifests
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"path"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -62,7 +62,7 @@ func (p *ImageContentSourcePolicy) Generate(_ context.Context, dependencies asse
|
||||
return errors.Wrapf(err, "failed to marshal ImageContentSourcePolicy")
|
||||
}
|
||||
p.File = &asset.File{
|
||||
Filename: filepath.Join(manifestDir, imageContentSourcePolicyFilename),
|
||||
Filename: path.Join(manifestDir, imageContentSourcePolicyFilename),
|
||||
Data: policyData,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package manifests
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"path"
|
||||
"sort"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -35,8 +35,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
infraCfgFilename = filepath.Join(manifestDir, "cluster-infrastructure-02-config.yml")
|
||||
cloudControllerUIDFilename = filepath.Join(manifestDir, "cloud-controller-uid-config.yml")
|
||||
infraCfgFilename = path.Join(manifestDir, "cluster-infrastructure-02-config.yml")
|
||||
cloudControllerUIDFilename = path.Join(manifestDir, "cloud-controller-uid-config.yml")
|
||||
)
|
||||
|
||||
// Infrastructure generates the cluster-infrastructure-*.yml files.
|
||||
|
||||
@@ -3,7 +3,7 @@ package manifests
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"path"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -18,8 +18,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
clusterIngressConfigFile = filepath.Join(manifestDir, "cluster-ingress-02-config.yml")
|
||||
defaultIngressControllerFile = filepath.Join(manifestDir, "cluster-ingress-default-ingresscontroller.yaml")
|
||||
clusterIngressConfigFile = path.Join(manifestDir, "cluster-ingress-02-config.yml")
|
||||
defaultIngressControllerFile = path.Join(manifestDir, "cluster-ingress-default-ingresscontroller.yaml")
|
||||
)
|
||||
|
||||
// Ingress generates the cluster-ingress-*.yml files.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package manifests
|
||||
|
||||
import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -24,7 +25,7 @@ func generateMCOManifest(installConfig *types.InstallConfig, template []*asset.F
|
||||
mcoCfg := applyTemplateData(template[0].Data, tmplData)
|
||||
return []*asset.File{
|
||||
{
|
||||
Filename: filepath.Join(manifestDir, strings.TrimSuffix(filepath.Base(template[0].Filename), ".template")),
|
||||
Filename: path.Join(manifestDir, strings.TrimSuffix(filepath.Base(template[0].Filename), ".template")),
|
||||
Data: mcoCfg,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package manifests
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"path"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -19,8 +19,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
noCfgFilename = filepath.Join(manifestDir, "cluster-network-02-config.yml")
|
||||
cnoCfgFilename = filepath.Join(manifestDir, "cluster-network-03-config.yml")
|
||||
noCfgFilename = path.Join(manifestDir, "cluster-network-02-config.yml")
|
||||
cnoCfgFilename = path.Join(manifestDir, "cluster-network-03-config.yml")
|
||||
// Cluster Network MTU for AWS Local Zone deployments on edge machine pools.
|
||||
ovnKubernetesNetworkMtuEdge uint32 = 1200
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -286,7 +287,7 @@ func (o *Openshift) Generate(ctx context.Context, dependencies asset.Parents) er
|
||||
continue
|
||||
}
|
||||
o.FileList = append(o.FileList, &asset.File{
|
||||
Filename: filepath.Join(openshiftManifestDir, name),
|
||||
Filename: path.Join(openshiftManifestDir, name),
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"text/template"
|
||||
@@ -32,7 +33,7 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
kubeSysConfigPath = filepath.Join(manifestDir, "cluster-config.yaml")
|
||||
kubeSysConfigPath = path.Join(manifestDir, "cluster-config.yaml")
|
||||
|
||||
_ asset.WritableAsset = (*Manifests)(nil)
|
||||
|
||||
@@ -216,7 +217,7 @@ func (m *Manifests) generateBootKubeManifests(dependencies asset.Parents) []*ass
|
||||
dependencies.Get(a)
|
||||
for _, f := range a.Files() {
|
||||
files = append(files, &asset.File{
|
||||
Filename: filepath.Join(manifestDir, strings.TrimSuffix(filepath.Base(f.Filename), ".template")),
|
||||
Filename: path.Join(manifestDir, strings.TrimSuffix(filepath.Base(f.Filename), ".template")),
|
||||
Data: applyTemplateData(f.Data, templateData),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
"github.com/openshift/installer/pkg/types/openstack"
|
||||
)
|
||||
|
||||
var proxyCfgFilename = filepath.Join(manifestDir, "cluster-proxy-01-config.yaml")
|
||||
var proxyCfgFilename = path.Join(manifestDir, "cluster-proxy-01-config.yaml")
|
||||
|
||||
// Proxy generates the cluster-proxy-*.yml files.
|
||||
type Proxy struct {
|
||||
|
||||
@@ -2,7 +2,7 @@ package manifests
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"path"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
|
||||
var (
|
||||
// SchedulerCfgFilename is the path of the Scheduler Config file
|
||||
SchedulerCfgFilename = filepath.Join(manifestDir, "cluster-scheduler-02-config.yml")
|
||||
SchedulerCfgFilename = path.Join(manifestDir, "cluster-scheduler-02-config.yml")
|
||||
)
|
||||
|
||||
// Scheduler generates the cluster-scheduler-*.yml files.
|
||||
|
||||
@@ -3,7 +3,7 @@ package openshiftinstall
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"path"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
configPath = filepath.Join("openshift", "openshift-install-manifests.yaml")
|
||||
configPath = path.Join("openshift", "openshift-install-manifests.yaml")
|
||||
)
|
||||
|
||||
// Config generates the openshift-install ConfigMap.
|
||||
|
||||
@@ -3,7 +3,6 @@ package tls
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -43,7 +42,7 @@ func (sk *BoundSASigningKey) Files() []*asset.File {
|
||||
// Load reads the private key from the disk.
|
||||
// It ensures that the key provided is a valid RSA key.
|
||||
func (sk *BoundSASigningKey) Load(f asset.FileFetcher) (bool, error) {
|
||||
keyFile, err := f.FetchByName(filepath.Join(tlsDir, "bound-service-account-signing-key.key"))
|
||||
keyFile, err := f.FetchByName(assetFilePath("bound-service-account-signing-key.key"))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
@@ -60,6 +59,6 @@ func (sk *BoundSASigningKey) Load(f asset.FileFetcher) (bool, error) {
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "failed to extract public key from the key")
|
||||
}
|
||||
sk.FileList = []*asset.File{keyFile, {Filename: filepath.Join(tlsDir, "bound-service-account-signing-key.pub"), Data: pubData}}
|
||||
sk.FileList = []*asset.File{keyFile, {Filename: assetFilePath("bound-service-account-signing-key.pub"), Data: pubData}}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package tls
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"path/filepath"
|
||||
"path"
|
||||
|
||||
"github.com/apparentlymart/go-cidr/cidr"
|
||||
|
||||
@@ -15,7 +15,7 @@ const (
|
||||
)
|
||||
|
||||
func assetFilePath(filename string) string {
|
||||
return filepath.Join(tlsDir, filename)
|
||||
return path.Join(tlsDir, filename)
|
||||
}
|
||||
|
||||
func apiAddress(cfg *types.InstallConfig) string {
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"path"
|
||||
"regexp"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -133,9 +132,7 @@ func (ps *State) Start(ctx context.Context, stdout io.Writer, stderr io.Writer)
|
||||
ps.Cmd.Stdout = stdout
|
||||
ps.Cmd.Stderr = stderr
|
||||
ps.Cmd.Dir = ps.Dir
|
||||
ps.Cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
Setpgid: true,
|
||||
}
|
||||
setSysProcAttr(ps.Cmd)
|
||||
|
||||
ready := make(chan bool)
|
||||
timedOut := time.After(ps.StartTimeout)
|
||||
@@ -178,7 +175,7 @@ func (ps *State) Start(ctx context.Context, stdout io.Writer, stderr io.Writer)
|
||||
close(pollerStopCh)
|
||||
if ps.Cmd != nil {
|
||||
// intentionally ignore this -- we might've crashed, failed to start, etc
|
||||
ps.Cmd.Process.Signal(syscall.SIGTERM) //nolint:errcheck
|
||||
stopProcess(ps) //nolint:errcheck
|
||||
}
|
||||
return fmt.Errorf("timeout waiting for process %s to start", path.Base(ps.Path))
|
||||
}
|
||||
@@ -237,7 +234,7 @@ func (ps *State) Stop() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if err := ps.Cmd.Process.Signal(syscall.SIGTERM); err != nil {
|
||||
if err := stopProcess(ps); err != nil {
|
||||
return fmt.Errorf("unable to signal for process %s to stop: %w", ps.Path, err)
|
||||
}
|
||||
|
||||
@@ -246,10 +243,10 @@ func (ps *State) Stop() error {
|
||||
case <-ps.waitDone:
|
||||
break
|
||||
case <-timedOut:
|
||||
if err := ps.Cmd.Process.Signal(syscall.SIGKILL); err != nil {
|
||||
return fmt.Errorf("unable to signal for process %s to stop: %w", ps.Path, err)
|
||||
if err := killProcess(ps); err != nil {
|
||||
return fmt.Errorf("unable to kill process %s: %w", ps.Path, err)
|
||||
}
|
||||
return fmt.Errorf("timeout waiting for process %s to stop, sent SIGKILL", path.Base(ps.Path))
|
||||
return fmt.Errorf("timeout waiting for process %s to stop, killed process", path.Base(ps.Path))
|
||||
}
|
||||
ps.ready = false
|
||||
return nil
|
||||
|
||||
23
pkg/clusterapi/internal/process/process_unix.go
Normal file
23
pkg/clusterapi/internal/process/process_unix.go
Normal file
@@ -0,0 +1,23 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package process
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func setSysProcAttr(cmd *exec.Cmd) {
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||||
Setpgid: true,
|
||||
}
|
||||
}
|
||||
|
||||
func stopProcess(ps *State) error {
|
||||
return ps.Cmd.Process.Signal(syscall.SIGTERM)
|
||||
}
|
||||
|
||||
func killProcess(ps *State) error {
|
||||
return ps.Cmd.Process.Signal(syscall.SIGKILL)
|
||||
}
|
||||
19
pkg/clusterapi/internal/process/process_windows.go
Normal file
19
pkg/clusterapi/internal/process/process_windows.go
Normal file
@@ -0,0 +1,19 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package process
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func setSysProcAttr(cmd *exec.Cmd) {
|
||||
}
|
||||
|
||||
func stopProcess(ps *State) error {
|
||||
return ps.Cmd.Process.Kill()
|
||||
}
|
||||
|
||||
func killProcess(ps *State) error {
|
||||
return ps.Cmd.Process.Kill()
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
capnv1 "github.com/nutanix-cloud-native/cluster-api-provider-nutanix/api/v1beta1"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -84,6 +85,11 @@ func (c *localControlPlane) Run(ctx context.Context) error {
|
||||
return fmt.Errorf("failed to create kube-apiserver log file: %w", err)
|
||||
}
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
os.Setenv("TEST_ASSET_ETCD", filepath.Join(c.BinDir, "etcd.exe"))
|
||||
os.Setenv("TEST_ASSET_KUBE_APISERVER", filepath.Join(c.BinDir, "kube-apiserver.exe"))
|
||||
}
|
||||
|
||||
log.SetLogger(klog.NewKlogr())
|
||||
logrus.Info("Started local control plane with envtest")
|
||||
c.Env = &envtest.Environment{
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -78,7 +79,7 @@ var Mirror embed.FS
|
||||
|
||||
// Extract extracts the provider from the embedded data into the specified directory.
|
||||
func (p Provider) Extract(dir string) error {
|
||||
f, err := Mirror.Open(filepath.Join("mirror", zipFile))
|
||||
f, err := Mirror.Open(path.Join("mirror", zipFile))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to open cluster api zip from mirror")
|
||||
}
|
||||
@@ -113,9 +114,11 @@ func (p Provider) Extract(dir string) error {
|
||||
// Extract the files.
|
||||
for _, f := range r.File {
|
||||
name := f.Name
|
||||
if !p.Sources.Has(name) {
|
||||
nameWithoutExt := strings.TrimSuffix(name, ".exe")
|
||||
if !p.Sources.Has(name) && !p.Sources.Has(nameWithoutExt) {
|
||||
continue
|
||||
}
|
||||
|
||||
path, err := sanitizeArchivePath(dir, name)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to sanitize archive file %q", name)
|
||||
|
||||
5
pkg/rhcos/cache/cache.go
vendored
5
pkg/rhcos/cache/cache.go
vendored
@@ -18,7 +18,6 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/thedevsaddam/retry"
|
||||
"github.com/ulikunitz/xz"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -99,12 +98,12 @@ func cacheFile(reader io.Reader, filePath string, sha256Checksum string) (err er
|
||||
}
|
||||
}()
|
||||
|
||||
err = unix.Flock(int(flock.Fd()), unix.LOCK_EX)
|
||||
err = flockFile(flock, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
err2 := unix.Flock(int(flock.Fd()), unix.LOCK_UN)
|
||||
err2 := flockFile(flock, false)
|
||||
if err == nil {
|
||||
err = err2
|
||||
}
|
||||
|
||||
17
pkg/rhcos/cache/flock_unix.go
vendored
Normal file
17
pkg/rhcos/cache/flock_unix.go
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
//go:build !windows
|
||||
// +build !windows
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func flockFile(f *os.File, lock bool) error {
|
||||
if lock {
|
||||
return unix.Flock(int(f.Fd()), unix.LOCK_EX)
|
||||
}
|
||||
return unix.Flock(int(f.Fd()), unix.LOCK_UN)
|
||||
}
|
||||
19
pkg/rhcos/cache/flock_windows.go
vendored
Normal file
19
pkg/rhcos/cache/flock_windows.go
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func flockFile(f *os.File, lock bool) error {
|
||||
if lock {
|
||||
var overlapped windows.Overlapped
|
||||
return windows.LockFileEx(windows.Handle(f.Fd()), windows.LOCKFILE_EXCLUSIVE_LOCK, 0, 1, 0, &overlapped)
|
||||
}
|
||||
var overlapped windows.Overlapped
|
||||
return windows.UnlockFileEx(windows.Handle(f.Fd()), 0, 1, 0, &overlapped)
|
||||
}
|
||||
Reference in New Issue
Block a user