Commit c2349da2 authored by Antti Kervinen's avatar Antti Kervinen Committed by Jim Harris
Browse files

pkgdep: add -G/--golang: install golang and protoc



- Install dependencies for generating Go/gRPC API for SMA:
  go, protoc and protoc-go plugins.
- Introduce scripts/pkgdep.path.sh to prevent conflicts between
  tools in the system and tools versions installed with pkgdep.
  Sourcing this generated file changes PATH to pkgdep versions.

Signed-off-by: default avatarAntti Kervinen <antti.kervinen@intel.com>
Change-Id: I4a2602cc5bdfa55115fca0f54151def722c9a00d
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15346


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarMichal Berger <michal.berger@intel.com>
parent eac5d183
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ function usage() {
	echo "  -u --uring                  Additional dependencies for io_uring"
	echo "  -D --daos                   Additional dependencies for DAOS"
	echo "  -A --avahi                  Additional dependencies for Avahi mDNS Discovery"
	echo "  -G --golang                 Additional dependencies for go API generation (excluded from --all)"
	echo ""
	exit 0
}
@@ -51,8 +52,9 @@ INSTALL_DOCS=false
INSTALL_LIBURING=false
INSTALL_DAOS=false
INSTALL_AVAHI=false
INSTALL_GOLANG=false

while getopts 'abdfhipruADR-:' optchar; do
while getopts 'abdfhipruADGR-:' optchar; do
	case "$optchar" in
		-)
			case "$OPTARG" in
@@ -67,6 +69,7 @@ while getopts 'abdfhipruADR-:' optchar; do
				uring) INSTALL_LIBURING=true ;;
				daos) INSTALL_DAOS=true ;;
				avahi) INSTALL_AVAHI=true ;;
				golang) INSTALL_GOLANG=true ;;
				*)
					echo "Invalid argument '$OPTARG'"
					usage
@@ -84,6 +87,7 @@ while getopts 'abdfhipruADR-:' optchar; do
		u) INSTALL_LIBURING=true ;;
		D) INSTALL_DAOS=true ;;
		A) INSTALL_AVAHI=true ;;
		G) INSTALL_GOLANG=true ;;
		*)
			echo "Invalid argument '$OPTARG'"
			usage
+137 −0
Original line number Diff line number Diff line
@@ -109,6 +109,138 @@ install_markdownlint() {
	fi
}

version-at-least() {
	local atleastver="$1"
	local askver="$2"
	local smallest
	smallest=$(echo -e "${atleastver}\n${askver}" | sort -V | head -n 1)
	[[ "${smallest}" == "${atleastver}" ]]
}

install_protoc() {
	local PROTOCVERSION=${PROTOCVERSION:-21.7}
	local PROTOCGENGOVERSION=${PROTOCGENGOVERSION:-1.28}
	local PROTOCGENGOGRPCVERSION=${PROTOCGENGOGRPCVERSION:-1.2}
	local protocdir protocpkg protocurl protocver arch
	local skip_protoc=0
	# It is easy to find an incompatible combination of protoc,
	# protoc-gen-go and protoc-gen-go-grpc. Therefore install a
	# preferred version combination even if more recent versions
	# of some of these tools would be available in the system.
	protocver=$(protoc --version 2> /dev/null | {
		read -r _ v
		echo $v
	})
	if [[ "3.${PROTOCVERSION}" == "${protocver}" ]]; then
		echo "found protoc version ${protocver} exactly required 3.${PROTOCVERSION}, skip installing"
		skip_protoc=1
	fi
	protocdir=/opt/protoc/${PROTOCVERSION}
	if [[ -x "${protocdir}/bin/protoc" ]]; then
		echo "protoc already installed to ${protocdir}, skip installing"
		skip_protoc=1
	fi
	if [[ "${skip_protoc}" != "1" ]]; then
		echo "installing protoc v${PROTOCVERSION} to ${protocdir}"
		mkdir -p "${protocdir}"
		arch=x86_64
		if [[ "$(arch)" == "aarch64" ]]; then
			arch=aarch_64
		fi
		protocpkg=protoc-${PROTOCVERSION}-linux-${arch}.zip
		protocurl=https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOCVERSION}/${protocpkg}
		curl -f -LO "${protocurl}" || {
			echo "downloading protoc ${PROTOCVERSION} from ${protocurl} failed"
			return 1
		}
		unzip -d "${protocdir}" "${protocpkg}" || {
			echo "extracting protoc ${PROTOCVERSION} from ${protocpkg} failed"
			rm -f "${protocpkg}"
			return 1
		}
		rm -f "${protocpkg}"
	fi
	if [[ -x "${protocdir}/bin/protoc-gen-go" ]]; then
		echo "${protocdir}/bin/protoc-gen-go already installed"
	else
		echo "installing protoc-gen-go v${PROTOCGENGOVERSION} to ${protocdir}/bin"
		mkdir -p "${protocdir}/bin"
		GOBIN="${protocdir}/bin" go install "google.golang.org/protobuf/cmd/protoc-gen-go@v${PROTOCGENGOVERSION}" || {
			echo "protoc protoc-gen-go plugin install failed"
			return 1
		}
	fi
	if [[ -x "${protocdir}/bin/protoc-gen-go-grpc" ]]; then
		echo "${protocdir}/bin/protoc-gen-go-grpc already installed"
	else
		echo "installing protoc-gen-go-grpc v${PROTOCGENGOGRPCVERSION} to ${protocdir}/bin"
		mkdir -p "${protocdir}/bin"
		GOBIN="${protocdir}/bin" go install "google.golang.org/grpc/cmd/protoc-gen-go-grpc@v${PROTOCGENGOGRPCVERSION}" || {
			echo "protoc protoc-gen-go-grpc plugin install failed"
			return 1
		}
	fi
	pkgdep_toolpath protoc "${protocdir}/bin"
}

