feat(server): present Silo identity and close the inherited upstream services

Two coupled changes that must land together, because the same files carry both:
the server now identifies itself as Silo, and every path that would have called
home to a MinIO-operated service is closed.

Product identity
- build-constants.go: store name, UA name and startup banner become Silo. The
  Go identifiers (MinioStoreName, MinioBannerName, ...) keep their names on
  purpose - renaming exported symbols would churn the compatibility surface for
  a cosmetic gain, and the rebrand guard freezes that surface.
- main.go, server-startup-msg.go, ftp-server.go and the user-visible log, help
  and error strings across cmd/ and internal/ switch to Silo. Original MinIO
  copyright, LICENSE, NOTICE and CREDITS are untouched; --version now prints
  the upstream copyright, the pgsty modification notice, and the trademark
  policy's approved "based on MinIO technology" attribution.
- api-headers.go: the HTTP Server header becomes "Silo". This is the one
  externally observable identity change, so TestCommonHeadersUseSiloProductName
  pins it - probes that sniff for "MinIO" must move to capability detection.
- Prometheus metric HELP strings keep their MinIO wording. They are part of the
  metrics contract the guard protects, not product copy.

Configuration directory
- config-dir.go: new installs use ~/.silo. If only ~/.minio exists it is still
  read, with a one-time notice and no files moved. If both exist ~/.silo wins
  and an ambiguity warning is emitted; an explicit --config-dir always wins.
  Covered by TestSelectDefaultConfigDir. The internal .minio.sys layout is
  never renamed - this rule applies to the user config directory only.

Upstream service lockdown
- globalInplaceUpdateDisabled is now true at initialization rather than being
  set from MINIO_UPDATE. common-main.go still parses MINIO_UPDATE so upgrading
  nodes do not fail on an unknown key, but warns that the value is ignored;
  there is no way to re-enable the updater. TestInplaceUpdateCannotBeEnabled
  guards that. Without this, an admin with mc could have overwritten
  /usr/bin/silo with an upstream MinIO binary.
- verifyBinary and commitBinary refuse early; the ServerUpdate v1/v2 admin
  routes and the peer-rest update endpoints stay registered and keep returning
  the existing programmatic error, so clients see a stable failure rather than
  a 404.
- MinioReleaseBaseURL and defaultMinisignPubkey are emptied: no dl.min.io
  download root, and upstream's minisign key is no longer a trust root for
  anything this fork ships.
- cmd/callhome.go is deleted and internal/config/subnet/ is reduced to parsing
  its old keys and reporting that the integration is disabled. config-current.go
  warns instead of failing when callhome or SUBNET settings are present, so an
  upgraded node with those keys still starts.
- internal/config/errors.go replaces the MinIO Slack and support entry points
  with Silo documentation and issue links. Error codes and programmatic fields
  are unchanged.

