GithubHelp home page GithubHelp logo

mcorbin / meuse Goto Github PK

View Code? Open in Web Editor NEW
284.0 6.0 12.0 8.31 MB

A private Cargo crate registry, for Rust

Home Page: https://meuse.mcorbin.fr/

License: Eclipse Public License 2.0

Clojure 97.98% Shell 0.13% CSS 1.76% Dockerfile 0.13%
rust-lang rust registry crates alternative-registries cargo

meuse's Introduction

Meuse

A free crate registry for the Rust programming language.

It implements the alternative registries RFC and offers also various features (cf the Features section).

You can use Meuse to store your private crates, configure it to mirror crates.io...

Documentation is available at https://meuse.mcorbin.fr/

Features

  • Complete implementation of the alternative registries RFC (including search).
  • crates.io mirroring.
  • Multiple backends for crates files: filesystem, S3.
  • Multiple ways of managing the Git crate Index: git command, JGit.
  • Manage categories.
  • Manage users, roles, and tokens.
  • Manage crates.
  • Security: HTTPS support, TLS support for the PostgreSQL client.
  • Monitoring: Meuse exposes a Prometheus endpoint with various metrics (HTTP server, database pool, JVM metrics...).
  • Small frontend to explore crates.

Plan

Take a look at https://meuse.mcorbin.fr/roadmap/.

meuse's People

Contributors

aloso avatar mcorbin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

meuse's Issues

Show last token usage

To use as private registry, and provide a great monitoring on access (very important because it store sources of code...), I think it can be awesome to add the last usage of the token.
It requires to update database, Rest API and UI.

frontend authentication

Currently, there is no authentication.
We should decide which authentication mechanism we want to use.

can't not copy file from build stage

run docker build -t meuse .

it will fail on

Step 8/13 : COPY --from=build-env /app/target/uberjar/meuse-*-standalone.jar /app/meuse.jar
COPY failed: no source files were specified

Missing CSS after deployment

Hello,

I have configured my Meuse, that's awesome project, the first one usable for Rust private registry in private.

I just received that error:

front:2 Resource interpreted as Stylesheet but transferred with MIME type text/plain: "https://crates.media-io.com/static/css/style.css".
front:2 Resource interpreted as Stylesheet but transferred with MIME type text/plain: "https://crates.media-io.com/static/css/bootstrap.min.css".

Which render me the page without any css. Pretty bad design :P
Do you think it's possible to set the MIME type to "text/css" ?

I don't know Closure to contribute...

Best regards,
Marc-Antoine

issues with Dockerfile upgrade to jdk:17

encountered this error message from running $ docker build .:

Step 10/13 : RUN apt-get update && apt-get -y upgrade && apt-get install -y git
 ---> Running in 107a7a75fb08
/bin/sh: apt-get: command not found

It's confusing because the image it was using before (openjdk:11) did that step just fine, I guess they changed it.

I found another image, openjdk:slim-bullseye that works. "bullseye" is debian release code name. not sure if "slim" is worth much vs the fat one but it was the first one I got to work.

Initially I tried to do openjdk:17-alpine but that had a lot of differences (apk vs apt-get, need to install openssh, different command line options for useradd/groupadd and I abandoned that effort).

Login with OAuth2/SSO

To simplify user management, do you think it can be possible to add a OAuth2 (and maybe SSO) login system ?
Personally I use Google for my company, so it can be excellent to support that, even for open source.

I think a support of Google and Github and Gitlab will be awesome !
Do you think it can be complex to do that in Clojure ?

can't create a token

version 0.5.0

when following the example in the documentation:
curl --header "Content-Type: application/json" --request POST --data '{"name":"test_token","validity":10,"user":"root_user","password":"do_not_use_this_password"}' localhost:8855/api/v1/meuse/token

the result is

