Skip to content

Commit

Permalink
feat: initial docker implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
jackstar12 committed Sep 5, 2023
1 parent 35f56c9 commit 9cf8530
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 50 deletions.
11 changes: 11 additions & 0 deletions coffee_lib/docker/pip.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM python:3.10-slim

COPY requirements.txt /plugin/requirements.txt

WORKDIR /plugin

RUN pip install -r requirements.txt --no-cache-dir

COPY . /plugin/

CMD [ "" ]
13 changes: 13 additions & 0 deletions coffee_lib/docker/poetry.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM python:3.10-slim

RUN pip3 install poetry

COPY pyproject.toml /plugin/pyproject.toml

WORKDIR /plugin

RUN poetry config virtualenvs.create false && poetry install --without dev

COPY . /plugin/

CMD [ "python" ]
136 changes: 86 additions & 50 deletions coffee_lib/src/plugin.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! Plugin module that abstract the concept of a cln plugin
//! from a plugin manager point of view.
use std::fmt::{self, Display};
use std::fs::{File, Permissions};
use std::io::Write;
use std::os::unix::prelude::PermissionsExt;

use log;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -42,52 +45,87 @@ impl Display for PluginLang {
}

impl PluginLang {
fn docker_file(&self) -> Option<&str> {
match self {
PluginLang::PyPip => Some(include_str!("../docker/pip.Dockerfile")),
PluginLang::PyPoetry => Some(include_str!("../docker/poetry.Dockerfile")),
_ => None,
}
}

pub async fn default_install(
&self,
path: &str,
name: &str,
verbose: bool,
) -> Result<String, CoffeeError> {
match self {
PluginLang::PyPip => {
/* 1. RUN PIP install or poetry install
* 2. return the path of the main file */
let script = "pip3 install -r requirements.txt --break-system-packages";
sh!(path, script, verbose);
let main_file = format!("{path}/{name}.py");
Ok(main_file)
}
PluginLang::PyPoetry => {
let mut script = "pip3 install poetry\n".to_string();
script += "poetry export -f requirements.txt --output requirements.txt\n";
script += "pip3 install -r requirements.txt";
match self.docker_file() {
Some(docker_file) => {
let container_name = format!("plugin.{name}");
log::debug!("Using dockerfile: \n{docker_file}");
let script =
format!("echo \"{docker_file}\" | docker build . -f - -t {container_name}");

sh!(path, script, verbose);
Ok(format!("{path}/{name}.py"))
}
PluginLang::Go => Err(error!(
"golang is not supported as default language, please us the coffee.yml manifest"
)),
PluginLang::Rust => Err(error!(
"rust is not supported as default language, please use the coffee.yml manifest"
)),
PluginLang::Dart => Err(error!(
"dart is not supported as default language, please use the cofee.yml manifest"
)),
PluginLang::JavaScript => Err(error!(
"js is not supported as default language, please use the coffee.yml manifest"
)),
PluginLang::TypeScript => Err(error!(
"ts is not supported as default language, please use the coffee.yml manifest"
)),
PluginLang::JVM => Err(error!(
"JVM is not supported as default language, please use the coffee.yml manifest"
)),
PluginLang::Unknown => {
/* 1. emit an error message */
Err(error!(
"unknown default install procedure, the language in undefined"
))
let exec = format!("{path}/{name}.sh");

log::debug!("{}", exec);

let args = match self {
PluginLang::PyPip | PluginLang::PyPoetry => format!("python {name}.py"),
_ => String::new(),
};

let mut f = File::create(&exec)?;
f.write_all(format!("docker run {container_name} {args}").as_bytes())
.map_err(|_| error!("could not write executable file"))?;

f.set_permissions(Permissions::from_mode(0o755))
.map_err(|_| error!("could not set permissions for executable file"))?;

Ok(exec)
}
None => match self {
PluginLang::PyPip => {
/* 1. RUN PIP install or poetry install
* 2. return the path of the main file */
let script = "pip3 install -r requirements.txt --break-system-packages";
sh!(path, script, verbose);
let main_file = format!("{path}/{name}.py");
Ok(main_file)
}
PluginLang::PyPoetry => {
let mut script = "pip3 install poetry\n".to_string();
script += "poetry export -f requirements.txt --output requirements.txt\n";
script += "pip3 install -r requirements.txt";
sh!(path, script, verbose);
Ok(format!("{path}/{name}.py"))
}
PluginLang::Go => Err(error!(
"golang is not supported as default language, please us the coffee.yml manifest"
)),
PluginLang::Rust => Err(error!(
"rust is not supported as default language, please use the coffee.yml manifest"
)),
PluginLang::Dart => Err(error!(
"dart is not supported as default language, please use the cofee.yml manifest"
)),
PluginLang::JavaScript => Err(error!(
"js is not supported as default language, please use the coffee.yml manifest"
)),
PluginLang::TypeScript => Err(error!(
"ts is not supported as default language, please use the coffee.yml manifest"
)),
PluginLang::JVM => Err(error!(
"JVM is not supported as default language, please use the coffee.yml manifest"
)),
PluginLang::Unknown => {
/* 1. emit an error message */
Err(error!(
"unknown default install procedure, the language in undefined"
))
}
},
}
}
}
Expand Down Expand Up @@ -131,21 +169,19 @@ impl Plugin {
/// In case of success return the path of the executable.
pub async fn configure(&mut self, verbose: bool) -> Result<String, CoffeeError> {
log::debug!("install plugin inside from root dir {}", self.root_path);
let exec_path = if let Some(conf) = &self.conf {
if let Some(script) = &conf.plugin.install {
sh!(self.root_path.clone(), script, verbose);
self.exec_path.clone()
} else {
self.lang

let conf = self.conf.as_ref();
match conf.and_then(|conf| conf.plugin.install.clone()) {
Some(script) => sh!(self.root_path.clone(), script, verbose),
None => {
self.exec_path = self
.lang
.default_install(&self.root_path, &self.name, verbose)
.await?
.await?;
}
} else {
self.lang
.default_install(&self.root_path, &self.name, verbose)
.await?
};
Ok(exec_path)

Ok(self.exec_path.clone())
}

/// upgrade the plugin to a new version.
Expand Down

0 comments on commit 9cf8530

Please sign in to comment.