This commit is contained in:
Arthur Wambst 2025-10-05 23:33:28 +02:00
parent a82677b3bb
commit 1699603853
No known key found for this signature in database
12 changed files with 149 additions and 113 deletions

11
dockerfile/Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM linuxserver/openssh-server
RUN apk update
RUN apk upgrade
RUN apk add vim python3 py3-pip apache2 git
RUN pip install discord-py --break-system-packages
RUN mkdir -p /run/apache2
CMD exec /bin/sh -c "trap : TERM INT; sleep 9999999999d & wait"

View File

@ -7,10 +7,10 @@ import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import java.util.Map; import java.util.Map;
@Path("/containers") @Path("/docker")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public class ContainerResource { public class DockerResource {
@Inject DockerService dockerService; @Inject DockerService dockerService;
@ -46,8 +46,7 @@ public class ContainerResource {
@Path("/all") @Path("/all")
public Response listContainers() { public Response listContainers() {
try { try {
String id = dockerService.listAllContainers(); return Response.ok(dockerService.listAllContainers()).build();
return Response.ok(id).build();
} catch (Exception e) { } catch (Exception e) {
return Response.status(500) return Response.status(500)
.entity(Map.of("error", e.getMessage())) .entity(Map.of("error", e.getMessage()))

View File

@ -36,8 +36,8 @@ public class InstanceEndpoints {
@POST @POST
@Path("/{id}/instance") @Path("/{id}/instance")
public Response createInstance(@PathParam("id") Long jiId, public Response createInstance(@PathParam("id") Long jiId,
@QueryParam("username") String username) { @QueryParam("userId") Long userId) {
jiService.createInstance(jiId, username); jiService.createInstance(jiId, userId);
return Response.ok().build(); return Response.ok().build();
} }

View File

@ -1,12 +1,7 @@
package fr.la_banquise.backend.rest; package fr.la_banquise.backend.rest;
import fr.la_banquise.backend.data.model.RolesAsso;
import fr.la_banquise.backend.data.model.User; import fr.la_banquise.backend.data.model.User;
import fr.la_banquise.backend.rest.request.BulkUserDelRequest;
import fr.la_banquise.backend.rest.request.BulkUserPostRequest;
import fr.la_banquise.backend.rest.request.UserRequest; import fr.la_banquise.backend.rest.request.UserRequest;
import fr.la_banquise.backend.rest.response.BulkUserDelResponse;
import fr.la_banquise.backend.rest.response.BulkUserPostResponse;
import fr.la_banquise.backend.rest.response.LoggedUserResponse; import fr.la_banquise.backend.rest.response.LoggedUserResponse;
import fr.la_banquise.backend.services.UserService; import fr.la_banquise.backend.services.UserService;
import io.quarkus.security.Authenticated; import io.quarkus.security.Authenticated;
@ -22,7 +17,6 @@ import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam; import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
@ -72,9 +66,8 @@ public class UserEndpoints {
public Response addRole(@PathParam("id") Long userId, public Response addRole(@PathParam("id") Long userId,
@QueryParam("role") String role) { @QueryParam("role") String role) {
try { try {
User user = userService.getUser(userId); userService.updateRole(role, userId);
user.role.add(userService.fromString(role)); return Response.ok().build();
return Response.ok(user.role).build();
} catch (Exception e) { } catch (Exception e) {
return Response.status(404) return Response.status(404)
.entity(Map.of("User or Role not found", e)) .entity(Map.of("User or Role not found", e))
@ -88,9 +81,8 @@ public class UserEndpoints {
public Response removeRole(@PathParam("id") Long userId, public Response removeRole(@PathParam("id") Long userId,
@QueryParam("role") String role) { @QueryParam("role") String role) {
try { try {
User user = userService.getUser(userId); userService.removeRole(role, userId);
user.role.remove(userService.fromString(role)); return Response.ok().build();
return Response.ok(user.role).build();
} catch (Exception e) { } catch (Exception e) {
return Response.status(404) return Response.status(404)
.entity(Map.of("User or Role not found", e)) .entity(Map.of("User or Role not found", e))

View File

@ -49,11 +49,11 @@ public class UsersEndpoints {
public Response createUsersBulk(BulkUserPostRequest users) { public Response createUsersBulk(BulkUserPostRequest users) {
BulkUserPostResponse response = userService.createUsers( BulkUserPostResponse response = userService.createUsers(
users); users);
if (response.success_names.size() == users.users.size()) if (response.successNames.size() == users.users.size())
return Response.ok().build(); return Response.ok().build();
return Response.status(202) return Response.status(202)
.entity(Map.of("These users were already created : ", .entity(Map.of("These users were already created : ",
response.already_created)) response.alreadyCreated))
.build(); .build();
} }
@ -61,13 +61,13 @@ public class UsersEndpoints {
@RolesAllowed("ROOT") @RolesAllowed("ROOT")
public Response deleteUserBulk(BulkUserDelRequest users) { public Response deleteUserBulk(BulkUserDelRequest users) {
BulkUserDelResponse response = userService.deleteUsers(users); BulkUserDelResponse response = userService.deleteUsers(users);
if (response.success_names.size() == users.usernames.size()) if (response.successNames.size() == users.usernames.size())
return Response.ok().build(); return Response.ok().build();
Map<String, String> retour = new HashMap<String, String>(); Map<String, String> retour = new HashMap<String, String>();
for (int id = 0; id < response.failed_names.size(); id++) { for (int id = 0; id < response.failedNames.size(); id++) {
retour.put(response.failed_names.get(id), retour.put(response.failedNames.get(id),
response.failed_reasons.get(id)); response.failedReasons.get(id));
} }
return Response.status(202).entity(retour).build(); return Response.status(202).entity(retour).build();
} }

View File

@ -7,13 +7,13 @@ import java.util.List;
@RegisterForReflection @RegisterForReflection
public class BulkUserDelResponse { public class BulkUserDelResponse {
public List<String> success_names; public List<String> successNames;
public List<String> failed_names; public List<String> failedNames;
public List<String> failed_reasons; public List<String> failedReasons;
public BulkUserDelResponse() { public BulkUserDelResponse() {
this.success_names = new ArrayList<String>(); this.successNames = new ArrayList<String>();
this.failed_names = new ArrayList<String>(); this.failedNames = new ArrayList<String>();
this.failed_reasons = new ArrayList<String>(); this.failedReasons = new ArrayList<String>();
} }
} }

View File

@ -7,11 +7,11 @@ import io.quarkus.runtime.annotations.RegisterForReflection;
@RegisterForReflection @RegisterForReflection
public class BulkUserPostResponse { public class BulkUserPostResponse {
public List<String> success_names; public List<String> successNames;
public List<String> already_created; public List<String> alreadyCreated;
public BulkUserPostResponse() { public BulkUserPostResponse() {
this.success_names = new ArrayList<String>(); this.successNames = new ArrayList<String>();
this.already_created = new ArrayList<String>(); this.alreadyCreated = new ArrayList<String>();
} }
} }

View File

@ -1,6 +1,7 @@
package fr.la_banquise.backend.services; package fr.la_banquise.backend.services;
import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.BuildImageResultCallback;
import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.command.CreateContainerResponse;
import com.github.dockerjava.api.command.InspectContainerResponse; import com.github.dockerjava.api.command.InspectContainerResponse;
import com.github.dockerjava.api.model.Container; import com.github.dockerjava.api.model.Container;
@ -9,11 +10,15 @@ import com.github.dockerjava.api.model.ExposedPort;
import com.github.dockerjava.api.model.HostConfig; import com.github.dockerjava.api.model.HostConfig;
import com.github.dockerjava.api.model.PortBinding; import com.github.dockerjava.api.model.PortBinding;
import com.github.dockerjava.api.model.Ports; import com.github.dockerjava.api.model.Ports;
import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject; import jakarta.inject.Inject;
import java.io.File;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
@ApplicationScoped @ApplicationScoped
public class DockerService { public class DockerService {
@ -46,26 +51,7 @@ public class DockerService {
return container.getId(); return container.getId();
} }
public String createContainer(String containerName, int port) {
StringBuilder result = new StringBuilder();
ExposedPort tcpSsh = ExposedPort.tcp(80);
Ports portBindings = new Ports();
portBindings.bind(tcpSsh, Ports.Binding.bindPort(port));
HostConfig hostConfig =
HostConfig.newHostConfig().withPortBindings(portBindings);
CreateContainerResponse container =
dockerClient.createContainerCmd("nginx:latest")
.withName(containerName)
.withExposedPorts(tcpSsh)
.withHostConfig(hostConfig)
.exec();
// dockerClient.startContainerCmd(container.getId()).exec();
return container.getId();
}
/* /*
public String listAllContainers() { public String listAllContainers() {
StringBuilder json = new StringBuilder(); StringBuilder json = new StringBuilder();
@ -176,7 +162,70 @@ public class DockerService {
json.append("]"); json.append("]");
return json.toString(); return json.toString();
}*/ }*/
public String listAllContainers() { return ""; }
////////////////////
public String createContainer(String name, int port) {
ExposedPort tcpSsh = ExposedPort.tcp(2222);
Ports portBindings = new Ports();
portBindings.bind(tcpSsh, Ports.Binding.bindPort(port));
HostConfig hostConfig =
HostConfig.newHostConfig().withPortBindings(portBindings);
Map<String, String> labels = new HashMap<>();
labels.put("test", "banquise");
labels.put("environment", "development");
labels.put("version", "1.0");
labels.put("created-by", "java-docker-api");
dockerClient.buildImageCmd()
.withDockerfile(new File("./dockerfile/Dockerfile"))
.withBaseDirectory(new File("./dockerfile"))
.withTags(Set.of("ji-python:latest"))
.exec(new BuildImageResultCallback())
.awaitImageId();
CreateContainerResponse container =
dockerClient.createContainerCmd("ji-python:latest")
.withName(name)
.withLabels(labels)
.withExposedPorts(tcpSsh)
.withHostConfig(hostConfig)
.withEnv(
"SUDO_ACCESS=false",
"PASSWORD_ACCESS=true",
"USER_NAME=test", // TODO: CHANGE THIS
"USER_PASSWORD=test" // AND this also oc
)
.exec();
return container.getId();
}
public InspectContainerResponse.ContainerState getStatusContainer(String name) {
InspectContainerResponse container =
dockerClient.inspectContainerCmd(name).exec();
return container.getState();
}
public boolean remove(String name) {
try {
dockerClient.removeContainerCmd(name).exec();
return true;
} catch (Exception e) {
return false;
}
}
public boolean containerExists(String name) {
try {
dockerClient.inspectContainerCmd(name).exec();
return true;
} catch (Exception e) {
return false;
}
}
public void start(String containerId) { public void start(String containerId) {
dockerClient.startContainerCmd(containerId).exec(); dockerClient.startContainerCmd(containerId).exec();
@ -186,7 +235,11 @@ public class DockerService {
dockerClient.stopContainerCmd(containerId).exec(); dockerClient.stopContainerCmd(containerId).exec();
} }
public void remove(String containerId) { public List<Container> listAllContainers() {
dockerClient.removeContainerCmd(containerId).exec(); return dockerClient.listContainersCmd()
.withShowAll(true)
.exec();
} }
} }

View File

@ -35,14 +35,14 @@ public class InstanceService {
@Inject JiRepository jiRepository; @Inject JiRepository jiRepository;
@Inject DockerClient dockerClient; @Inject DockerService dockerService;
public List<Instance> getAllInstances() { public List<Instance> getAllInstances() {
return instanceRepository.findAll().list(); return instanceRepository.findAll().list();
} }
public List<Instance> getInstancesByOwner(String username) { public List<Instance> getInstancesByOwner(Long id) {
User user = userRepository.findByName(username); User user = userRepository.findById(id);
return instanceRepository.find("owner", user).list(); return instanceRepository.find("owner", user).list();
} }
@ -52,15 +52,13 @@ public class InstanceService {
public InspectContainerResponse.ContainerState getStatusContainer(Long id) { public InspectContainerResponse.ContainerState getStatusContainer(Long id) {
Instance instance = instanceRepository.findById(id); Instance instance = instanceRepository.findById(id);
InspectContainerResponse container = return dockerService.getStatusContainer(instance.name);
dockerClient.inspectContainerCmd(instance.name).exec();
return container.getState();
} }
@Transactional @Transactional
public Instance createInstance(String username, Ji ji) { public Instance createInstance(Long id, Ji ji) {
User user = userRepository.findByName(username); User user = userRepository.findById(id);
String name = username + "-" + ji.id; String name = user.name + "-" + ji.id;
int port = getFreePort(1).iterator().next(); int port = getFreePort(1).iterator().next();
Instance instance = new Instance(name, port, user); Instance instance = new Instance(name, port, user);
instanceRepository.persist(instance); instanceRepository.persist(instance);
@ -70,56 +68,23 @@ public class InstanceService {
public String createContainer(Long instanceId) { public String createContainer(Long instanceId) {
Instance instance = instanceRepository.findById(instanceId); Instance instance = instanceRepository.findById(instanceId);
ExposedPort tcpSsh = ExposedPort.tcp(22); return dockerService.createContainer(instance.name, instance.port);
Ports portBindings = new Ports();
portBindings.bind(tcpSsh, Ports.Binding.bindPort(instance.port));
HostConfig hostConfig =
HostConfig.newHostConfig().withPortBindings(portBindings);
Map<String, String> labels = new HashMap<>();
labels.put("test", "banquise");
labels.put("environment", "development");
labels.put("version", "1.0");
labels.put("created-by", "java-docker-api");
CreateContainerResponse container =
dockerClient.createContainerCmd("nginx:latest")
.withName(instance.name)
.withLabels(labels)
.withExposedPorts(tcpSsh)
.withHostConfig(hostConfig)
.exec();
return container.getId();
} }
public boolean deleteContainer(String containerName) { public boolean deleteContainer(Long id) {
try { Instance instance = instanceRepository.findById(id);
dockerClient.removeContainerCmd(containerName).exec();
return true; return dockerService.remove(instance.name);
} catch (Exception e) {
return false;
}
} }
@Transactional @Transactional
public boolean deleteInstance(Long id) { public boolean deleteInstance(Long id) {
Instance instance = instanceRepository.findById(id); Instance instance = instanceRepository.findById(id);
if (!containerExists(instance.name)) if (!dockerService.containerExists(instance.name))
return instanceRepository.deleteById(id); return instanceRepository.deleteById(id);
return false; return false;
} }
public boolean containerExists(String containerName) {
try {
dockerClient.inspectContainerCmd(containerName).exec();
return true;
} catch (Exception e) {
return false;
}
}
public Set<Integer> getUsedPorts() { public Set<Integer> getUsedPorts() {
Set<Integer> retour = new HashSet<>(); Set<Integer> retour = new HashSet<>();
List<Instance> allInstances = getAllInstances(); List<Instance> allInstances = getAllInstances();
@ -146,4 +111,5 @@ public class InstanceService {
return retour; return retour;
} }
} }

View File

@ -61,9 +61,9 @@ public class JiService {
} }
@Transactional @Transactional
public Instance createInstance(Long id, String username) { public Instance createInstance(Long jiId, Long userId) {
Ji ji = jiRepository.findById(id); Ji ji = jiRepository.findById(jiId);
Instance instance = instanceService.createInstance(username, ji); Instance instance = instanceService.createInstance(userId, ji);
ji.instances.add(instance); ji.instances.add(instance);
return instance; return instance;
} }

View File

@ -90,6 +90,8 @@ public class SujetService {
} }
/* /*
* TODO: Seuls les respos du sujet et root doivent pouvoir avoir acces * TODO: Seuls les respos du sujet et root doivent pouvoir avoir acces
* TODO: move ce todo et refactor poru que les check d acces soient dans
* rest et pas dans services
* @Transactional * @Transactional
public Sujet updateSujet(Long id) { public Sujet updateSujet(Long id) {
Sujet sujet = sujetRepository.findById(id); Sujet sujet = sujetRepository.findById(id);

View File

@ -68,10 +68,10 @@ public class UserService {
userToDel = userToDel =
userRepository.find("name", requestName.name).firstResult(); userRepository.find("name", requestName.name).firstResult();
userRepository.delete(userToDel); userRepository.delete(userToDel);
response.success_names.add(requestName.name); response.successNames.add(requestName.name);
} catch (Exception e) { } catch (Exception e) {
response.failed_names.add(requestName.name); response.failedNames.add(requestName.name);
response.failed_reasons.add(e.toString()); response.failedReasons.add(e.toString());
} }
} }
@ -86,9 +86,9 @@ public class UserService {
for (UserRequest user : usersRequest.users) { for (UserRequest user : usersRequest.users) {
try { try {
createUser(user); createUser(user);
response.success_names.add(user.name); response.successNames.add(user.name);
} catch (Exception e) { } catch (Exception e) {
response.already_created.add(user.name); response.alreadyCreated.add(user.name);
} }
} }
} }
@ -106,4 +106,17 @@ public class UserService {
default -> throw new Error("Wrong role str"); default -> throw new Error("Wrong role str");
}; };
} }
@Transactional
public void updateRole(String role, Long userId) {
User user = userRepository.findById(userId);
user.role.add(fromString(role));
}
@Transactional
public void removeRole(String role, Long userId) {
User user = userRepository.findById(userId);
user.role.remove(fromString(role));
}
} }