Skip to content

Commit

Permalink
remove fileitem and diritem, add hostitem, containeritem
Browse files Browse the repository at this point in the history
  • Loading branch information
RCmerci committed Jan 23, 2019
1 parent b7a2e44 commit 83883a9
Show file tree
Hide file tree
Showing 10 changed files with 227 additions and 165 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions db/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion db/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ authors = ["root"]
[dependencies]
dockerclient = { path = "../dockerclient" }
sha2 = "0.8.0"
walkdir = "2.2.7"
walkdir = "2.2.7"
hex = "0.3.2"
88 changes: 88 additions & 0 deletions db/src/containeritem.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
use crate::utils::get_or_run;
use hex::FromHex;
use std::io;
use std::path::Path;
#[derive(Debug)]
pub enum Error {
BadPath(String),
IOError(io::Error),
DefaultError(String),
}

pub struct ContainerItem<'a, 'b> {
path: &'a Path,
id: String,
dockercli: &'b dockerclient::DockerClient,
image: String,
}

impl<'a, 'b> ContainerItem<'a, 'b> {
pub fn new(
path: &'a Path,
dockercli: &'b dockerclient::DockerClient,
image: &str,
) -> Result<Self, Error> {
let mut filename = "".into();
match path.file_name() {
None => {
return Err(Error::BadPath(path.display().to_string()));
}
Some(s) => filename = s.to_string_lossy().to_owned(),
}
let id = format!("{:?}", filename);
let image = image.into();
Ok(ContainerItem {
path,
id,
dockercli,
image,
})
}
}

impl<'a, 'b> crate::Item for ContainerItem<'a, 'b> {
fn hash(&mut self) -> Vec<u8> {
let c = get_or_run(self.dockercli, &self.image).expect("get or run container fail");
let (out, err) = self
.dockercli
.exec(
&c.id,
&format!(
"cat {}",
Path::new("/checksum")
.join(self.path.strip_prefix("/").unwrap())
.display()
),
)
.map(|(out, err)| {
(
(String::from_utf8_lossy(&out).to_owned().to_string()),
(String::from_utf8_lossy(&err).to_owned().to_string()),
)
})
.expect("get checksum file fail");

if err != "" {
panic!(format!(
"out:{}, err:{}, {}",
out,
err,
format!(
"cat {}",
Path::new("/checksum")
.join(self.path.strip_prefix("/").unwrap())
.display()
)
));
}
Vec::from_hex(out.trim()).expect("from_hex")
}

fn id(&self) -> &str {
&self.id
}

fn srcpath(&self) -> &Path {
self.path
}
}
57 changes: 0 additions & 57 deletions db/src/dir_item.rs

This file was deleted.

