Skip to content
GitLab
Explore
Projects
Groups
Snippets
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
CoTA
cota-backend
Commits
cf30aa1a
Commit
cf30aa1a
authored
2 months ago
by
mamunozgil
Browse files
Options
Download
Email Patches
Plain Diff
Add ssh to the backend container
parent
09af96c7
Pipeline
#10986
passed with stage
in 17 seconds
Changes
3
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
Dockerfile
+28
-9
Dockerfile
src/main/java/de/hftstuttgart/dtabackend/utils/RepoUtil.java
+46
-32
src/main/java/de/hftstuttgart/dtabackend/utils/RepoUtil.java
src/main/resources/application.properties
+7
-1
src/main/resources/application.properties
with
81 additions
and
42 deletions
+81
-42
Dockerfile
+
28
-
9
View file @
cf30aa1a
#
b
ase image to build a JRE
#
B
ase image to build a JRE
FROM
eclipse-temurin:21-jdk-alpine
as
corretto-jdk
#
r
equired for strip-debug to work
#
R
equired for strip-debug to work
RUN
apk add
--no-cache
binutils
# Build small JRE image
...
...
@@ -14,14 +14,17 @@ RUN $JAVA_HOME/bin/jlink \
--compress=2 \
--output /customjre
#
m
ain app image
#
M
ain app image
FROM
alpine:latest
ENV
JAVA_HOME=/jre
ENV
PATH="${JAVA_HOME}/bin:${PATH}"
ENV
SPRING_CONFIG_ADDITIONAL_LOCATION
"file:/data/config/"
ENV
SPRING_CONFIG_ADDITIONAL_LOCATION
=
"file:/data/config/"
# copy JRE from the base image
# Install OpenSSH client and required dependencies
RUN
apk add
--no-cache
openssh-client bash
# Copy JRE from the base image
COPY
--from=corretto-jdk /customjre $JAVA_HOME
# Add app user
...
...
@@ -35,16 +38,32 @@ ARG BUILD_NUMBER=
RUN
addgroup
--gid
$GID
--system
docker
RUN
adduser
--no-create-home
-u
1000
--ingroup
docker
--disabled-password
$USER
# Prepare environment
.
# Prepare environment
# Create needed folders
RUN
mkdir
/data
&&
\
mkdir /data/config
&& \
ch
own -R $USER /data
RUN
mkdir
-p
/data
/home/
$USER
/.ssh
&&
\
chown -R $USER:$GID /data /home/$USER/.ssh
&& \
ch
mod 700 /home/$USER/.ssh
VOLUME
/data
# Copy SSH keys from build context (MAKE SURE TO ADD THEM TO .dockerignore)
COPY
--chown=1000:$GID id_rsa /home/$USER/.ssh/id_rsa
COPY
--chown=1000:$GID known_hosts /home/$USER/.ssh/known_hosts
# Set proper permissions for SSH keys
RUN
chmod
600 /home/
$USER
/.ssh/id_rsa
&&
\
chmod 644 /home/$USER/.ssh/known_hosts && \
chown -R $USER:$GID /home/$USER/.ssh
# Copy application JAR
COPY
--chown=1000:$GID target/dta-backend-$BUILD_NUMBER.jar app.jar
# Switch to non-root user
USER
1000:$GID
# Set environment variables for SVNKit SSH authentication
ENV
SVN_SSH="/usr/bin/ssh"
ENV
SVN_SSH_KEY="/home/$USER/.ssh/id_rsa"
# Start application
ENTRYPOINT
["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
This diff is collapsed.
Click to expand it.
src/main/java/de/hftstuttgart/dtabackend/utils/RepoUtil.java
+
46
-
32
View file @
cf30aa1a
...
...
@@ -8,10 +8,7 @@ import org.eclipse.jgit.api.errors.GitAPIException;
import
org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider
;
import
org.springframework.stereotype.Component
;
import
org.springframework.util.FileSystemUtils
;
import
org.tmatesoft.svn.core.SVNDepth
;
import
org.tmatesoft.svn.core.SVNException
;
import
org.tmatesoft.svn.core.SVNURL
;
import
org.tmatesoft.svn.core.auth.BasicAuthenticationManager
;
import
org.tmatesoft.svn.core.*
;
import
org.tmatesoft.svn.core.auth.ISVNAuthenticationManager
;
import
org.tmatesoft.svn.core.wc.SVNWCUtil
;
import
org.tmatesoft.svn.core.wc2.SvnCheckout
;
...
...
@@ -20,7 +17,6 @@ import org.tmatesoft.svn.core.wc2.SvnTarget;
import
java.io.File
;
import
java.io.IOException
;
import
java.net.URL
;
import
java.util.regex.Matcher
;
@Component
...
...
@@ -35,19 +31,19 @@ public class RepoUtil {
LOG
.
error
(
"Invalid repository URL format."
);
return
;
}
String
repoUrl
=
config
.
group
(
1
);
String
username
=
config
.
group
(
2
);
String
password
=
config
.
group
(
3
);
LOG
.
debug
(
String
.
format
(
"Cloning repository:
%s
"
,
repoUrl
)
)
;
String
password
=
config
.
group
(
3
);
// Not used for SSH authentication
LOG
.
debug
(
"Cloning repository:
{}
"
,
repoUrl
);
File
targetDirectory
=
new
File
(
targetPath
);
if
(
targetDirectory
.
exists
())
{
LOG
.
debug
(
"Target directory exists, deleting it."
);
FileSystemUtils
.
deleteRecursively
(
targetDirectory
);
}
File
checkoutDirectory
=
targetDirectory
;
if
(!
subDir
.
isEmpty
())
{
checkoutDirectory
=
new
File
(
targetPath
+
"_checkout"
);
...
...
@@ -56,49 +52,65 @@ public class RepoUtil {
FileSystemUtils
.
deleteRecursively
(
checkoutDirectory
);
}
}
try
{
LOG
.
debug
(
"Preparing clone..."
);
if
(
repoUrl
.
endsWith
(
".git"
))
{
// GIT Repository Clone
CloneCommand
cloneCommand
=
Git
.
cloneRepository
()
.
setDirectory
(
checkoutDirectory
)
.
setURI
(
repoUrl
);
if
(!
"none"
.
equals
(
username
)
&&
!
"none"
.
equals
(
password
))
{
LOG
.
debug
(
"Setting Git credentials."
);
cloneCommand
.
setCredentialsProvider
(
new
UsernamePasswordCredentialsProvider
(
username
,
password
));
}
LOG
.
debug
(
"Cloning Git repository..."
);
cloneCommand
.
call
().
close
();
}
else
{
// SVN Repository Clone (including svn+ssh support)
SvnOperationFactory
operationFactory
=
new
SvnOperationFactory
();
try
{
URL
sourceUrl
=
new
URL
(
repoUrl
);
SVNURL
svnUrl
=
SVNURL
.
create
(
sourceUrl
.
getProtocol
(),
null
,
sourceUrl
.
getHost
(),
sourceUrl
.
getPort
(),
sourceUrl
.
getPath
(),
false
);
SVNURL
svnUrl
=
SVNURL
.
parseURIEncoded
(
repoUrl
);
SvnCheckout
checkout
=
operationFactory
.
createCheckout
();
checkout
.
setSingleTarget
(
SvnTarget
.
fromFile
(
new
File
(
targetPath
)
));
checkout
.
setSingleTarget
(
SvnTarget
.
fromFile
(
checkoutDirectory
));
checkout
.
setSource
(
SvnTarget
.
fromURL
(
svnUrl
));
checkout
.
setDepth
(
SVNDepth
.
INFINITY
);
if
(!
"none"
.
equals
(
username
)
&&
!
"none"
.
equals
(
password
))
{
if
(
repoUrl
.
startsWith
(
"https"
))
{
LOG
.
debug
(
"Setting SVN credentials for HTTPS."
);
operationFactory
.
setAuthenticationManager
(
new
BasicAuthenticationManager
(
username
,
password
));
}
else
if
(
repoUrl
.
startsWith
(
"svn+ssh"
))
{
LOG
.
debug
(
"Setting SVN credentials for SSH."
);
ISVNAuthenticationManager
authManager
=
SVNWCUtil
.
createDefaultAuthenticationManager
(
username
,
password
.
toCharArray
());
operationFactory
.
setAuthenticationManager
(
authManager
);
// **Use SSH authentication if URL starts with svn+ssh://**
if
(
repoUrl
.
startsWith
(
"svn+ssh://"
))
{
LOG
.
debug
(
"Setting up SSH authentication for SVN..."
);
String
sshPrivateKeyPath
=
"/home/appuser/.ssh/id_rsa"
;
File
privateKeyFile
=
new
File
(
sshPrivateKeyPath
);
if
(!
privateKeyFile
.
exists
())
{
LOG
.
error
(
"SSH private key not found at: {}"
,
sshPrivateKeyPath
);
throw
new
SVNException
(
SVNErrorMessage
.
create
(
SVNErrorCode
.
AUTHN_CREDS_UNAVAILABLE
,
"SSH key not found"
));
}
ISVNAuthenticationManager
authManager
=
SVNWCUtil
.
createDefaultAuthenticationManager
(
new
File
(
"/home/appuser/.ssh/id_rsa"
),
// Explicit SSH Key
username
,
null
,
new
File
(
"/home/appuser/.ssh/known_hosts"
),
// Explicit Known Hosts
false
);
operationFactory
.
setAuthenticationManager
(
authManager
);
}
LOG
.
debug
(
"Performing SVN checkout..."
);
checkout
.
run
();
}
finally
{
operationFactory
.
dispose
();
operationFactory
.
dispose
();
}
}
// Handle subdirectory case
if
(!
subDir
.
isEmpty
())
{
File
sourceSubDir
=
new
File
(
checkoutDirectory
,
subDir
);
if
(
sourceSubDir
.
exists
())
{
...
...
@@ -107,10 +119,12 @@ public class RepoUtil {
LOG
.
error
(
"Specified subdirectory does not exist."
);
}
}
LOG
.
debug
(
String
.
format
(
"Repository cloned from %s to %s"
,
repoUrl
,
targetDirectory
));
LOG
.
debug
(
"Repository successfully cloned from {} to {}"
,
repoUrl
,
targetDirectory
);
}
catch
(
IOException
|
GitAPIException
|
SVNException
e
)
{
LOG
.
error
(
"Error while cloning repository: "
+
repoUrl
,
e
);
}
}
}
}
This diff is collapsed.
Click to expand it.
src/main/resources/application.properties
+
7
-
1
View file @
cf30aa1a
...
...
@@ -14,4 +14,10 @@ host.tests.tmp.dir=${tests.tmp.dir}
data.dir
=
/data
data.dir.test.folder.name
=
UnitTests
logging.level.de.hftstuttgart
=
TRACE
\ No newline at end of file
logging.level.de.hftstuttgart
=
TRACE
################################################
# SSH directory
################################################
ssh.file
=
/home/appuser/.ssh/id_rsa
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Explore
Projects
Groups
Snippets