This commit is contained in:
weisd
2024-06-25 17:33:46 +08:00
parent 0e4e574bd4
commit d3714de65b
8 changed files with 34 additions and 17 deletions
+2 -3
View File
@@ -1,5 +1,4 @@
use clap::Parser;
use std::path::PathBuf;
/// Default port that a rustfs server listens on.
///
@@ -10,10 +9,10 @@ pub const DEFAULT_PORT: u16 = 9000;
pub struct Opt {
/// DIR points to a directory on a filesystem.
#[arg(required = true)]
pub volumes: Vec<PathBuf>,
pub volumes: Vec<String>,
/// bind to a specific ADDRESS:PORT, ADDRESS can be an IP or hostname
#[arg(long, default_value_t = format!(":{}", DEFAULT_PORT))]
#[arg(long, default_value_t = format!("0.0.0.0:{}", DEFAULT_PORT))]
pub address: String,
/// Access key used for authentication.
+4 -2
View File
@@ -3,6 +3,7 @@ mod storage;
use anyhow::Result;
use clap::Parser;
use ecstore::store::ECStore;
use hyper_util::{
rt::{TokioExecutor, TokioIo},
server::conn::auto::Builder as ConnBuilder,
@@ -10,7 +11,7 @@ use hyper_util::{
use s3s::{auth::SimpleAuth, service::S3ServiceBuilder};
use std::io::IsTerminal;
use tokio::net::TcpListener;
use tracing::info;
use tracing::{debug, info};
fn setup_tracing() {
use tracing_subscriber::EnvFilter;
@@ -35,9 +36,10 @@ fn main() -> Result<()> {
#[tokio::main]
async fn run(opt: config::Opt) -> Result<()> {
debug!("opt: {:?}", &opt);
// Setup S3 service
let service = {
let mut b = S3ServiceBuilder::new(storage::SimpleFS {});
let mut b = S3ServiceBuilder::new(storage::ecfs::EC::new(opt.volumes)?);
// Enable authentication
if let (Some(ak), Some(sk)) = (opt.access_key, opt.secret_key) {
+289
View File
@@ -0,0 +1,289 @@
use s3s::dto::*;
use s3s::s3_error;
use s3s::S3Result;
use s3s::S3;
use s3s::{S3Request, S3Response};
use anyhow::Result;
use ecstore::store::ECStore;
#[derive(Debug)]
pub struct EC {
store: ECStore,
}
impl EC {
pub fn new(endpoints: Vec<String>) -> Result<Self> {
let store = ECStore::new(endpoints)?;
Ok(EC { store })
}
}
#[async_trait::async_trait]
impl S3 for EC {
#[tracing::instrument]
async fn create_bucket(
&self,
req: S3Request<CreateBucketInput>,
) -> S3Result<S3Response<CreateBucketOutput>> {
let input = req.input;
let output = CreateBucketOutput::default(); // TODO: handle other fields
Ok(S3Response::new(output))
}
#[tracing::instrument]
async fn copy_object(
&self,
req: S3Request<CopyObjectInput>,
) -> S3Result<S3Response<CopyObjectOutput>> {
let input = req.input;
let (bucket, key) = match input.copy_source {
CopySource::AccessPoint { .. } => return Err(s3_error!(NotImplemented)),
CopySource::Bucket {
ref bucket,
ref key,
..
} => (bucket, key),
};
let output = CopyObjectOutput {
..Default::default()
};
Ok(S3Response::new(output))
}
#[tracing::instrument]
async fn delete_bucket(
&self,
req: S3Request<DeleteBucketInput>,
) -> S3Result<S3Response<DeleteBucketOutput>> {
let input = req.input;
Ok(S3Response::new(DeleteBucketOutput {}))
}
#[tracing::instrument]
async fn delete_object(
&self,
req: S3Request<DeleteObjectInput>,
) -> S3Result<S3Response<DeleteObjectOutput>> {
let input = req.input;
let output = DeleteObjectOutput::default(); // TODO: handle other fields
Ok(S3Response::new(output))
}
#[tracing::instrument]
async fn delete_objects(
&self,
req: S3Request<DeleteObjectsInput>,
) -> S3Result<S3Response<DeleteObjectsOutput>> {
let input = req.input;
let output = DeleteObjectsOutput {
..Default::default()
};
Ok(S3Response::new(output))
}
#[tracing::instrument]
async fn get_bucket_location(
&self,
req: S3Request<GetBucketLocationInput>,
) -> S3Result<S3Response<GetBucketLocationOutput>> {
let input = req.input;
let output = GetBucketLocationOutput::default();
Ok(S3Response::new(output))
}
#[tracing::instrument]
async fn get_object(
&self,
req: S3Request<GetObjectInput>,
) -> S3Result<S3Response<GetObjectOutput>> {
let input = req.input;
let output = GetObjectOutput {
..Default::default()
};
Ok(S3Response::new(output))
}
#[tracing::instrument]
async fn head_bucket(
&self,
req: S3Request<HeadBucketInput>,
) -> S3Result<S3Response<HeadBucketOutput>> {
let input = req.input;
Ok(S3Response::new(HeadBucketOutput::default()))
}
#[tracing::instrument]
async fn head_object(
&self,
req: S3Request<HeadObjectInput>,
) -> S3Result<S3Response<HeadObjectOutput>> {
let input = req.input;
let output = HeadObjectOutput {
..Default::default()
};
Ok(S3Response::new(output))
}
#[tracing::instrument]
async fn list_buckets(
&self,
_: S3Request<ListBucketsInput>,
) -> S3Result<S3Response<ListBucketsOutput>> {
let output = ListBucketsOutput {
..Default::default()
};
Ok(S3Response::new(output))
}
#[tracing::instrument]
async fn list_objects(
&self,
req: S3Request<ListObjectsInput>,
) -> S3Result<S3Response<ListObjectsOutput>> {
let v2_resp = self.list_objects_v2(req.map_input(Into::into)).await?;
Ok(v2_resp.map_output(|v2| ListObjectsOutput {
contents: v2.contents,
delimiter: v2.delimiter,
encoding_type: v2.encoding_type,
name: v2.name,
prefix: v2.prefix,
max_keys: v2.max_keys,
..Default::default()
}))
}
#[tracing::instrument]
async fn list_objects_v2(
&self,
req: S3Request<ListObjectsV2Input>,
) -> S3Result<S3Response<ListObjectsV2Output>> {
let input = req.input;
let output = ListObjectsV2Output {
..Default::default()
};
Ok(S3Response::new(output))
}
#[tracing::instrument]
async fn put_object(
&self,
req: S3Request<PutObjectInput>,
) -> S3Result<S3Response<PutObjectOutput>> {
let input = req.input;
let output = PutObjectOutput {
..Default::default()
};
Ok(S3Response::new(output))
}
#[tracing::instrument]
async fn create_multipart_upload(
&self,
req: S3Request<CreateMultipartUploadInput>,
) -> S3Result<S3Response<CreateMultipartUploadOutput>> {
let input = req.input;
let output = CreateMultipartUploadOutput {
..Default::default()
};
Ok(S3Response::new(output))
}
#[tracing::instrument]
async fn upload_part(
&self,
req: S3Request<UploadPartInput>,
) -> S3Result<S3Response<UploadPartOutput>> {
let UploadPartInput {
body,
upload_id,
part_number,
..
} = req.input;
let output = UploadPartOutput {
..Default::default()
};
Ok(S3Response::new(output))
}
#[tracing::instrument]
async fn upload_part_copy(
&self,
req: S3Request<UploadPartCopyInput>,
) -> S3Result<S3Response<UploadPartCopyOutput>> {
let input = req.input;
let output = UploadPartCopyOutput {
..Default::default()
};
Ok(S3Response::new(output))
}
#[tracing::instrument]
async fn list_parts(
&self,
req: S3Request<ListPartsInput>,
) -> S3Result<S3Response<ListPartsOutput>> {
let ListPartsInput {
bucket,
key,
upload_id,
..
} = req.input;
let output = ListPartsOutput {
bucket: Some(bucket),
key: Some(key),
upload_id: Some(upload_id),
..Default::default()
};
Ok(S3Response::new(output))
}
#[tracing::instrument]
async fn complete_multipart_upload(
&self,
req: S3Request<CompleteMultipartUploadInput>,
) -> S3Result<S3Response<CompleteMultipartUploadOutput>> {
let CompleteMultipartUploadInput {
multipart_upload,
bucket,
key,
upload_id,
..
} = req.input;
let output = CompleteMultipartUploadOutput {
bucket: Some(bucket),
key: Some(key),
..Default::default()
};
Ok(S3Response::new(output))
}
#[tracing::instrument]
async fn abort_multipart_upload(
&self,
req: S3Request<AbortMultipartUploadInput>,
) -> S3Result<S3Response<AbortMultipartUploadOutput>> {
Ok(S3Response::new(AbortMultipartUploadOutput {
..Default::default()
}))
}
}
+1
View File
@@ -1,3 +1,4 @@
pub mod ecfs;
mod simple_fs;
pub use simple_fs::SimpleFS;