Verified: the compatibility baseline is unchanged except for the deliberate
removal of the /api/health/upload SUBNET route; go build, go vet and the full
cmd/ and internal/ unit suites pass; a locally built binary starts, serves
S3/Admin/metrics on the unchanged /minio/* routes, answers with Server: Silo,
and falls back to a pre-existing ~/.minio with the expected notice.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Feng Ruohang
2026-08-06 08:46:58 +08:00
parent 15def34dce
commit 77bdc4c0cd
50 changed files with 469 additions and 581 deletions
+13 -23
View File
@@ -114,7 +114,7 @@ var ServerFlags = []cli.Flag{
},
cli.StringFlag{
Name: "interface",
Usage: "bind to right VRF device for MinIO services",
Usage: "bind to the VRF device used by Silo services",
Hidden: true,
EnvVar: "MINIO_INTERFACE",
},
@@ -220,20 +220,20 @@ FLAGS:
{{range .VisibleFlags}}{{.}}
{{end}}{{end}}
EXAMPLES:
1. Start MinIO server on "/home/shared" directory.
1. Start Silo server on "/home/shared" directory.
{{.Prompt}} {{.HelpName}} /home/shared
2. Start single node server with 64 local drives "/mnt/data1" to "/mnt/data64".
{{.Prompt}} {{.HelpName}} /mnt/data{1...64}
3. Start distributed MinIO server on an 32 node setup with 32 drives each, run following command on all the nodes
3. Start distributed Silo server on a 32-node setup with 32 drives each; run the following command on all nodes.
{{.Prompt}} {{.HelpName}} http://node{1...32}.example.com/mnt/export{1...32}
4. Start distributed MinIO server in an expanded setup, run the following command on all the nodes
4. Start distributed Silo server in an expanded setup; run the following command on all nodes.
{{.Prompt}} {{.HelpName}} http://node{1...16}.example.com/mnt/export{1...32} \
http://node{17...64}.example.com/mnt/export{1...64}
5. Start distributed MinIO server, with FTP and SFTP servers on all interfaces via port 8021, 8022 respectively
5. Start distributed Silo server with FTP and SFTP on ports 8021 and 8022.
{{.Prompt}} {{.HelpName}} http://node{1...4}.example.com/mnt/export{1...4} \
--ftp="address=:8021" --ftp="passive-port-range=30000-40000" \
--sftp="address=:8022" --sftp="ssh-private-key=${HOME}/.ssh/id_rsa"
@@ -597,7 +597,7 @@ func initServerConfig(ctx context.Context, newObject ObjectLayer) error {
// These messages only meant primarily for distributed setup, so only log during distributed setup.
if globalIsDistErasure {
logger.Info("Waiting for all MinIO sub-systems to be initialize...")
logger.Info("Waiting for all Silo subsystems to initialize...")
}
// Upon success migrating the config, initialize all sub-systems
@@ -607,13 +607,13 @@ func initServerConfig(ctx context.Context, newObject ObjectLayer) error {
// All successful return.
if globalIsDistErasure {
// These messages only meant primarily for distributed setup, so only log during distributed setup.
logger.Info("All MinIO sub-systems initialized successfully in %s", time.Since(t1))
logger.Info("All Silo subsystems initialized successfully in %s", time.Since(t1))
}
return nil
}
if configRetriableErrors(err) {
logger.Info("Waiting for all MinIO sub-systems to be initialized.. possible cause (%v)", err)
logger.Info("Waiting for all Silo subsystems to initialize; possible cause: %v", err)
time.Sleep(time.Duration(r.Float64() * float64(5*time.Second)))
continue
}
@@ -742,7 +742,7 @@ func initializeLogRotate(ctx *cli.Context) (io.WriteCloser, error) {
return output, nil
}
// serverMain handler called for 'minio server' command.
// serverMain handles the 'silo server' command.
func serverMain(ctx *cli.Context) {
r := rand.New(rand.NewSource(time.Now().UnixNano()))
@@ -851,16 +851,6 @@ func serverMain(ctx *cli.Context) {
getCert = globalTLSCerts.GetCertificate
}
// Check for updates in non-blocking manner.
go func() {
if !globalServerCtxt.Quiet && !globalInplaceUpdateDisabled {
// Check for new updates from dl.min.io.
bootstrapTrace("checkUpdate", func() {
checkUpdate(getMinioMode())
})
}
}()
// Set system resources to maximum.
bootstrapTrace("setMaxResources", func() {
_ = setMaxResources(globalServerCtxt)
@@ -868,13 +858,13 @@ func serverMain(ctx *cli.Context) {
// Verify kernel release and version.
if oldLinux() {
warnings = append(warnings, color.YellowBold("Detected Linux kernel version older than 4.0 release, there are some known potential performance problems with this kernel version. MinIO recommends a minimum of 4.x linux kernel version for best performance"))
warnings = append(warnings, color.YellowBold("Detected a Linux kernel older than 4.0; Silo recommends kernel 4.x or newer to avoid known performance problems"))
}
maxProcs := runtime.GOMAXPROCS(0)
cpuProcs := runtime.NumCPU()
if maxProcs < cpuProcs {
warnings = append(warnings, color.YellowBold("Detected GOMAXPROCS(%d) < NumCPU(%d), please make sure to provide all PROCS to MinIO for optimal performance",
warnings = append(warnings, color.YellowBold("Detected GOMAXPROCS(%d) < NumCPU(%d); provide all processors to Silo for optimal performance",
maxProcs, cpuProcs))
}
@@ -1161,7 +1151,7 @@ func serverMain(ctx *cli.Context) {
Transport: globalRemoteTargetTransport,
Region: region,
})
logger.FatalIf(err, "Unable to initialize MinIO client")
logger.FatalIf(err, "Unable to initialize the internal S3 client")
})
go bootstrapTrace("startResourceMetricsCollection", func() {
@@ -1169,7 +1159,7 @@ func serverMain(ctx *cli.Context) {
})
// Add User-Agent to differentiate the requests.
globalMinioClient.SetAppInfo("minio-perf-test", ReleaseTag)
globalMinioClient.SetAppInfo("silo-perf-test", ReleaseTag)
if serverDebugLog {
fmt.Println("== DEBUG Mode enabled ==")