java.lang.NoSuchMethodError: java.nio.CharBuffer.flip()Ljava/nio/CharBuffer;
	at byte_streams.char_sequence$lazy_char_buffer_sequence$fn__11298.invoke(char_sequence.clj:77)
	at clojure.lang.LazySeq.sval(LazySeq.java:42)
	at clojure.lang.LazySeq.seq(LazySeq.java:51)
	at clojure.lang.RT.seq(RT.java:535)
	at clojure.core$seq__5402.invokeStatic(core.clj:137)
	at clojure.core$seq__5402.invoke(core.clj:137)
	at byte_streams.char_sequence$decode_byte_source$reify__11308.toString(char_sequence.clj:120)
	at byte_streams$fn__11633$f__11337__auto____11634.invoke(byte_streams.clj:556)
	at byte_streams.graph$conversion_fn$fn__10929$fn__10930.invoke(graph.clj:259)
	at clojure.lang.PersistentUnrolledVector$Card2.reduce(PersistentUnrolledVector.java:482)
	at clojure.core$reduce.invokeStatic(core.clj:6827)
	at clojure.core$reduce.invoke(core.clj:6810)
	at byte_streams.graph$conversion_fn$fn__10929.invoke(graph.clj:253)
	at byte_streams$convert.invokeStatic(byte_streams.clj:193)
	at byte_streams$convert.invoke(byte_streams.clj:162)
	at byte_streams$convert.invokeStatic(byte_streams.clj:177)
	at byte_streams$convert.invoke(byte_streams.clj:162)
	at meuse.request$convert_body_edn$fn__12262.invoke(request.clj:14)
	at clojure.core$update.invokeStatic(core.clj:6196)
	at clojure.core$update.invoke(core.clj:6188)
	at meuse.request$convert_body_edn.invokeStatic(request.clj:12)
	at meuse.request$convert_body_edn.invoke(request.clj:7)
	at meuse.interceptor.route$fn__18506.invokeStatic(route.clj:72)
	at meuse.interceptor.route$fn__18506.invoke(route.clj:69)
	at clojure.lang.MultiFn.invoke(MultiFn.java:229)
	at meuse.interceptor.route$fn__18518.invokeStatic(route.clj:92)
	at meuse.interceptor.route$fn__18518.invoke(route.clj:87)
	at exoscale.interceptor.impl$invoke_stage.invokeStatic(impl.cljc:45)
	at exoscale.interceptor.impl$invoke_stage.invoke(impl.cljc:39)
	at exoscale.interceptor.impl$enter.invokeStatic(impl.cljc:77)
	at exoscale.interceptor.impl$enter.invoke(impl.cljc:65)
	at exoscale.interceptor.impl$execute.invokeStatic(impl.cljc:104)
	at exoscale.interceptor.impl$execute.invoke(impl.cljc:101)
	at exoscale.interceptor$execute.invokeStatic(interceptor.cljc:41)
	at exoscale.interceptor$execute.invoke(interceptor.cljc:8)
	at exoscale.interceptor$execute.invokeStatic(interceptor.cljc:39)
	at exoscale.interceptor$execute.invoke(interceptor.cljc:8)
	at meuse.http$interceptor_handler$handler__18755.invoke(http.clj:44)
	at aleph.http.server$handle_request$fn__15150$f__8803__auto____15151.invoke(server.clj:166)
	at clojure.lang.AFn.run(AFn.java:22)
	at io.aleph.dirigiste.Executor$Worker$1.run(Executor.java:62)
	at manifold.executor$thread_factory$reify__8695$f__8696.invoke(executor.clj:47)
	at clojure.lang.AFn.run(AFn.java:22)
	at java.lang.Thread.run(Thread.java:748)

search: token needed

cargo search does not seem to pass the user token to the HTTP call.

Currently, Meuse checks the token for the search endpoint, so search calls with cargo are failing (but work with curl).

I can easily remove the auth check on the search endpoint, but I would like to first check if it's possible to (optionally) pass the token in Cargo itself.

Cargo yank fails with exception

Got an error when trying to run cargo yank. From the logs:

