Skip to content

Commit

Permalink
Support arm64 architecture
Browse files Browse the repository at this point in the history
  • Loading branch information
felipeparaujo authored and saniales committed Apr 13, 2023
1 parent c4c97da commit de2d8c1
Show file tree
Hide file tree
Showing 3 changed files with 259 additions and 9 deletions.
66 changes: 58 additions & 8 deletions mongobin/downloadSpec.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package mongobin

import (
"fmt"
"io/ioutil"
"runtime"
"strconv"
Expand All @@ -27,7 +28,10 @@ type DownloadSpec struct {
// (needed for <4.2)
SSLBuildNeeded bool

// Arch is always "x86_64"
// Arch is one of:
// - x86_64
// - arm64
// - aarch64
Arch string

// OSName is one of:
Expand Down Expand Up @@ -67,17 +71,16 @@ func MakeDownloadSpec(version string) (*DownloadSpec, error) {
ssl = true
}

arch, archErr := detectArch()
if archErr != nil {
return nil, archErr
}

osName := detectOSName(parsedVersion)

if platform == "linux" && osName == "" && versionGTE(parsedVersion, []int{4, 2, 0}) {
return nil, &UnsupportedSystemError{msg: "MongoDB 4.2 removed support for generic linux tarballs. Specify the download URL manually or use a supported distro. See: https://www.mongodb.com/blog/post/a-proposal-to-endoflife-our-generic-linux-tar-packages"}
}

arch, archErr := detectArch(platform, osName, parsedVersion)
if archErr != nil {
return nil, archErr
}

return &DownloadSpec{
Version: version,
Arch: arch,
Expand Down Expand Up @@ -141,15 +144,62 @@ func detectPlatform() (string, error) {
}
}

func detectArch() (string, error) {
func detectArch(platform string, osName string, mongoVersion []int) (string, error) {
switch GoArch {
case "amd64":
return "x86_64", nil
case "arm64":
return arm64ArchFromOSNameAndVersion(platform, osName, mongoVersion)
default:
return "", &UnsupportedSystemError{msg: "your architecture, " + GoArch + ", is not supported"}
}
}

func arm64ArchFromOSNameAndVersion(platform string, osName string, mongoVersion []int) (string, error) {
// version numbers extracted from https://www.mongodb.com/download-center/community/releases/archive
if !versionGTE(mongoVersion, []int{3, 4, 0}) {
return "", &UnsupportedSystemError{msg: "arm64 support was introduced in Mongo 3.4.0"}
}

// ubuntu1604 arm support was introduced in version 3.4.0 and removed in version 4.0.27
if osName == "ubuntu1604" && !versionGTE(mongoVersion, []int{4, 0, 27}) {
return "arm64", nil
}

if osName == "ubuntu1804" && versionGTE(mongoVersion, []int{4, 2, 0}) {
return "aarch64", nil
}

if osName == "ubuntu2004" && versionGTE(mongoVersion, []int{4, 4, 0}) {
return "aarch64", nil
}

if osName == "ubuntu2204" && versionGTE(mongoVersion, []int{6, 0, 4}) {
return "aarch64", nil
}

if osName == "amazon2" && versionGTE(mongoVersion, []int{4, 2, 13}) {
return "aarch64", nil
}

// TODO: "rhel82" isn't a value that osName can have yet as osNameFromOsRelease doesn't support this version
if osName == "rhel82" && versionGTE(mongoVersion, []int{4, 4, 4}) {
return "aarch64", nil
}

if platform == "osx" && versionGTE(mongoVersion, []int{6, 0, 0}) {
return "arm64", nil
}

os := osName
if os == "" {
os = platform
}

versionString := fmt.Sprintf("%d.%d.%d", mongoVersion[0], mongoVersion[1], mongoVersion[2])
return "", &UnsupportedSystemError{msg: "Mongo doesn't support your environment, " + os + "/" + GoArch + ", on version " + versionString}
}

func detectOSName(mongoVersion []int) string {
if GoOS != "linux" {
// Not on Linux
Expand Down
135 changes: 134 additions & 1 deletion mongobin/downloadSpec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

const (
testMongoVersion = "4.0.5"
latestMongoVersion = "6.0.0"
latestMongoVersion = "6.0.4"
)

func TestMakeDownloadSpec(t *testing.T) {
Expand Down Expand Up @@ -46,6 +46,19 @@ func TestMakeDownloadSpec(t *testing.T) {
OSName: "",
},
},
"arm64 mac and newer mongo": {
goOs: "darwin",
goArch: "arm64",
mongoVersion: latestMongoVersion,

expectedSpec: &mongobin.DownloadSpec{
Version: latestMongoVersion,
Platform: "osx",
SSLBuildNeeded: false,
Arch: "arm64",
OSName: "",
},
},
"windows": {
goOs: "windows",

Expand All @@ -63,6 +76,19 @@ func TestMakeDownloadSpec(t *testing.T) {
OSName: "ubuntu2204",
},
},
"arm64 ubuntu 22.04 newer mongo": {
mongoVersion: latestMongoVersion,
etcFolder: "ubuntu2204",
goArch: "arm64",

expectedSpec: &mongobin.DownloadSpec{
Version: latestMongoVersion,
Platform: "linux",
SSLBuildNeeded: false,
Arch: "aarch64",
OSName: "ubuntu2204",
},
},
"ubuntu 22.04": {
mongoVersion: testMongoVersion,
etcFolder: "ubuntu2204",
Expand All @@ -87,6 +113,19 @@ func TestMakeDownloadSpec(t *testing.T) {
OSName: "ubuntu2004",
},
},
"arm64 ubuntu 20.04 and newer mongo": {
mongoVersion: latestMongoVersion,
etcFolder: "ubuntu2004",
goArch: "arm64",

expectedSpec: &mongobin.DownloadSpec{
Version: latestMongoVersion,
Platform: "linux",
SSLBuildNeeded: false,
Arch: "aarch64",
OSName: "ubuntu2004",
},
},
"ubuntu 18.04": {
mongoVersion: testMongoVersion,
etcFolder: "ubuntu1804",
Expand All @@ -99,6 +138,19 @@ func TestMakeDownloadSpec(t *testing.T) {
OSName: "ubuntu1804",
},
},
"arm64 ubuntu 18.04 and newer mongo": {
mongoVersion: latestMongoVersion,
etcFolder: "ubuntu1804",
goArch: "arm64",

expectedSpec: &mongobin.DownloadSpec{
Version: latestMongoVersion,
Platform: "linux",
SSLBuildNeeded: false,
Arch: "aarch64",
OSName: "ubuntu1804",
},
},
"ubuntu 18.04 older mongo": {
mongoVersion: "4.0.0",
etcFolder: "ubuntu1804",
Expand Down Expand Up @@ -135,6 +187,19 @@ func TestMakeDownloadSpec(t *testing.T) {
OSName: "ubuntu1604",
},
},
"arm64 ubuntu 16.04": {
mongoVersion: testMongoVersion,
etcFolder: "ubuntu1604",
goArch: "arm64",

expectedSpec: &mongobin.DownloadSpec{
Version: testMongoVersion,
Platform: "linux",
SSLBuildNeeded: false,
Arch: "arm64",
OSName: "ubuntu1604",
},
},
"ubuntu 16.04 older mongo": {
mongoVersion: "3.2.6",
etcFolder: "ubuntu1604",
Expand Down Expand Up @@ -339,6 +404,19 @@ func TestMakeDownloadSpec(t *testing.T) {
OSName: "amazon2",
},
},
"ARM64 Amazon Linux 2 and newer mongo": {
mongoVersion: latestMongoVersion,
etcFolder: "amazon2",
goArch: "arm64",

expectedSpec: &mongobin.DownloadSpec{
Version: latestMongoVersion,
Platform: "linux",
SSLBuildNeeded: false,
Arch: "aarch64",
OSName: "amazon2",
},
},
"Amazon Linux 2 older mongo": {
mongoVersion: "3.6.5",
etcFolder: "amazon2",
Expand Down Expand Up @@ -428,6 +506,61 @@ func TestMakeDownloadSpec(t *testing.T) {
OSName: "",
},
},
"MongoDB Unsupported arch for version": {
mongoVersion: "3.3.0",
goArch: "arm64",

expectedError: "memongo does not support automatic downloading on your system: arm64 support was introduced in Mongo 3.4.0",
},
"MongoDB Unsupported newer version for arm64 ubuntu1604": {
mongoVersion: "6.0.0",
etcFolder: "ubuntu1604",
goArch: "arm64",

expectedError: "memongo does not support automatic downloading on your system: Mongo doesn't support your environment, ubuntu1604/arm64, on version 6.0.0",
},
"MongoDB Unsupported older version for arm64 ubuntu1804": {
mongoVersion: "4.1.0",
etcFolder: "ubuntu1804",
goArch: "arm64",

expectedError: "memongo does not support automatic downloading on your system: Mongo doesn't support your environment, ubuntu1804/arm64, on version 4.1.0",
},
"MongoDB Unsupported older version for arm64 ubuntu2004": {
mongoVersion: "4.1.0",
etcFolder: "ubuntu2004",
goArch: "arm64",

expectedError: "memongo does not support automatic downloading on your system: Mongo doesn't support your environment, ubuntu2004/arm64, on version 4.1.0",
},
"MongoDB Unsupported older version for arm64 ubuntu2204": {
mongoVersion: "4.1.0",
etcFolder: "ubuntu2204",
goArch: "arm64",

expectedError: "memongo does not support automatic downloading on your system: Mongo doesn't support your environment, ubuntu2204/arm64, on version 4.1.0",
},
"MongoDB Unsupported older version for arm64 amazon2": {
mongoVersion: "4.1.0",
etcFolder: "amazon2",
goArch: "arm64",

expectedError: "memongo does not support automatic downloading on your system: Mongo doesn't support your environment, amazon2/arm64, on version 4.1.0",
},
"MongoDB Unsupported older version for arm64 rhel82": {
mongoVersion: "4.1.0",
etcFolder: "rhel82",
goArch: "arm64",

expectedError: "memongo does not support automatic downloading on your system: Mongo doesn't support your environment, linux/arm64, on version 4.1.0",
},
"MongoDB Unsupported version for arm mac": {
mongoVersion: "4.1.0",
goOs: "darwin",
goArch: "arm64",

expectedError: "memongo does not support automatic downloading on your system: Mongo doesn't support your environment, osx/arm64, on version 4.1.0",
},
"MongoDB 3.0": {
mongoVersion: "3.0.2",

Expand Down
67 changes: 67 additions & 0 deletions mongobin/downloadURL_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ func TestGetDownloadURL(t *testing.T) {
},
expectedURL: "https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-VERSION.tgz",
},
"arm64 mac": {
spec: &mongobin.DownloadSpec{
Platform: "osx",
Arch: "arm64",
OSName: "",
},
mongoVersions: []string{
"6.0.0",
},
expectedURL: "https://fastdl.mongodb.org/osx/mongodb-macos-arm64-VERSION.tgz",
},
"ubuntu 18.04": {
spec: &mongobin.DownloadSpec{
Platform: "linux",
Expand All @@ -58,6 +69,33 @@ func TestGetDownloadURL(t *testing.T) {
mongoVersions: []string{"4.0.1", "4.0.13", "4.2.1"},
expectedURL: "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1804-VERSION.tgz",
},
"arm64 ubuntu 18.04": {
spec: &mongobin.DownloadSpec{
Platform: "linux",
Arch: "aarch64",
OSName: "ubuntu1804",
},
mongoVersions: []string{"4.2.1", "4.4.0", "6.0.0"},
expectedURL: "https://fastdl.mongodb.org/linux/mongodb-linux-aarch64-ubuntu1804-VERSION.tgz",
},
"arm64 ubuntu 20.04": {
spec: &mongobin.DownloadSpec{
Platform: "linux",
Arch: "aarch64",
OSName: "ubuntu2004",
},
mongoVersions: []string{"4.4.0", "6.0.0"},
expectedURL: "https://fastdl.mongodb.org/linux/mongodb-linux-aarch64-ubuntu2004-VERSION.tgz",
},
"arm64 ubuntu 22.04": {
spec: &mongobin.DownloadSpec{
Platform: "linux",
Arch: "aarch64",
OSName: "ubuntu2204",
},
mongoVersions: []string{"6.0.4"},
expectedURL: "https://fastdl.mongodb.org/linux/mongodb-linux-aarch64-ubuntu2204-VERSION.tgz",
},
"ubuntu 16.04": {
spec: &mongobin.DownloadSpec{
Platform: "linux",
Expand All @@ -69,6 +107,17 @@ func TestGetDownloadURL(t *testing.T) {
},
expectedURL: "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-VERSION.tgz",
},
"arm64 ubuntu 16.04": {
spec: &mongobin.DownloadSpec{
Platform: "linux",
Arch: "arm64",
OSName: "ubuntu1604",
},
mongoVersions: []string{
"3.4.0", "3.4.19", "3.6.0", "3.6.10", "4.0.0", "4.0.13",
},
expectedURL: "https://fastdl.mongodb.org/linux/mongodb-linux-arm64-ubuntu1604-VERSION.tgz",
},
"ubuntu 14.04": {
spec: &mongobin.DownloadSpec{
Platform: "linux",
Expand All @@ -89,6 +138,15 @@ func TestGetDownloadURL(t *testing.T) {
mongoVersions: mongoVersionsToTest,
expectedURL: "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse12-VERSION.tgz",
},
"ARM64 RHEL 8.2": {
spec: &mongobin.DownloadSpec{
Platform: "linux",
Arch: "aarch64",
OSName: "rhel82",
},
mongoVersions: []string{"4.4.4", "5.0.1", "6.0.4"},
expectedURL: "https://fastdl.mongodb.org/linux/mongodb-linux-aarch64-rhel82-VERSION.tgz",
},
"RHEL 7": {
spec: &mongobin.DownloadSpec{
Platform: "linux",
Expand Down Expand Up @@ -162,6 +220,15 @@ func TestGetDownloadURL(t *testing.T) {
},
expectedURL: "https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-amazon2-VERSION.tgz",
},
"ARM64 Amazon Linux 2": {
spec: &mongobin.DownloadSpec{
Platform: "linux",
Arch: "aarch64",
OSName: "amazon2",
},
mongoVersions: []string{"4.4.4", "5.0.1", "6.0.4"},
expectedURL: "https://fastdl.mongodb.org/linux/mongodb-linux-aarch64-amazon2-VERSION.tgz",
},
"Other Linux": {
spec: &mongobin.DownloadSpec{
Platform: "linux",
Expand Down

0 comments on commit de2d8c1

Please sign in to comment.