install_golang() {
	local GOVERSION=${GOVERSION:-1.19}
	local godir gopkg gover arch
	gover=$(go version 2> /dev/null | {
		read -r _ _ v _
		echo ${v#go}
	})
	if [[ -n "${gover}" ]] && version-at-least "${GOVERSION}" "${gover}"; then
		echo "found go version ${gover} >= required ${GOVERSION}, skip installing"
		return 0
	fi
	godir=/opt/go/${GOVERSION}
	if [[ -x "${godir}/bin/go" ]]; then
		echo "go already installed in ${godir}, skip installing"
		return 0
	fi
	mkdir -p "${godir}"
	arch=amd64
	if [[ "$(arch)" == "aarch64" ]]; then
		arch=arm64
	fi
	gopkg=go${GOVERSION}.linux-${arch}.tar.gz
	echo "installing go v${GOVERSION} to ${godir}/bin"
	curl -s https://dl.google.com/go/${gopkg} | tar -C "${godir}" -xzf - --strip 1
	${godir}/bin/go version || {
		echo "go install failed"
		return 1
	}
	export PATH=${godir}/bin:$PATH
	export GOBIN=${godir}/bin
	pkgdep_toolpath go "${godir}/bin"
}

pkgdep_toolpath() {
	# Usage: pkgdep_toolpath TOOL DIR
	#
	# Regenerates /etc/opt/spdk-pkgdep/paths to ensure that
	# TOOL in DIR will be in PATH before other versions
	# of the TOOL installed in the system.
	local toolname="$1"
	local toolpath="$2"
	local toolpath_dir="/etc/opt/spdk-pkgdep/paths"
	local toolpath_file="${toolpath_dir}/${toolname}.path"
	local export_file="${toolpath_dir}/export.sh"
	mkdir -p "$(dirname "${toolpath_file}")"
	echo "${toolpath}" > "${toolpath_file}" || {
		echo "cannot write toolpath ${toolpath} to ${toolpath_file}"
		return 1
	}
	echo "# generated, source this file in shell" > "${export_file}"
	for pathfile in "${toolpath_dir}"/*.path; do
		echo "PATH=$(< ${pathfile}):\$PATH" >> "${export_file}"
	done
	echo "export PATH" >> "${export_file}"
	echo "echo \$PATH" >> "${export_file}"
	chmod a+x "${export_file}"
}

if [[ $INSTALL_DEV_TOOLS == true ]]; then
	install_shfmt
	install_spdk_bash_completion
@@ -122,3 +254,8 @@ fi
if [[ $INSTALL_LIBURING == true ]]; then
	install_liburing
fi

if [[ $INSTALL_GOLANG == true ]]; then
	install_golang
	install_protoc
fi