java.io.FileNotFoundException: /app/registry/se/rv/mycrate (No such file or directory)
	at java.base/java.io.FileInputStream.open0(Native Method)
	at java.base/java.io.FileInputStream.open(FileInputStream.java:219)
	at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
	at clojure.java.io$fn__11520.invokeStatic(io.clj:229)
	at clojure.java.io$fn__11520.invoke(io.clj:229)
	at clojure.java.io$fn__11433$G__11426__11440.invoke(io.clj:69)
	at clojure.java.io$fn__11532.invokeStatic(io.clj:258)
	at clojure.java.io$fn__11532.invoke(io.clj:254)
	at clojure.java.io$fn__11433$G__11426__11440.invoke(io.clj:69)
	at clojure.java.io$fn__11494.invokeStatic(io.clj:165)
	at clojure.java.io$fn__11494.invoke(io.clj:165)
	at clojure.java.io$fn__11446$G__11422__11453.invoke(io.clj:69)
	at clojure.java.io$reader.invokeStatic(io.clj:102)
	at clojure.java.io$reader.doInvoke(io.clj:86)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at clojure.lang.AFn.applyToHelper(AFn.java:154)
	at clojure.lang.RestFn.applyTo(RestFn.java:132)
	at clojure.core$apply.invokeStatic(core.clj:669)
	at clojure.core$slurp.invokeStatic(core.clj:6944)
	at clojure.core$slurp.doInvoke(core.clj:6944)
	at clojure.lang.RestFn.invoke(RestFn.java:410)
	at meuse.metadata$update_yank.invokeStatic(metadata.clj:65)
	at meuse.metadata$update_yank.invoke(metadata.clj:61)
	at meuse.api.crate.yank$update_yank$fn__12902.invoke(yank.clj:26)
	at meuse.api.crate.yank$update_yank.invokeStatic(yank.clj:25)
	at meuse.api.crate.yank$update_yank.invoke(yank.clj:11)
	at meuse.api.crate.yank$yank.invokeStatic(yank.clj:41)
	at meuse.api.crate.yank$yank.invoke(yank.clj:39)
	at meuse.inject$inject_crate_api_BANG_$fn__17980.invoke(inject.clj:115)
	at clojure.lang.MultiFn.invoke(MultiFn.java:229)
	at meuse.interceptor.route$fn__18970.invokeStatic(route.clj:66)
	at meuse.interceptor.route$fn__18970.invoke(route.clj:56)
	at clojure.lang.MultiFn.invoke(MultiFn.java:229)
	at meuse.interceptor.route$fn__18996.invokeStatic(route.clj:107)
	at meuse.interceptor.route$fn__18996.invoke(route.clj:102)
	at exoscale.interceptor.impl$invoke_stage.invokeStatic(impl.cljc:45)
	at exoscale.interceptor.impl$invoke_stage.invoke(impl.cljc:39)
	at exoscale.interceptor.impl$enter.invokeStatic(impl.cljc:77)
	at exoscale.interceptor.impl$enter.invoke(impl.cljc:65)
	at exoscale.interceptor.impl$execute.invokeStatic(impl.cljc:104)
	at exoscale.interceptor.impl$execute.invoke(impl.cljc:101)
	at exoscale.interceptor$execute.invokeStatic(interceptor.cljc:41)
	at exoscale.interceptor$execute.invoke(interceptor.cljc:8)
	at exoscale.interceptor$execute.invokeStatic(interceptor.cljc:39)
	at exoscale.interceptor$execute.invoke(interceptor.cljc:8)
	at meuse.http$interceptor_handler$handler__19386.invoke(http.clj:43)
	at ring.adapter.jetty$proxy_handler$fn__19341.invoke(jetty.clj:27)
	at ring.adapter.jetty.proxy$org.eclipse.jetty.server.handler.AbstractHandler$ff19274a.handle(Unknown Source)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.eclipse.jetty.server.Server.handle(Server.java:516)
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388)
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
	at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:383)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:882)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1036)
	at java.base/java.lang.Thread.run(Thread.java:829)

configurable s3 key prefix?

I noticed that the code in src/meuse/store/s3.clj pretty uniformly includes a notion of a prefix that is appended to the beginning of the object key. However, the config specification in src/meuse/spec.clj does not include any option to specify a key prefix for s3 storage.

Is the notion of prefix in the s3 storage code limited to prefixing keys by crate name and/or version? Or would it be possible to allow a configurable key prefix to be used, as a means of namespacing the s3 objects at smaller granularity than a bucket?