94 changes: 40 additions & 54 deletions db/src/docker.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use crate::utils::get_or_run;
use crate::*;
use hex;
use std::fmt;
use std::ops::DerefMut;
use std::path::Path;
#[derive(Debug)]
pub enum Error {
NotExistItem(String),
NotFoundEntry(String),
DockerError(dockerclient::Error),
ExecError(String),
FileItemError(file_item::Error),
DirItemError(dir_item::Error),
HostItemError(hostitem::Error),
ContainerItemError(containeritem::Error),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Expand Down Expand Up @@ -54,13 +56,12 @@ impl DB<Error> for ImageDrive {
}

fn add(&self, entry: &str, itempath: &Path) -> Result<AddResult, Error> {
let mut item: Box<Item> = if itempath.is_file() {
Box::new(file_item::FileItem::new(itempath).map_err(Error::FileItemError)?)
} else {
Box::new(dir_item::DirItem::new(itempath).map_err(Error::DirItemError)?)
};
if !itempath.exists() {
return Err(Error::NotExistItem(format!("{}", itempath.display())));
}
let mut item = hostitem::HostItem::new(itempath).map_err(Error::HostItemError)?;

let c = get_or_run(&self.dockercli, &self.image_name)?;
let c = get_or_run(&self.dockercli, &self.image_name).map_err(Error::DockerError)?;
let path = Path::new("/data").join(entry);
let ls_entry = format!(
"mkdir -p {} && ls {}",
Expand All @@ -83,55 +84,58 @@ impl DB<Error> for ImageDrive {
let items: Vec<&str> = if out.trim() == "" {
vec![]
} else {
out.trim().split(" ").collect()
out.trim().split_whitespace().collect()
};
let mut ps = vec![];
let mut fileitems = vec![];
let mut diritems = vec![];
for item in items {
ps.push(Path::new("/data").join(item));
ps.push(Path::new("/data").join(entry).join(item));
}
for p in &ps {
if p.is_file() {
fileitems.push(file_item::FileItem::new(&p).map_err(Error::FileItemError)?);
} else {
diritems.push(dir_item::DirItem::new(&p).map_err(Error::DirItemError)?);
};
fileitems.push(
containeritem::ContainerItem::new(&p, &self.dockercli, &self.image_name)
.map_err(Error::ContainerItemError)?,
);
}

for mut fi in fileitems {
if compare_items(&mut fi, item.deref_mut()) {
if compare_items(&mut fi, &mut item) {
return Ok(AddResult::ExistedItem(fi.id().into()));
}
}
for mut di in diritems {
if compare_items(&mut di, item.deref_mut()) {
return Ok(AddResult::ExistedItem(di.id().into()));
}
}
let dstpath = Path::new("/data").join(entry).join(item.id());
self.dockercli
.copy_in(&c.id, item.srcpath(), &dstpath)
.map_err(Error::DockerError)?;

self.dockercli
.exec(
&c.id,
&format!(
"mkdir -p {} && echo {} > {}",
Path::new("/checksum")
.join(dstpath.parent().unwrap().strip_prefix("/").unwrap())
.display(),
hex::encode(item.hash()),
Path::new("/checksum")
.join(dstpath.strip_prefix("/").unwrap())
.display()
),
)
.expect("write checksum");
Ok(AddResult::Succ)
})
}
fn delete(&self, entry: &str, itempath: &Path) -> Result<(), Error> {
let item: Box<Item> = if itempath.is_file() {
Box::new(file_item::FileItem::new(itempath).map_err(Error::FileItemError)?)
} else {
Box::new(dir_item::DirItem::new(itempath).map_err(Error::DirItemError)?)
};

let c = get_or_run(&self.dockercli, &self.image_name)?;
let dstpath = Path::new("/data").join(entry).join(item.id());
fn delete(&self, entry: &str, item: &str) -> Result<(), Error> {
let c = get_or_run(&self.dockercli, &self.image_name).map_err(Error::DockerError)?;
let dstpath = Path::new("/data").join(entry).join(item);
self.dockercli
.remove_file(&c.id, &dstpath)
.map_err(|e| Error::ExecError(format!("{:?}", e)))
}

fn export_to_dir(&self, dir: &Path, entry: &str) -> Result<(), Error> {
let c = get_or_run(&self.dockercli, &self.image_name)?;
let c = get_or_run(&self.dockercli, &self.image_name).map_err(Error::DockerError)?;
let srcpath = Path::new("/data").join(entry);
self.dockercli
.copy_out(&c.id, &srcpath, dir)
Expand All @@ -144,7 +148,7 @@ impl DB<Error> for ImageDrive {
// image existed, so push to registry

// 1. commit all changed data in container to image
let c = get_or_run(&self.dockercli, &self.image_name)?;
let c = get_or_run(&self.dockercli, &self.image_name).map_err(Error::DockerError)?;
if self.dockercli.diff_container_image_content(&c.id) {
let _ = self
.dockercli
Expand All @@ -170,26 +174,8 @@ impl DB<Error> for ImageDrive {
}
}

fn get_or_run(
cli: &dockerclient::DockerClient,
image: &str,
) -> Result<dockerclient::Container, Error> {
let cs = cli.ps(false).map_err(Error::DockerError)?;
for c in cs {
if c.image.split(":").collect::<Vec<&str>>()[0]
== image.split(":").collect::<Vec<&str>>()[0]
{
return Ok(c);
}
}
// not found
let c = cli.create(image).map_err(Error::DockerError)?;
cli.start(&c.id).map_err(Error::DockerError)?;
Ok(c)
}

fn ls(cli: &dockerclient::DockerClient, image: &str, dir: &Path) -> Result<Vec<String>, Error> {
let c = get_or_run(cli, image)?;
let c = get_or_run(cli, image).map_err(Error::DockerError)?;
cli.exec(&c.id, &format!("ls {}", dir.display()))
.map_err(Error::DockerError)
.map(|(out, err)| {
Expand All @@ -205,7 +191,7 @@ fn ls(cli: &dockerclient::DockerClient, image: &str, dir: &Path) -> Result<Vec<S
if out.trim() == "" {
return Ok(vec![]);
}
let dirs: Vec<&str> = out.trim().split(" ").collect();
let dirs: Vec<&str> = out.trim().split_whitespace().collect();
let mut r = vec![];
for dir in dirs {
r.push(dir.trim().to_owned().to_string());
Expand Down
49 changes: 0 additions & 49 deletions db/src/file_item.rs

This file was deleted.

Loading

0 comments on commit 83883a9

Please sign in to comment.