fix: allow override of artifact server bind address (#1560)
* Prior to this change, the artifact server always binds to the detected "outbound IP", breaks functionality when that IP is unroutable. For example, Zscaler assigns the host a local CGNAT address, 100.64.0.1, which is unreachable from Docker Desktop. * Add the `--artifact-server-addr` flag to allow override of the address to which the artifact server binds, defaulting to the existing behaviour. Fixes: #1559
This commit is contained in:
parent
93907931df
commit
d064863f9b
7 changed files with 18 additions and 12 deletions
|
@ -169,8 +169,9 @@ It will save that information to `~/.actrc`, please refer to [Configuration](#co
|
||||||
-a, --actor string user that triggered the event (default "nektos/act")
|
-a, --actor string user that triggered the event (default "nektos/act")
|
||||||
--replace-ghe-action-with-github-com If you are using GitHub Enterprise Server and allow specified actions from GitHub (github.com), you can set actions on this. (e.g. --replace-ghe-action-with-github-com=github/super-linter)
|
--replace-ghe-action-with-github-com If you are using GitHub Enterprise Server and allow specified actions from GitHub (github.com), you can set actions on this. (e.g. --replace-ghe-action-with-github-com=github/super-linter)
|
||||||
--replace-ghe-action-token-with-github-com If you are using replace-ghe-action-with-github-com and you want to use private actions on GitHub, you have to set personal access token
|
--replace-ghe-action-token-with-github-com If you are using replace-ghe-action-with-github-com and you want to use private actions on GitHub, you have to set personal access token
|
||||||
|
--artifact-server-addr string Defines the address to which the artifact server binds. (default "<default-outbound-IP>")
|
||||||
--artifact-server-path string Defines the path where the artifact server stores uploads and retrieves downloads from. If not specified the artifact server will not start.
|
--artifact-server-path string Defines the path where the artifact server stores uploads and retrieves downloads from. If not specified the artifact server will not start.
|
||||||
--artifact-server-port string Defines the port where the artifact server listens (will only bind to localhost). (default "34567")
|
--artifact-server-port string Defines the port where the artifact server listens. (default "34567")
|
||||||
-b, --bind bind working directory to container, rather than copy
|
-b, --bind bind working directory to container, rather than copy
|
||||||
--container-architecture string Architecture which should be used to run containers, e.g.: linux/amd64. If not specified, will use host default architecture. Requires Docker server API Version 1.41+. Ignored on earlier Docker server platforms.
|
--container-architecture string Architecture which should be used to run containers, e.g.: linux/amd64. If not specified, will use host default architecture. Requires Docker server API Version 1.41+. Ignored on earlier Docker server platforms.
|
||||||
--container-cap-add stringArray kernel capabilities to add to the workflow containers (e.g. --container-cap-add SYS_PTRACE)
|
--container-cap-add stringArray kernel capabilities to add to the workflow containers (e.g. --container-cap-add SYS_PTRACE)
|
||||||
|
|
|
@ -40,6 +40,7 @@ type Input struct {
|
||||||
containerCapDrop []string
|
containerCapDrop []string
|
||||||
autoRemove bool
|
autoRemove bool
|
||||||
artifactServerPath string
|
artifactServerPath string
|
||||||
|
artifactServerAddr string
|
||||||
artifactServerPort string
|
artifactServerPort string
|
||||||
jsonLogger bool
|
jsonLogger bool
|
||||||
noSkipCheckout bool
|
noSkipCheckout bool
|
||||||
|
|
|
@ -82,7 +82,8 @@ func Execute(ctx context.Context, version string) {
|
||||||
rootCmd.PersistentFlags().StringVarP(&input.containerOptions, "container-options", "", "", "Custom docker container options for the job container without an options property in the job definition")
|
rootCmd.PersistentFlags().StringVarP(&input.containerOptions, "container-options", "", "", "Custom docker container options for the job container without an options property in the job definition")
|
||||||
rootCmd.PersistentFlags().StringVarP(&input.githubInstance, "github-instance", "", "github.com", "GitHub instance to use. Don't use this if you are not using GitHub Enterprise Server.")
|
rootCmd.PersistentFlags().StringVarP(&input.githubInstance, "github-instance", "", "github.com", "GitHub instance to use. Don't use this if you are not using GitHub Enterprise Server.")
|
||||||
rootCmd.PersistentFlags().StringVarP(&input.artifactServerPath, "artifact-server-path", "", "", "Defines the path where the artifact server stores uploads and retrieves downloads from. If not specified the artifact server will not start.")
|
rootCmd.PersistentFlags().StringVarP(&input.artifactServerPath, "artifact-server-path", "", "", "Defines the path where the artifact server stores uploads and retrieves downloads from. If not specified the artifact server will not start.")
|
||||||
rootCmd.PersistentFlags().StringVarP(&input.artifactServerPort, "artifact-server-port", "", "34567", "Defines the port where the artifact server listens (will only bind to localhost).")
|
rootCmd.PersistentFlags().StringVarP(&input.artifactServerAddr, "artifact-server-addr", "", common.GetOutboundIP().String(), "Defines the address to which the artifact server binds.")
|
||||||
|
rootCmd.PersistentFlags().StringVarP(&input.artifactServerPort, "artifact-server-port", "", "34567", "Defines the port where the artifact server listens.")
|
||||||
rootCmd.PersistentFlags().BoolVarP(&input.noSkipCheckout, "no-skip-checkout", "", false, "Do not skip actions/checkout")
|
rootCmd.PersistentFlags().BoolVarP(&input.noSkipCheckout, "no-skip-checkout", "", false, "Do not skip actions/checkout")
|
||||||
rootCmd.SetArgs(args())
|
rootCmd.SetArgs(args())
|
||||||
|
|
||||||
|
@ -482,6 +483,7 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
|
||||||
ContainerCapDrop: input.containerCapDrop,
|
ContainerCapDrop: input.containerCapDrop,
|
||||||
AutoRemove: input.autoRemove,
|
AutoRemove: input.autoRemove,
|
||||||
ArtifactServerPath: input.artifactServerPath,
|
ArtifactServerPath: input.artifactServerPath,
|
||||||
|
ArtifactServerAddr: input.artifactServerAddr,
|
||||||
ArtifactServerPort: input.artifactServerPort,
|
ArtifactServerPort: input.artifactServerPort,
|
||||||
NoSkipCheckout: input.noSkipCheckout,
|
NoSkipCheckout: input.noSkipCheckout,
|
||||||
RemoteName: input.remoteName,
|
RemoteName: input.remoteName,
|
||||||
|
@ -493,7 +495,7 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel := artifacts.Serve(ctx, input.artifactServerPath, input.artifactServerPort)
|
cancel := artifacts.Serve(ctx, input.artifactServerPath, input.artifactServerAddr, input.artifactServerPort)
|
||||||
|
|
||||||
ctx = common.WithDryrun(ctx, input.dryrun)
|
ctx = common.WithDryrun(ctx, input.dryrun)
|
||||||
if watch, err := cmd.Flags().GetBool("watch"); err != nil {
|
if watch, err := cmd.Flags().GetBool("watch"); err != nil {
|
||||||
|
|
|
@ -262,7 +262,7 @@ func downloads(router *httprouter.Router, fsys fs.FS) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func Serve(ctx context.Context, artifactPath string, port string) context.CancelFunc {
|
func Serve(ctx context.Context, artifactPath string, addr string, port string) context.CancelFunc {
|
||||||
serverContext, cancel := context.WithCancel(ctx)
|
serverContext, cancel := context.WithCancel(ctx)
|
||||||
logger := common.Logger(serverContext)
|
logger := common.Logger(serverContext)
|
||||||
|
|
||||||
|
@ -276,17 +276,16 @@ func Serve(ctx context.Context, artifactPath string, port string) context.Cancel
|
||||||
fs := os.DirFS(artifactPath)
|
fs := os.DirFS(artifactPath)
|
||||||
uploads(router, MkdirFsImpl{artifactPath, fs})
|
uploads(router, MkdirFsImpl{artifactPath, fs})
|
||||||
downloads(router, fs)
|
downloads(router, fs)
|
||||||
ip := common.GetOutboundIP().String()
|
|
||||||
|
|
||||||
server := &http.Server{
|
server := &http.Server{
|
||||||
Addr: fmt.Sprintf("%s:%s", ip, port),
|
Addr: fmt.Sprintf("%s:%s", addr, port),
|
||||||
ReadHeaderTimeout: 2 * time.Second,
|
ReadHeaderTimeout: 2 * time.Second,
|
||||||
Handler: router,
|
Handler: router,
|
||||||
}
|
}
|
||||||
|
|
||||||
// run server
|
// run server
|
||||||
go func() {
|
go func() {
|
||||||
logger.Infof("Start server on http://%s:%s", ip, port)
|
logger.Infof("Start server on http://%s:%s", addr, port)
|
||||||
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||||
logger.Fatal(err)
|
logger.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,7 +240,8 @@ type TestJobFileInfo struct {
|
||||||
containerArchitecture string
|
containerArchitecture string
|
||||||
}
|
}
|
||||||
|
|
||||||
var aritfactsPath = path.Join(os.TempDir(), "test-artifacts")
|
var artifactsPath = path.Join(os.TempDir(), "test-artifacts")
|
||||||
|
var artifactsAddr = "127.0.0.1"
|
||||||
var artifactsPort = "12345"
|
var artifactsPort = "12345"
|
||||||
|
|
||||||
func TestArtifactFlow(t *testing.T) {
|
func TestArtifactFlow(t *testing.T) {
|
||||||
|
@ -250,7 +251,7 @@ func TestArtifactFlow(t *testing.T) {
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
cancel := Serve(ctx, aritfactsPath, artifactsPort)
|
cancel := Serve(ctx, artifactsPath, artifactsAddr, artifactsPort)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
platforms := map[string]string{
|
platforms := map[string]string{
|
||||||
|
@ -271,7 +272,7 @@ func runTestJobFile(ctx context.Context, t *testing.T, tjfi TestJobFileInfo) {
|
||||||
t.Run(tjfi.workflowPath, func(t *testing.T) {
|
t.Run(tjfi.workflowPath, func(t *testing.T) {
|
||||||
fmt.Printf("::group::%s\n", tjfi.workflowPath)
|
fmt.Printf("::group::%s\n", tjfi.workflowPath)
|
||||||
|
|
||||||
if err := os.RemoveAll(aritfactsPath); err != nil {
|
if err := os.RemoveAll(artifactsPath); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +287,8 @@ func runTestJobFile(ctx context.Context, t *testing.T, tjfi TestJobFileInfo) {
|
||||||
ReuseContainers: false,
|
ReuseContainers: false,
|
||||||
ContainerArchitecture: tjfi.containerArchitecture,
|
ContainerArchitecture: tjfi.containerArchitecture,
|
||||||
GitHubInstance: "github.com",
|
GitHubInstance: "github.com",
|
||||||
ArtifactServerPath: aritfactsPath,
|
ArtifactServerPath: artifactsPath,
|
||||||
|
ArtifactServerAddr: artifactsAddr,
|
||||||
ArtifactServerPort: artifactsPort,
|
ArtifactServerPort: artifactsPort,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -751,7 +751,7 @@ func (rc *RunContext) withGithubEnv(ctx context.Context, github *model.GithubCon
|
||||||
func setActionRuntimeVars(rc *RunContext, env map[string]string) {
|
func setActionRuntimeVars(rc *RunContext, env map[string]string) {
|
||||||
actionsRuntimeURL := os.Getenv("ACTIONS_RUNTIME_URL")
|
actionsRuntimeURL := os.Getenv("ACTIONS_RUNTIME_URL")
|
||||||
if actionsRuntimeURL == "" {
|
if actionsRuntimeURL == "" {
|
||||||
actionsRuntimeURL = fmt.Sprintf("http://%s:%s/", common.GetOutboundIP().String(), rc.Config.ArtifactServerPort)
|
actionsRuntimeURL = fmt.Sprintf("http://%s:%s/", rc.Config.ArtifactServerAddr, rc.Config.ArtifactServerPort)
|
||||||
}
|
}
|
||||||
env["ACTIONS_RUNTIME_URL"] = actionsRuntimeURL
|
env["ACTIONS_RUNTIME_URL"] = actionsRuntimeURL
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ type Config struct {
|
||||||
ContainerCapDrop []string // list of kernel capabilities to remove from the containers
|
ContainerCapDrop []string // list of kernel capabilities to remove from the containers
|
||||||
AutoRemove bool // controls if the container is automatically removed upon workflow completion
|
AutoRemove bool // controls if the container is automatically removed upon workflow completion
|
||||||
ArtifactServerPath string // the path where the artifact server stores uploads
|
ArtifactServerPath string // the path where the artifact server stores uploads
|
||||||
|
ArtifactServerAddr string // the address the artifact server binds to
|
||||||
ArtifactServerPort string // the port the artifact server binds to
|
ArtifactServerPort string // the port the artifact server binds to
|
||||||
NoSkipCheckout bool // do not skip actions/checkout
|
NoSkipCheckout bool // do not skip actions/checkout
|
||||||
RemoteName string // remote name in local git repo config
|
RemoteName string // remote name in local git repo config
|
||||||
|
|
Loading…
Reference in a new issue