In other words, would it be possible to change the spec to

(defmethod crate-store "s3"
  [_]
  (s/keys :req-un [:s3/access-key
                   :s3/secret-key
                   :s3/endpoint
                   :s3/bucket
                   :s3/key-prefix]))

... and then integrate the s3/key-prefix value into the key-generating code in s3.clj?

(I am not a clojure developer - asking to check whether I am missing something big about this. I would be happy to attempt to make the changes myself if this is a desirable change and you think it will be straightforward.)

One problem a configurable key prefix would create is if the prefix configuration were changed, after objects had already been written to s3 -- the current code would not be able to find those objects, would it?

Another possible solution would be to include the crates_versions id in the s3 key, which would at least guarantee unique object keys.

Support for sparce registry

Hi. I want to ask if you have any plans to support sparse registries. This could be especially helpful with mirroring, since crates.io index is very heavy.

Or if you could give some tips on how this could be done and where to start I could try to implement this (although I never used Clojure).

by-crate-id query bug

https://github.com/mcorbin/meuse/blob/master/src/meuse/db/queries/category.clj#L27-L37

this code seems to return all categories, not just the categories associated with the crate.

I think the query needs to have the crate_id condition as part of the where clause, not as part of the left-join.

exapmle:

meuse=# select c.id, c.description, c.name, cc.crate_id
from categories c 
left join crates_categories cc on c.id=cc.category_id and cc.crate_id='2ff956f6-7b3e-49fc-8697-845d3a10fc75';

                  id                  |       description        |           name           |               crate_id               
--------------------------------------+--------------------------+--------------------------+--------------------------------------
 5527b5af-84ec-432f-b4a5-698048e5d096 | statistics               | statistics               | 2ff956f6-7b3e-49fc-8697-845d3a10fc75
 3759e640-2ba1-49c0-9ca3-10babdb07629 | science                  | science                  | 

"science" row should not be part of query results. if you change the second clause of the left-join to be in the where clause instead, it works without returning extra rows:

meuse=# select c.id, c.description, c.name, cc.crate_id
from categories c 
left join crates_categories cc on c.id=cc.category_id 
where cc.crate_id='2ff956f6-7b3e-49fc-8697-845d3a10fc75';

                  id                  |       description        |           name           |               crate_id               
--------------------------------------+--------------------------+--------------------------+--------------------------------------
 5527b5af-84ec-432f-b4a5-698048e5d096 | statistics               | statistics               | 2ff956f6-7b3e-49fc-8697-845d3a10fc75

fwiw I did try to fix this in the clojure code but failed :( - maybe next time.

Contribute to the Frontend

I read on your blog that you would like help improving the Frontend. I have a bit of free time, so I'd like to offer my help.

About me: I'm a CS student and live in Germany. I'm experienced in writing Java, Kotlin, Javascript, Typescript, HTML, CSS, SQL and Rust.

I'm not yet familiar with Clojure, but I guess I don't have to understand everything to work with the HTML templates :)

Could you create some issues with a frontend label, so I know what needs to be implemented?

P.S. could you add build instructions to the readme?

UI: list users

In the small UI, it can be important for private to see list of users.
And maybe also the number of token generated for each user.

Crates rename doesn't work with features (`package = ...`)

Hi and thanks for the great custom registry! :)

I've come over an issue that i don't know how to handle: it's impossible to use a crate that renames a crate and uses it as a feature.

Step to reproduce:

  1. Create two crates: $ cargo init --lib test-crate and $ cargo init --lib use-test-crate.
  2. Set up the test-crate (test-crate/Cargo.toml):
[package]
name = "test-crate"
version = "0.1.0"
authors = []
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
with = [ "bit-vec6" ]

[dependencies]
bit-vec6 = { version = "0.6", package = "bit-vec" }
  1. Set up the use-test-crate (use-test-crate/Cargo.toml):
