diff --git a/CHANGELOG.md b/CHANGELOG.md index 43e9df832..7ba0cbc59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - New cli flag --distributed for running cluster with Charon distributed validator +### Changed +- Override `--latest` flag to not use the latest version of the image in the clients if image is specified + ## [v1.7.2] - 2024-11-12 ### Fixed diff --git a/cli/actions/generation_test.go b/cli/actions/generation_test.go index ea80bfaf2..f121862fb 100644 --- a/cli/actions/generation_test.go +++ b/cli/actions/generation_test.go @@ -260,9 +260,9 @@ func TestGenerateDockerCompose(t *testing.T) { }, }, genTestData{ - name: fmt.Sprintf("execution: %s, consensus: %s, validator: %s, network: %s, no validator, with latest", executionCl, consensusCl, consensusCl, network), + name: fmt.Sprintf("execution: %s, consensus: %s, validator: %s, network: %s, no validator, with latest, execution has image specified", executionCl, consensusCl, consensusCl, network), genData: generate.GenData{ - ExecutionClient: &clients.Client{Name: executionCl, Type: "execution"}, + ExecutionClient: &clients.Client{Name: executionCl, Type: "execution", Image: "execution/execution:1.1.1", Modified: true}, ConsensusClient: &clients.Client{Name: consensusCl, Type: "consensus"}, Services: []string{"execution", "consensus"}, Network: network, @@ -270,6 +270,29 @@ func TestGenerateDockerCompose(t *testing.T) { LatestVersion: true, }, }, + genTestData{ + name: fmt.Sprintf("execution: %s, consensus: %s, validator: %s, network: %s, no validator, with latest, consensus has image specified", executionCl, consensusCl, consensusCl, network), + genData: generate.GenData{ + ExecutionClient: &clients.Client{Name: executionCl, Type: "execution"}, + ConsensusClient: &clients.Client{Name: consensusCl, Type: "consensus", Image: "consensus/consensus:1.1.1", Modified: true}, + Services: []string{"execution", "consensus"}, + Network: network, + ContainerTag: "sampleTag", + LatestVersion: true, + }, + }, + genTestData{ + name: fmt.Sprintf("execution: %s, consensus: %s, validator: %s, network: %s, no validator, with latest, consensus and validator has image specified", executionCl, consensusCl, consensusCl, network), + genData: generate.GenData{ + ExecutionClient: &clients.Client{Name: executionCl, Type: "execution"}, + ConsensusClient: &clients.Client{Name: consensusCl, Type: "consensus", Image: "consensus/consensus:1.1.1", Modified: true}, + ValidatorClient: &clients.Client{Name: consensusCl, Type: "validator", Image: "validator/validator:1.1.1", Modified: true}, + Services: []string{"execution", "consensus", "validator"}, + Network: network, + ContainerTag: "sampleTag", + LatestVersion: true, + }, + }, ) } @@ -350,9 +373,13 @@ func TestGenerateDockerCompose(t *testing.T) { named, err := reference.ParseNormalizedNamed(ecImageVersion) assert.NoError(t, err, "invalid image", ecImageVersion) - // Test that the execution image is set to latest if flag --latest is provided + // Test that the execution image is set to latest if flag --latest is provided, and the image is not modified if tc.genData.LatestVersion { - assert.True(t, strings.HasSuffix(named.String(), ":latest")) + if tc.genData.ExecutionClient.Modified { + assert.True(t, strings.HasSuffix(named.String(), tc.genData.ExecutionClient.Image)) + } else { + assert.True(t, strings.HasSuffix(named.String(), ":latest")) + } } // Check that mev-boost service is not set when execution only @@ -387,9 +414,15 @@ func TestGenerateDockerCompose(t *testing.T) { named, err := reference.ParseNormalizedNamed(ccImageVersion) assert.NoError(t, err, "invalid image", ccImageVersion) - // Test that the consensus image is set to latest if flag --latest is provided + // Test that the consensus image is set to latest if flag --latest is provided, and the image is not modified if tc.genData.LatestVersion { - assert.True(t, strings.HasSuffix(named.String(), ":latest")) + if tc.genData.ConsensusClient.Modified { + assert.True(t, strings.HasSuffix(named.String(), tc.genData.ConsensusClient.Image)) + } else if tc.genData.ConsensusClient.Name == "nimbus" { + assert.True(t, strings.HasSuffix(named.String(), ":multiarch-latest")) + } else { + assert.True(t, strings.HasSuffix(named.String(), ":latest")) + } } // Validate Execution API and AUTH URLs apiEndpoint, authEndpoint := envData["EC_API_URL"], envData["EC_AUTH_URL"] @@ -448,9 +481,15 @@ func TestGenerateDockerCompose(t *testing.T) { named, err := reference.ParseNormalizedNamed(vlImageVersion) assert.NoError(t, err, "invalid image", vlImageVersion) - // Test that the consensus image is set to latest if flag --latest is provided + // Test that the consensus image is set to latest if flag --latest is provided, and the image is not modified if tc.genData.LatestVersion { - assert.True(t, strings.HasSuffix(named.String(), ":latest")) + if tc.genData.ValidatorClient.Modified { + assert.True(t, strings.HasSuffix(named.String(), tc.genData.ValidatorClient.Image)) + } else if tc.genData.ValidatorClient.Name == "nimbus" { + assert.True(t, strings.HasSuffix(named.String(), ":multiarch-latest")) + } else { + assert.True(t, strings.HasSuffix(named.String(), ":latest")) + } } // Check Consensus API URL is set and is valid diff --git a/cli/generate.go b/cli/generate.go index e9c400c18..cc83bb645 100644 --- a/cli/generate.go +++ b/cli/generate.go @@ -398,7 +398,7 @@ func valClients(allClients clients.OrderedClients, flags *GenCmdFlags, services if len(executionParts) > 1 { log.Warn(configs.CustomExecutionImagesWarning) executionClient.Image = strings.Join(executionParts[1:], ":") - flags.latestVersion = false + executionClient.Modified = true } } executionClient.SetImageOrDefault(strings.Join(executionParts[1:], ":")) @@ -425,7 +425,7 @@ func valClients(allClients clients.OrderedClients, flags *GenCmdFlags, services if len(consensusParts) > 1 { log.Warn(configs.CustomConsensusImagesWarning) consensusClient.Image = strings.Join(consensusParts[1:], ":") - flags.latestVersion = false + consensusClient.Modified = true } } consensusClient.SetImageOrDefault(strings.Join(consensusParts[1:], ":")) @@ -447,8 +447,7 @@ func valClients(allClients clients.OrderedClients, flags *GenCmdFlags, services if len(validatorParts) > 1 { log.Warn(configs.CustomValidatorImagesWarning) validatorClient.Image = strings.Join(validatorParts[1:], ":") - flags.latestVersion = false - + validatorClient.Modified = true } } validatorClient.SetImageOrDefault(strings.Join(validatorParts[1:], ":")) @@ -469,6 +468,7 @@ func valClients(allClients clients.OrderedClients, flags *GenCmdFlags, services opClient.Name = "opnode" if len(optimismParts) > 1 { opClient.Image = strings.Join(optimismParts[1:], ":") + opClient.Modified = true } } opClient.SetImageOrDefault(strings.Join(optimismParts[1:], ":")) @@ -485,6 +485,7 @@ func valClients(allClients clients.OrderedClients, flags *GenCmdFlags, services executionOpClient.Name = strings.ReplaceAll(optimismExecutionParts[0], "-", "") if len(optimismExecutionParts) > 1 { executionOpClient.Image = strings.Join(optimismExecutionParts[1:], ":") + executionOpClient.Modified = true } } executionOpClient.SetImageOrDefault(strings.Join(optimismExecutionParts[1:], ":")) @@ -510,6 +511,7 @@ func valClients(allClients clients.OrderedClients, flags *GenCmdFlags, services distributedValidatorClient.Name = distributedValidatorParts[0] if len(distributedValidatorParts) > 1 { distributedValidatorClient.Image = strings.Join(distributedValidatorParts[1:], ":") + distributedValidatorClient.Modified = true } distributedValidatorClient.SetImageOrDefault(strings.Join(distributedValidatorParts[1:], ":")) } else { diff --git a/internal/pkg/clients/types.go b/internal/pkg/clients/types.go index aa6138d0e..ab951ae34 100644 --- a/internal/pkg/clients/types.go +++ b/internal/pkg/clients/types.go @@ -24,6 +24,7 @@ type Client struct { Name string Type string Image string + Modified bool Endpoint string Supported bool } diff --git a/internal/pkg/generate/generate_scripts.go b/internal/pkg/generate/generate_scripts.go index 982eed425..a87ecae0e 100644 --- a/internal/pkg/generate/generate_scripts.go +++ b/internal/pkg/generate/generate_scripts.go @@ -697,10 +697,17 @@ func joinIfNotEmpty(strs ...string) string { // imageOrEmpty returns the image of the client if it is not nil, otherwise returns an empty string func imageOrEmpty(cls *clients.Client, latest bool) string { if cls != nil { - if latest { - splits := strings.Split(cls.Image, ":") - splits[len(splits)-1] = "latest" - return strings.Join(splits, ":") + if latest && !cls.Modified { + if cls.Name == "nimbus" { + splits := strings.Split(cls.Image, ":") + splits[len(splits)-1] = "multiarch-latest" + return strings.Join(splits, ":") + + } else { + splits := strings.Split(cls.Image, ":") + splits[len(splits)-1] = "latest" + return strings.Join(splits, ":") + } } return cls.Image }