mirror of
https://github.com/harness/drone.git
synced 2025-05-31 11:43:15 +00:00
feat: [CDE-332]: Install tools (#2907)
* feat: [CDE-332]: Install tools * feat: [CDE-332]: Install tools * feat: [CDE-332]: Install tools * feat: [CDE-332]: Install tools * feat: [CDE-332]: Install tools * feat: [CDE-332]: lint issues * feat: [CDE-332]: Install tools
This commit is contained in:
parent
75f695dc51
commit
9e9790a67d
@ -1,4 +1,4 @@
|
||||
# Detect OS type
|
||||
|
||||
os() {
|
||||
uname="$(uname)"
|
||||
case $uname in
|
||||
@ -9,7 +9,6 @@ os() {
|
||||
esac
|
||||
}
|
||||
|
||||
# Detect Linux distro type
|
||||
distro() {
|
||||
local os_name
|
||||
os_name=$(os)
|
||||
@ -38,7 +37,6 @@ distro() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Print a human-readable name for the OS/distro
|
||||
distro_name() {
|
||||
if [ "$(uname)" = "Darwin" ]; then
|
||||
echo "macOS v$(sw_vers -productVersion)"
|
||||
|
114
app/gitspace/orchestrator/common/utils.go
Normal file
114
app/gitspace/orchestrator/common/utils.go
Normal file
@ -0,0 +1,114 @@
|
||||
// Copyright 2023 Harness, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator/template"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
)
|
||||
|
||||
const templateSupportedOSDistribution = "supported_os_distribution.sh"
|
||||
const templateVsCodeWebToolsInstallation = "install_tools_vs_code_web.sh"
|
||||
const templateVsCodeToolsInstallation = "install_tools_vs_code.sh"
|
||||
|
||||
func ValidateSupportedOS(ctx context.Context, exec *devcontainer.Exec) ([]byte, error) {
|
||||
// TODO: Currently not supporting arch, freebsd and alpine.
|
||||
// For alpine wee need to install multiple things from
|
||||
// https://github.com/microsoft/vscode/wiki/How-to-Contribute#prerequisites
|
||||
script, err := template.GenerateScriptFromTemplate(
|
||||
templateSupportedOSDistribution, &template.SupportedOSDistributionPayload{
|
||||
OSInfoScript: osDetectScript,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate scipt to validate supported os distribution from template %s: %w",
|
||||
templateSupportedOSDistribution, err)
|
||||
}
|
||||
|
||||
output, err := exec.ExecuteCommandInHomeDirectory(ctx, script, true, false)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error while detecting os distribution: %w", err)
|
||||
}
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func InstallTools(ctx context.Context, exec *devcontainer.Exec, ideType enum.IDEType) ([]byte, error) {
|
||||
switch ideType {
|
||||
case enum.IDETypeVSCodeWeb:
|
||||
{
|
||||
output, err := InstallToolsForVsCodeWeb(ctx, exec)
|
||||
if err != nil {
|
||||
return []byte(output), err
|
||||
}
|
||||
return []byte(output), nil
|
||||
}
|
||||
case enum.IDETypeVSCode:
|
||||
{
|
||||
output, err := InstallToolsForVsCode(ctx, exec)
|
||||
if err != nil {
|
||||
return []byte(output), err
|
||||
}
|
||||
return []byte(output), nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func InstallToolsForVsCodeWeb(ctx context.Context, exec *devcontainer.Exec) (string, error) {
|
||||
script, err := template.GenerateScriptFromTemplate(
|
||||
templateVsCodeWebToolsInstallation, &template.InstallToolsPayload{
|
||||
OSInfoScript: osDetectScript,
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf(
|
||||
"failed to generate scipt to install tools for vs code web from template %s: %w",
|
||||
templateVsCodeWebToolsInstallation, err)
|
||||
}
|
||||
|
||||
output := "Installing tools for vs code web inside container\n"
|
||||
_, err = exec.ExecuteCommandInHomeDirectory(ctx, script, true, false)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to install tools for vs code web: %w", err)
|
||||
}
|
||||
|
||||
output += "Successfully installed tools for vs code web\n"
|
||||
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func InstallToolsForVsCode(ctx context.Context, exec *devcontainer.Exec) (string, error) {
|
||||
script, err := template.GenerateScriptFromTemplate(
|
||||
templateVsCodeToolsInstallation, &template.InstallToolsPayload{
|
||||
OSInfoScript: osDetectScript,
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf(
|
||||
"failed to generate scipt to install tools for vs code from template %s: %w",
|
||||
templateVsCodeToolsInstallation, err)
|
||||
}
|
||||
|
||||
output := "Installing tools for vs code inside container\n"
|
||||
_, err = exec.ExecuteCommandInHomeDirectory(ctx, script, true, false)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to install tools for vs code: %w", err)
|
||||
}
|
||||
|
||||
output += "Successfully installed tools for vs code\n"
|
||||
|
||||
return output, nil
|
||||
}
|
@ -24,6 +24,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/harness/gitness/app/gitspace/logutil"
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator/common"
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator/git"
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator/ide"
|
||||
@ -31,6 +32,7 @@ import (
|
||||
"github.com/harness/gitness/app/gitspace/scm"
|
||||
"github.com/harness/gitness/infraprovider"
|
||||
"github.com/harness/gitness/types"
|
||||
"github.com/harness/gitness/types/enum"
|
||||
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
@ -274,11 +276,21 @@ func (e *EmbeddedDockerOrchestrator) startGitspace(
|
||||
AccessType: gitspaceConfig.GitspaceInstance.AccessType,
|
||||
}
|
||||
|
||||
err = e.validateSupportedOS(ctx, exec, logStreamInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = e.manageUser(ctx, exec, logStreamInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = e.installTools(ctx, exec, logStreamInstance, gitspaceConfig.IDE)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = e.setupIDE(ctx, exec, ideService, logStreamInstance)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -544,9 +556,9 @@ func (e *EmbeddedDockerOrchestrator) executePostCreateCommand(
|
||||
return fmt.Errorf("logging error: %w", loggingErr)
|
||||
}
|
||||
|
||||
output, err := exec.ExecuteCommand(ctx, devcontainerConfig.PostCreateCommand, false, false, codeRepoDir)
|
||||
output, err := exec.ExecuteCommand(ctx, devcontainerConfig.PostCreateCommand, true, false, codeRepoDir)
|
||||
if err != nil {
|
||||
loggingErr = logStreamInstance.Write("Error while executing postCreate command")
|
||||
loggingErr = logStreamInstance.Write("Error while executing postCreate command" + err.Error())
|
||||
|
||||
err = fmt.Errorf("failed to execute postCreate command %q: %w", devcontainerConfig.PostCreateCommand, err)
|
||||
|
||||
@ -951,6 +963,59 @@ func (e *EmbeddedDockerOrchestrator) removeContainer(
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *EmbeddedDockerOrchestrator) validateSupportedOS(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
logStreamInstance *logutil.LogStreamInstance,
|
||||
) error {
|
||||
output, err := common.ValidateSupportedOS(ctx, exec)
|
||||
if err != nil {
|
||||
loggingErr := logStreamInstance.Write("Error while detecting os inside container: " + err.Error())
|
||||
|
||||
err = fmt.Errorf("failed to detect os in %s: %w", exec.ContainerName, err)
|
||||
|
||||
if loggingErr != nil {
|
||||
err = fmt.Errorf("original error: %w; logging error: %w", err, loggingErr)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
loggingErr := logStreamInstance.Write("Validate supported OSes...\n" + string(output))
|
||||
if loggingErr != nil {
|
||||
return fmt.Errorf("logging error: %w", loggingErr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *EmbeddedDockerOrchestrator) installTools(
|
||||
ctx context.Context,
|
||||
exec *devcontainer.Exec,
|
||||
logStreamInstance *logutil.LogStreamInstance,
|
||||
ideType enum.IDEType,
|
||||
) error {
|
||||
output, err := common.InstallTools(ctx, exec, ideType)
|
||||
if err != nil {
|
||||
loggingErr := logStreamInstance.Write("Error while installing tools inside container: " + err.Error())
|
||||
|
||||
err = fmt.Errorf("failed to install tools in %s: %w", exec.ContainerName, err)
|
||||
|
||||
if loggingErr != nil {
|
||||
err = fmt.Errorf("original error: %w; logging error: %w", err, loggingErr)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
loggingErr := logStreamInstance.Write("Tools installation output...\n" + string(output))
|
||||
if loggingErr != nil {
|
||||
return fmt.Errorf("logging error: %w", loggingErr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *EmbeddedDockerOrchestrator) StreamLogs(
|
||||
_ context.Context,
|
||||
_ types.GitspaceConfig,
|
||||
|
@ -48,7 +48,7 @@ func (g *ServiceImpl) Install(ctx context.Context, exec *devcontainer.Exec) ([]b
|
||||
"failed to generate scipt to setup git install from template %s: %w", templateGitInstallScript, err)
|
||||
}
|
||||
output := "Setting up git inside container\n"
|
||||
_, err = exec.ExecuteCommandInHomeDirectory(ctx, script, false, false)
|
||||
_, err = exec.ExecuteCommandInHomeDirectory(ctx, script, true, false)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to setup git: %w", err)
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ func (v *VSCode) Run(ctx context.Context, exec *devcontainer.Exec) ([]byte, erro
|
||||
|
||||
execOutput, err := exec.ExecuteCommandInHomeDirectory(ctx, runSSHScript, true, false)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to run SSH serverr: %w", err)
|
||||
return nil, fmt.Errorf("failed to run SSH server: %w", err)
|
||||
}
|
||||
|
||||
output += "SSH server run output...\n" + string(execOutput) + "\nSuccessfully run ssh-server\n"
|
||||
|
@ -74,6 +74,14 @@ type RunSSHServerPayload struct {
|
||||
Port string
|
||||
}
|
||||
|
||||
type InstallToolsPayload struct {
|
||||
OSInfoScript string
|
||||
}
|
||||
|
||||
type SupportedOSDistributionPayload struct {
|
||||
OSInfoScript string
|
||||
}
|
||||
|
||||
func init() {
|
||||
err := LoadTemplates()
|
||||
if err != nil {
|
||||
|
@ -9,34 +9,30 @@ install_git() {
|
||||
# Check if Git is installed
|
||||
if ! command -v git >/dev/null 2>&1; then
|
||||
echo "Git is not installed. Installing Git..."
|
||||
|
||||
case "$(distro)" in
|
||||
debian | ubuntu)
|
||||
apt-get update && apt-get install -y git
|
||||
;;
|
||||
fedora | centos | rhel)
|
||||
dnf install -y git
|
||||
;;
|
||||
opensuse)
|
||||
zypper install -y git
|
||||
;;
|
||||
alpine)
|
||||
apk add git
|
||||
;;
|
||||
arch | manjaro)
|
||||
pacman -Sy --noconfirm git
|
||||
;;
|
||||
freebsd)
|
||||
pkg install -y git
|
||||
;;
|
||||
macos)
|
||||
brew install git
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported OS for automatic Git installation."
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
debian)
|
||||
apt-get update && apt-get install -y git
|
||||
;;
|
||||
fedora)
|
||||
dnf install -y git
|
||||
;;
|
||||
opensuse)
|
||||
zypper install -y git
|
||||
;;
|
||||
alpine)
|
||||
apk add git
|
||||
;;
|
||||
arch)
|
||||
pacman -Sy --noconfirm git
|
||||
;;
|
||||
freebsd)
|
||||
pkg install -y git
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported OS for automatic Git installation."
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Verify installation
|
||||
|
@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
|
||||
osInfoScript={{ .OSInfoScript }}
|
||||
|
||||
eval "$osInfoScript"
|
||||
|
||||
echo "Checking if tar is installed..."
|
||||
if ! command -v tar >/dev/null 2>&1; then
|
||||
echo "Installing tar for $(distro)"
|
||||
case "$(distro)" in
|
||||
opensuse)
|
||||
zypper install -y tar
|
||||
zypper install -y gzip
|
||||
;;
|
||||
*)
|
||||
echo "Distribution: $distro. tar installation not required"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
echo "tar installation completed."
|
||||
fi
|
@ -0,0 +1,57 @@
|
||||
#!/bin/sh
|
||||
|
||||
osInfoScript={{ .OSInfoScript }}
|
||||
|
||||
eval "$osInfoScript"
|
||||
|
||||
# Check if curl is installed
|
||||
echo "Checking if curl is installed..."
|
||||
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
echo "Installing curl for $(distro)"
|
||||
case "$(distro)" in
|
||||
debian)
|
||||
apt update && apt install -y curl
|
||||
;;
|
||||
fedora)
|
||||
dnf install -y curl
|
||||
;;
|
||||
opensuse)
|
||||
zypper install -y curl
|
||||
;;
|
||||
alpine)
|
||||
apk add --no-cache curl
|
||||
;;
|
||||
arch)
|
||||
pacman -Syu --noconfirm curl
|
||||
;;
|
||||
freebsd)
|
||||
pkg install -y curl
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported distribution: $distro."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
echo "Curl installation completed."
|
||||
fi
|
||||
|
||||
if ! command -v npm >/dev/null 2>&1; then
|
||||
echo "Installing npm..."
|
||||
case "$(distro)" in
|
||||
alpine)
|
||||
echo "Detected Alpine Linux. Installing npm..."
|
||||
apk update
|
||||
apk add nodejs npm
|
||||
;;
|
||||
freebsd)
|
||||
echo "Detected FreeBSD. Installing npm..."
|
||||
pkg update
|
||||
pkg install -y node
|
||||
;;
|
||||
*)
|
||||
echo "Distribution: $distro. npm installation not required"
|
||||
;;
|
||||
esac
|
||||
echo "npm installation completed."
|
||||
fi
|
@ -10,18 +10,39 @@ eval "$osInfoScript"
|
||||
|
||||
# Check if the user already exists
|
||||
if id "$username" >/dev/null 2>&1; then
|
||||
echo "User $username already exists."
|
||||
echo "User $username already exists."
|
||||
else
|
||||
# Create a new user
|
||||
case "$(distro)" in
|
||||
debian | ubuntu)
|
||||
# Create a new user
|
||||
case "$(distro)" in
|
||||
debian)
|
||||
apt-get update && apt-get install -y adduser
|
||||
adduser --disabled-password --home "$homeDir" --gecos "" "$username"
|
||||
usermod -aG sudo "$username"
|
||||
;;
|
||||
fedora | centos | rhel)
|
||||
fedora)
|
||||
useradd -m -d "$homeDir" "$username"
|
||||
usermod -aG wheel "$username"
|
||||
;;
|
||||
opensuse)
|
||||
useradd -m -d "$homeDir" "$username"
|
||||
passwd -l "$username" # Locks the password to prevent login
|
||||
zypper in -y sudo
|
||||
groupadd sudo
|
||||
usermod -aG sudo "$username"
|
||||
echo "%sudo ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers
|
||||
chown -R "$username":sudo "$homeDir"
|
||||
;;
|
||||
alpine)
|
||||
adduser -h "$homeDir" -s /bin/ash -D "$username" # Default shell is ash for Alpine
|
||||
;;
|
||||
arch)
|
||||
useradd -m -d "$homeDir" -s /bin/bash "$username"
|
||||
;;
|
||||
freebsd)
|
||||
pw useradd -n "$username" -d "$homeDir" -m
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported distribution for user creation. Exiting..."
|
||||
echo "Unsupported distribution: $distro."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
@ -4,6 +4,28 @@ SSH_PORT={{ .Port }}
|
||||
|
||||
config_file='/etc/ssh/sshd_config'
|
||||
|
||||
HOST_KEYS="/etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_ecdsa_key /etc/ssh/ssh_host_ed25519_key"
|
||||
for KEY in $HOST_KEYS; do
|
||||
if [ ! -f "$KEY" ]; then
|
||||
echo "Generating host key: $KEY"
|
||||
case "$KEY" in
|
||||
"/etc/ssh/ssh_host_rsa_key")
|
||||
ssh-keygen -t rsa -b 4096 -f "$KEY" -N ""
|
||||
;;
|
||||
"/etc/ssh/ssh_host_ecdsa_key")
|
||||
ssh-keygen -t ecdsa -b 521 -f "$KEY" -N ""
|
||||
;;
|
||||
"/etc/ssh/ssh_host_ed25519_key")
|
||||
ssh-keygen -t ed25519 -f "$KEY" -N ""
|
||||
;;
|
||||
esac
|
||||
chmod 600 "$KEY"
|
||||
chmod 644 "${KEY}.pub"
|
||||
else
|
||||
echo "Host key already exists: $KEY"
|
||||
fi
|
||||
done
|
||||
|
||||
# Change the default SSH port
|
||||
sed -i "s/^#Port 22/Port $SSH_PORT/" $config_file
|
||||
if ! grep -q "^Port $SSH_PORT" $config_file; then
|
||||
|
@ -9,24 +9,32 @@ if ! command -v sshd >/dev/null 2>&1; then
|
||||
echo "OpenSSH server is not installed. Installing..."
|
||||
|
||||
case "$(distro)" in
|
||||
debian | ubuntu)
|
||||
debian)
|
||||
apt-get update
|
||||
apt-get install -y openssh-server
|
||||
;;
|
||||
fedora | centos | rhel)
|
||||
;;
|
||||
fedora)
|
||||
dnf install -y openssh-server
|
||||
;;
|
||||
;;
|
||||
opensuse)
|
||||
zypper install -y openssh
|
||||
;;
|
||||
;;
|
||||
alpine)
|
||||
apk add openssh
|
||||
;;
|
||||
apk add openssh
|
||||
;;
|
||||
arch)
|
||||
pacman -Syu --noconfirm openssh
|
||||
;;
|
||||
freebsd)
|
||||
pkg install -y openssh-portable
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported distribution for SSH installation. Exiting..."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
echo "Unsupported distribution: $distro."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
else
|
||||
echo "OpenSSH server is already installed."
|
||||
fi
|
||||
|
@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
osInfoScript={{ .OSInfoScript }}
|
||||
|
||||
eval "$osInfoScript"
|
||||
|
||||
case "$(distro)" in
|
||||
debian|fedora|opensuse)
|
||||
echo "Detected $(distro) distribution"
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported distribution: $distro." >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
Loading…
x
Reference in New Issue
Block a user