[package]
name = "use-test-crate"
version = "0.1.0"
authors = []
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
test-crate = { version = "0.1.0", registry = "REGISTRY-NAME"}
  1. Publish the test-crate: $ cd test-crate && cargo publish --registry REGISTRY-NAME
  2. Try to build the use-test-crate: $ cd use-test-crate && cargo check
    Updating `ssh://git@..../crates-index.git` index
error: no matching package named `test-crate` found
location searched: registry `ssh://git@.../crates-index.git`
required by package `use-test-crate v0.1.0 (/home/mexus/test/rust/use-test-crate)`

cargo search however returns the expected results though:

$ cargo search --registry REGISTRY-NAME test-crate
test-crate = "0.1.0"    #

Any ideas how to fix the issue? :)

Crates with + in version return 404 via meuse

Downloading a crate from meuse returns a 404 if the crate version contains a + sign.

tested with openssl-src, flatc and a few other crates.

From crates.io the following works as expected:

curl -v -L "https://crates.io/api/v1/crates/flatc/0.1.0+1.12.0/download" -o tmpdl
curl -v -L "https://crates.io/api/v1/crates/openssl-src/111.10.1+1.1.1g/download" -o tmpdl

via meuse I get a 404 on:
curl -v -L "https://mirror.company.com/api/v1/mirror/flatc/0.1.0+1.12.0/download" -o tmpdl
curl -v -L "https://mirror.company.com/api/v1/mirror/openssl-src/111.10.1+1.1.1g/download" -o tmpdl

but 200 on:
curl -v -L "https://mirror.company.com/api/v1/mirror/unicase/2.6.0/download" -o tmpdl

So it seems that versions with a + are not working atm.

Optimize frontend

Google Chrome Audits shows some problems:

Performance

Fix these to speed up page loading for devices with a slow internet connection.

Accessibility

  • Background and foreground colors do not have a sufficient contrast ratio (all blue links)

Best Practices

  • Use HTTP/2
  • jQuery 3.3.1 has a known security vulnerability

How to fix

  • Enable text compression, enable HTTP/2, set Cache-control header: There are probably options in the web framework, I don't know
  • Unused CSS: This could be easily fixed by switching from CSS to SASS
  • Make links slightly darker
  • Upgrade to jQuery 3.4

need more information on getting started

Thanks for starting this project! I wanted to experiment with what you have so far but am having trouble getting started. I'm coming at this from the perspective of never having worked on a Clojure project. Basically I'm looking for a 'from git clone to cargo publish' steps. What I figured out so far:

  • build uses https://leiningen.org/
    • sudo apt install leiningen
    • lein uberjar
      • produces target/uberjar/meuse-0.1.0-SNAPSHOT-standalone.jar
  • depends on configuration file
    • example in dev/resources/config.yaml
    • passed in via environment variable
      • export meuse_configuration="/path/to/config.yml"
  • run with java -jar target/uberjar/meuse-0.1.0-SNAPSHOT-standalone.jar

at this point it's up and running, I already have postgres running on my machine but didn't create the meuse user/schema. I was expecting an exception when running meuse but it didn't so I figured I'd try and publish and that would tell me what I had to get working next. However I haven't figured out what URL to use for the private registry. Example:

in .cargo/config:

[registries]
icooke = { index = "http://dev-icooke:8855/what/goes/here" }

because every cargo api call results in:
DEBUG [2019-05-02 05:08:02,479] manifold-pool-2-1 - meuse.http request b561f5de-eb3d-4c7a-8692-dea6989b3d5c with subsystem :meuse.api.default with action :not-found

so... do you have an example registries entry?

database and repo out of sync sometimes

this was a mistake on my part but thought I should mention it as other situations might arise that are similar:

when I initially created the repo (metadata.path) I just created an empty directory and forgot about it. when I attempted to publish a crate the git part failed because it wasn't actually a repo. I fixed that and tried to publish again but meuse complained that the package version already existed. Sure enough it had written the database entries. I deleted those rows and was able to publish again.

it seems to me like the database writing and the git updating should be atomic.

crate name with dash

I have tried to publish on my private crate the gloo-file dependency.
It works but not when I try to depend on it in an another project.

Do you think it can be a Meuse issue ?

Rejects version as non-semver

I am trying to publish a crate with a semver-compatibile version, but Meuse rejects it:

   Uploading foo v7.0.0-alpha.4 (/path/to/foo)
error: api errors (status 200 OK): Wrong input parameters:
 - field vers: the value should be a valid semver string

Am I missing something here?
See also: https://semver.org/spec/v2.0.0.html#spec-item-9 (and the BNF at the bottom)

Documentation source files

Hi!

Is the documentation source files available somewhere? :) I have some issues to access the full documentation website, it would be nice to be able to download/build the full documentation locally :)

Kind Regards
Carl

Can't create token

It seems like you need a token to create a token. I tried the following in Postman:

POST localhost:8855/api/v1/meuse/user
Content-Type: application/json

{
    "name": "admin_token",
    "validity": 10,
    "user": "admin",
    "password": "REDACTED"
}

and got this result:

{
    "errors": [
        {
            "detail": "token missing in the header"
        }
    ]
}
Console output:
INFO [2019-12-10 18:21:49,102] manifold-pool-2-21 - meuse.http handler is  :meuse.api.meuse.http/new-user
DEBUG [2019-12-10 18:21:49,103] manifold-pool-2-21 - meuse.http request 2feda17a-2443-4360-904a-6d662f189180 with subsystem :meuse.api.meuse.http with action :new-user
ERROR [2019-12-10 18:21:49,105] manifold-pool-2-21 - meuse.error 2feda17a-2443-4360-904a-6d662f189180 #error {
 :cause token missing in the header
 :data {:type :exoscale.ex/forbidden}
 :via
 [{:type clojure.lang.ExceptionInfo
   :message token missing in the header
   :data {:type :exoscale.ex/forbidden}
   :at [exoscale.ex$ex_info invokeStatic ex.clj 237]}]
 :trace
 [[exoscale.ex$ex_info invokeStatic ex.clj 237]
  [exoscale.ex$ex_info invoke ex.clj 219]
  [exoscale.ex$ex_forbidden invokeStatic ex.clj 265]
  [exoscale.ex$ex_forbidden invoke ex.clj 265]
  [exoscale.ex$ex_forbidden invokeStatic ex.clj 265]
  [exoscale.ex$ex_forbidden invoke ex.clj 265]
  [meuse.auth.request$check_user invokeStatic request.clj 31]
  [meuse.auth.request$check_user invoke request.clj 10]
  [meuse.http$eval21915$fn__21916 invoke http.clj 79]
  [clojure.lang.MultiFn invoke MultiFn.java 229]
  [meuse.http$get_handler$handler__21926 invoke http.clj 123]
  [ring.middleware.resource$wrap_resource_prefer_resources$fn__21816 invoke resource.clj 25]
  [meuse.middleware$wrap_json$fn__20645 invoke middleware.clj 14]
  [ring.middleware.keyword_params$wrap_keyword_params$fn__21868 invoke keyword_params.clj 53]
  [ring.middleware.params$wrap_params$fn__21892 invoke params.clj 67]
  [aleph.http.server$handle_request$fn__12888$f__7600__auto____12889 invoke server.clj 166]
  [clojure.lang.AFn run AFn.java 22]
  [io.aleph.dirigiste.Executor$Worker$1 run Executor.java 62]
  [manifold.executor$thread_factory$reify__7482$f__7483 invoke executor.clj 47]
  [clojure.lang.AFn run AFn.java 22]
  [java.lang.Thread run Thread.java 834]]} http error {:type :exoscale.ex/forbidden} 403

Extend database configuration with support for schema

Add schema to database configuration. It will look like this.

database:
  user: "meuse"
  host: "127.0.0.1"
  name: "meuse"
  schema: "project1"

Tables will be created in that schema. It means that instead of tabname it would be project1.tabname.

This is a very easy to do. You just need to issue 2 SQL commands:

CREATE schema IF NOT EXISTS project1;
SET search_path TO project1;

and access tables like you normally do now.

Documentation hosting

Hello again,

It's more a question, but can be a great feature ...
Do you think meuse can generate and host the Rust documentation of projects ?

Marc-Antoine

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.