mirror of
https://github.com/dathere/ckan-devstaller.git
synced 2025-11-09 13:39:49 +00:00
Compare commits
16 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0ac63a368 | ||
|
|
6c173fb779 | ||
|
|
e5d9324c7a | ||
|
|
8489e50eb9 | ||
|
|
475bcc4932 | ||
|
|
0e263202a1 | ||
|
|
82200d5f94 | ||
|
|
d2e2c70dca | ||
|
|
518ef00432 | ||
|
|
93fcb8a2c5 | ||
|
|
a0cb19978b | ||
|
|
a24d49042b | ||
|
|
6af03d8c0b | ||
|
|
cb0802a4b2 | ||
|
|
1f2b68f4d2 | ||
|
|
451184a914 |
25 changed files with 941 additions and 278 deletions
26
.github/workflows/run-ckan-only-install.yml
vendored
Normal file
26
.github/workflows/run-ckan-only-install.yml
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
name: Verify ckan-devstaller runs CKAN-only install successfully
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths-ignore:
|
||||||
|
- 'docs/**'
|
||||||
|
- 'README.md'
|
||||||
|
workflow_dispatch:
|
||||||
|
jobs:
|
||||||
|
ckanonlyinstall:
|
||||||
|
name: Run ckan-devstaller with a CKAN-only install
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
permissions:
|
||||||
|
# For the git-auto-commit-action
|
||||||
|
contents: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Install Rust stable toolchain
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
- name: Cache cargo deps and target folder
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
workspaces: ". -> target"
|
||||||
|
- name: Run ckan-devstaller
|
||||||
|
run: cargo run --release --verbose -- --ckan-version 2.11.4 --skip-interactive --skip-run
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
<a href="https://ckan-devstaller.dathere.com"><img width="1165" height="668" alt="{1329F0BA-A29F-4BF8-BB6B-E3BA84FDAFCC}" src="https://github.com/user-attachments/assets/8f0cc4ef-d90d-4715-ba21-9083dff0c3ff" /></a>
|
<a href="https://ckan-devstaller.dathere.com"><img width="1165" height="668" alt="{1329F0BA-A29F-4BF8-BB6B-E3BA84FDAFCC}" src="https://github.com/user-attachments/assets/8f0cc4ef-d90d-4715-ba21-9083dff0c3ff" /></a>
|
||||||
|
|
||||||
|
|
||||||
`ckan-devstaller` attempts to install a CKAN instance using [ckan-compose](https://github.com/tino097/ckan-compose) for development usage in a new Ubuntu 22.04 instance.
|
`ckan-devstaller` attempts to install a [CKAN](https://ckan.org) instance using [ckan-compose](https://github.com/tino097/ckan-compose/tree/ckan-devstaller) for development usage in a new Ubuntu 22.04 instance.
|
||||||
|
|
||||||
You may find `ckan-devstaller` useful for:
|
You may find `ckan-devstaller` useful for:
|
||||||
|
|
||||||
|
|
@ -29,6 +29,7 @@ You may find the following guides useful while developing with CKAN:
|
||||||
- [Customize your config file](https://docs.ckan.org/en/latest/extensions/index.html)
|
- [Customize your config file](https://docs.ckan.org/en/latest/extensions/index.html)
|
||||||
- [Create test data](https://docs.ckan.org/en/latest/maintaining/getting-started.html#creating-test-data)
|
- [Create test data](https://docs.ckan.org/en/latest/maintaining/getting-started.html#creating-test-data)
|
||||||
- [Visit ckan.org](https://ckan.org)
|
- [Visit ckan.org](https://ckan.org)
|
||||||
|
- [Interact with your CKAN API at ckanaction.dathere.com](https://ckanaction.dathere.com)
|
||||||
|
|
||||||
## `ckan-devstaller` demos
|
## `ckan-devstaller` demos
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
/** biome-ignore-all lint/suspicious/noArrayIndexKey: Would need to look into this trivial issue */
|
/** biome-ignore-all lint/suspicious/noArrayIndexKey: Would need to look into this trivial issue */
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { CodeBlock } from "fumadocs-ui/components/codeblock";
|
||||||
import defaultMdxComponents from "fumadocs-ui/mdx";
|
import defaultMdxComponents from "fumadocs-ui/mdx";
|
||||||
import { cn } from "fumadocs-ui/utils/cn";
|
import { cn } from "fumadocs-ui/utils/cn";
|
||||||
import {
|
import {
|
||||||
|
|
@ -8,11 +9,14 @@ import {
|
||||||
GitMergeIcon,
|
GitMergeIcon,
|
||||||
HomeIcon,
|
HomeIcon,
|
||||||
SailboatIcon,
|
SailboatIcon,
|
||||||
|
TerminalIcon,
|
||||||
|
Trash2Icon,
|
||||||
ZapIcon,
|
ZapIcon,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useState } from "react";
|
import { type HTMLProps, type ReactNode, useState } from "react";
|
||||||
|
import { Pre } from "@/components/codeblock";
|
||||||
import { buttonVariants } from "@/components/ui/button";
|
import { buttonVariants } from "@/components/ui/button";
|
||||||
import CkanDevstallerDemo from "./ckan-devstaller-demo.gif";
|
import CkanDevstallerDemo from "./ckan-devstaller-demo.gif";
|
||||||
|
|
||||||
|
|
@ -37,8 +41,34 @@ export default function HomePage() {
|
||||||
>
|
>
|
||||||
<div className="relative mb-4">
|
<div className="relative mb-4">
|
||||||
<Hero />
|
<Hero />
|
||||||
|
<Why />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<hr className="mt-12 mb-4" />
|
||||||
|
<footer className="flex flex-col bg-brand-secondary pb-12 text-brand-secondary-foreground rounded-2xl">
|
||||||
|
<p className="mb-1 text-xl font-semibold">ckan-devstaller</p>
|
||||||
|
<p className="text-xs">
|
||||||
|
Provided by{" "}
|
||||||
|
<a
|
||||||
|
href="https://dathere.com"
|
||||||
|
target="_blank"
|
||||||
|
className="font-medium text-blue-400"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
datHere
|
||||||
|
</a>
|
||||||
|
.{" "}
|
||||||
|
<a
|
||||||
|
href="https://dathere.com/privacy-policy/"
|
||||||
|
target="_blank"
|
||||||
|
className="font-medium text-blue-400"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
Privacy Policy
|
||||||
|
</a>
|
||||||
|
.
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
</main>
|
</main>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
@ -88,7 +118,7 @@ function Hero() {
|
||||||
</p>
|
</p>
|
||||||
<div className="inline-flex items-center gap-3 max-md:mx-auto mb-8">
|
<div className="inline-flex items-center gap-3 max-md:mx-auto mb-8">
|
||||||
<Link
|
<Link
|
||||||
href="/docs"
|
href="/docs/builder"
|
||||||
className={cn(
|
className={cn(
|
||||||
buttonVariants({ size: "lg", className: "rounded-full" }),
|
buttonVariants({ size: "lg", className: "rounded-full" }),
|
||||||
)}
|
)}
|
||||||
|
|
@ -109,11 +139,7 @@ function Hero() {
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<Cards>
|
<Cards>
|
||||||
<Card
|
<Card icon={<ZapIcon />} href="/docs/builder" title="Quick start">
|
||||||
icon={<ZapIcon />}
|
|
||||||
href="/docs/quick-start"
|
|
||||||
title="Quick start"
|
|
||||||
>
|
|
||||||
Get started with ckan-devstaller and install CKAN within minutes
|
Get started with ckan-devstaller and install CKAN within minutes
|
||||||
</Card>
|
</Card>
|
||||||
<Card icon={<BlocksIcon />} href="/docs/builder" title="Builder">
|
<Card icon={<BlocksIcon />} href="/docs/builder" title="Builder">
|
||||||
|
|
@ -124,8 +150,7 @@ function Hero() {
|
||||||
href="/docs/reference/installation-architecture"
|
href="/docs/reference/installation-architecture"
|
||||||
title="Installation architecture"
|
title="Installation architecture"
|
||||||
>
|
>
|
||||||
Learn about where files are installed after running
|
Learn about where files are installed after running ckan-devstaller
|
||||||
ckan-devstaller
|
|
||||||
</Card>
|
</Card>
|
||||||
<Card
|
<Card
|
||||||
icon={<GitMergeIcon />}
|
icon={<GitMergeIcon />}
|
||||||
|
|
@ -150,7 +175,7 @@ function PreviewImages() {
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="p-8 min-w-[800px] overflow-hidden xl:-mx-12 dark:[mask-image:linear-gradient(to_top,transparent,white_40px)]">
|
<div className="p-8 min-w-[600px] md:min-w-[800px] overflow-hidden xl:-mx-12 dark:[mask-image:linear-gradient(to_top,transparent,white_40px)]">
|
||||||
<div className="absolute flex flex-row left-1/2 -translate-1/2 bottom-4 z-2 p-1 rounded-full bg-fd-card border shadow-xl dark:shadow-fd-background">
|
<div className="absolute flex flex-row left-1/2 -translate-1/2 bottom-4 z-2 p-1 rounded-full bg-fd-card border shadow-xl dark:shadow-fd-background">
|
||||||
{/* <div
|
{/* <div
|
||||||
role="none"
|
role="none"
|
||||||
|
|
@ -176,7 +201,7 @@ function PreviewImages() {
|
||||||
alt="preview"
|
alt="preview"
|
||||||
priority
|
priority
|
||||||
className={cn(
|
className={cn(
|
||||||
"rounded-xl w-full select-none duration-1000 animate-in fade-in -mb-60 slide-in-from-bottom-12 lg:-mb-0",
|
"rounded-xl w-full select-none duration-1000 animate-in fade-in md:-mb-60 slide-in-from-bottom-12 lg:-mb-0",
|
||||||
active !== i && "hidden",
|
active !== i && "hidden",
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
@ -184,3 +209,207 @@ function PreviewImages() {
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Why() {
|
||||||
|
return (
|
||||||
|
<div className="relative overflow-hidden border-x border-t p-2">
|
||||||
|
<WhyInteractive
|
||||||
|
codeblockInstall={
|
||||||
|
<CodeBlock lang="bash">
|
||||||
|
<Pre className="text-wrap pl-4">./ckan-devstaller</Pre>
|
||||||
|
</CodeBlock>
|
||||||
|
}
|
||||||
|
codeblockUninstall={
|
||||||
|
<CodeBlock lang="bash">
|
||||||
|
<Pre className="text-wrap pl-4">./ckan-devstaller uninstall</Pre>
|
||||||
|
</CodeBlock>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function WhyInteractive(props: {
|
||||||
|
codeblockInstall: ReactNode;
|
||||||
|
codeblockUninstall: ReactNode;
|
||||||
|
}) {
|
||||||
|
const [active, setActive] = useState(0);
|
||||||
|
const items = [
|
||||||
|
[
|
||||||
|
<ZapIcon className="w-4 h-4 inline-block" key={0} />,
|
||||||
|
"Install CKAN within minutes",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
<BlocksIcon className="w-4 h-4 inline-block" key={1} />,
|
||||||
|
"Customize your installation",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
<TerminalIcon className="w-4 h-4 inline-block" key={2} />,
|
||||||
|
"Designed for developers",
|
||||||
|
],
|
||||||
|
[
|
||||||
|
<Trash2Icon className="w-4 h-4 inline-block" key={3} />,
|
||||||
|
"Uninstall with ease",
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
id="why-interactive"
|
||||||
|
className="flex flex-col-reverse gap-3 md:flex-row md:min-h-[200px]"
|
||||||
|
>
|
||||||
|
<div className="flex flex-col">
|
||||||
|
{items.map((item, i) => (
|
||||||
|
<button
|
||||||
|
key={item[1] as string}
|
||||||
|
ref={(element) => {
|
||||||
|
if (!element || i !== active) return;
|
||||||
|
}}
|
||||||
|
type="button"
|
||||||
|
className={cn(
|
||||||
|
"transition-colors text-nowrap border border-transparent rounded-lg px-3 py-2.5 text-start text-sm text-fd-muted-foreground font-medium",
|
||||||
|
i === active
|
||||||
|
? "text-fd-primary bg-fd-primary/10 border-fd-primary/10"
|
||||||
|
: "hover:text-fd-accent-foreground/80 cursor-pointer",
|
||||||
|
)}
|
||||||
|
onClick={() => {
|
||||||
|
setActive(i);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{item[0]} {item[1]}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<style>
|
||||||
|
{`
|
||||||
|
@keyframes why-interactive-x {
|
||||||
|
from {
|
||||||
|
width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}`}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div className="flex-1 p-4 border border-fd-primary/10 bg-fd-card/40 rounded-lg shadow-lg">
|
||||||
|
{active === 0 ? (
|
||||||
|
<WhyPanel>
|
||||||
|
<h3>
|
||||||
|
<ZapIcon className="w-4 h-4 inline-block mr-1 mb-1" />
|
||||||
|
Install CKAN within minutes.
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
One of the primary goals of ckan-devstaller is to ease
|
||||||
|
installation of CKAN for development. Built with Rust for speed
|
||||||
|
and streamlining installation with{" "}
|
||||||
|
<a href="https://github.com/tino097/ckan-compose/tree/ckan-devstaller">
|
||||||
|
ckan-compose
|
||||||
|
</a>
|
||||||
|
, ckan-devstaller improves installation speeds{" "}
|
||||||
|
<strong>from hours/days to just minutes</strong> depending on your
|
||||||
|
download speed.
|
||||||
|
</p>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Link href="/docs/builder" className={cn(buttonVariants(), "not-prose")}>
|
||||||
|
Get started
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</WhyPanel>
|
||||||
|
) : null}
|
||||||
|
{active === 1 ? (
|
||||||
|
<WhyPanel>
|
||||||
|
<h3>
|
||||||
|
<BlocksIcon className="w-4 h-4 inline-block mr-1 mb-1" />
|
||||||
|
Customize your installation with the Builder.
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
Try out the interactive web GUI for customizing your CKAN
|
||||||
|
installation. You can select:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Presets</li>
|
||||||
|
<li>CKAN version</li>
|
||||||
|
<li>Extensions</li>
|
||||||
|
<li>Features</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
Then you can copy the provided ckan-devstaller command to run your
|
||||||
|
selected configuration.
|
||||||
|
</p>
|
||||||
|
<div className="mt-4 flex flex-row items-center gap-1.5 not-prose">
|
||||||
|
<Link href="/docs/builder" className={cn(buttonVariants())}>
|
||||||
|
Try out the Builder
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</WhyPanel>
|
||||||
|
) : null}
|
||||||
|
{active === 2 ? (
|
||||||
|
<WhyPanel>
|
||||||
|
<h3>
|
||||||
|
<TerminalIcon className="w-4 h-4 inline-block mr-1 mb-1" />
|
||||||
|
Designed for developers.
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
We've kept development use cases in mind while developing
|
||||||
|
ckan-devstaller, such as:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Trying out a new version of CKAN</li>
|
||||||
|
<li>Developing CKAN extensions and themes</li>
|
||||||
|
</ul>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Link
|
||||||
|
href="/docs/reference/installation-architecture"
|
||||||
|
className={cn(buttonVariants(), "not-prose")}
|
||||||
|
>
|
||||||
|
View the installation architecture
|
||||||
|
</Link>
|
||||||
|
<Link
|
||||||
|
href="https://github.com/dathere/ckan-devstaller"
|
||||||
|
className={cn(buttonVariants({ variant: "ghost" }))}
|
||||||
|
>
|
||||||
|
Source code
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</WhyPanel>
|
||||||
|
) : null}
|
||||||
|
{active === 3 ? (
|
||||||
|
<WhyPanel>
|
||||||
|
<h3>
|
||||||
|
<Trash2Icon className="w-4 h-4 inline-block mr-1 mb-1" />
|
||||||
|
Uninstall CKAN with ease.
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
After you've installed CKAN with ckan-devstaller, you can
|
||||||
|
uninstall CKAN with ease. This allows for quickly re-installing
|
||||||
|
CKAN for a different use case.
|
||||||
|
</p>
|
||||||
|
{props.codeblockUninstall}
|
||||||
|
<Link
|
||||||
|
href="/docs/tutorials/uninstall-ckan"
|
||||||
|
className={cn(buttonVariants(), "not-prose")}
|
||||||
|
>
|
||||||
|
Learn more about uninstalling
|
||||||
|
</Link>
|
||||||
|
</WhyPanel>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function WhyPanel(props: HTMLProps<HTMLDivElement>) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
{...props}
|
||||||
|
className={cn(
|
||||||
|
"duration-700 animate-in fade-in text-sm prose",
|
||||||
|
props.className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@radix-ui/react-accordion": "^1.2.12",
|
"@radix-ui/react-accordion": "^1.2.12",
|
||||||
"@radix-ui/react-collapsible": "^1.1.12",
|
"@radix-ui/react-collapsible": "^1.1.12",
|
||||||
|
"@radix-ui/react-label": "^2.1.7",
|
||||||
|
"@radix-ui/react-switch": "^1.2.6",
|
||||||
"@radix-ui/react-tabs": "^1.1.13",
|
"@radix-ui/react-tabs": "^1.1.13",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
|
@ -227,6 +229,8 @@
|
||||||
|
|
||||||
"@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="],
|
"@radix-ui/react-id": ["@radix-ui/react-id@1.1.1", "", { "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg=="],
|
||||||
|
|
||||||
|
"@radix-ui/react-label": ["@radix-ui/react-label@2.1.7", "", { "dependencies": { "@radix-ui/react-primitive": "2.1.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ=="],
|
||||||
|
|
||||||
"@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w=="],
|
"@radix-ui/react-navigation-menu": ["@radix-ui/react-navigation-menu@1.2.14", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-collection": "1.1.7", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-callback-ref": "1.1.1", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-layout-effect": "1.1.1", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-visually-hidden": "1.2.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w=="],
|
||||||
|
|
||||||
"@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA=="],
|
"@radix-ui/react-popover": ["@radix-ui/react-popover@1.1.15", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", "aria-hidden": "^1.2.4", "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA=="],
|
||||||
|
|
@ -245,6 +249,8 @@
|
||||||
|
|
||||||
"@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
"@radix-ui/react-slot": ["@radix-ui/react-slot@1.2.3", "", { "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A=="],
|
||||||
|
|
||||||
|
"@radix-ui/react-switch": ["@radix-ui/react-switch@1.2.6", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-use-controllable-state": "1.2.2", "@radix-ui/react-use-previous": "1.1.1", "@radix-ui/react-use-size": "1.1.1" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ=="],
|
||||||
|
|
||||||
"@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="],
|
"@radix-ui/react-tabs": ["@radix-ui/react-tabs@1.1.13", "", { "dependencies": { "@radix-ui/primitive": "1.1.3", "@radix-ui/react-context": "1.1.2", "@radix-ui/react-direction": "1.1.1", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-roving-focus": "1.1.11", "@radix-ui/react-use-controllable-state": "1.2.2" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A=="],
|
||||||
|
|
||||||
"@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="],
|
"@radix-ui/react-use-callback-ref": ["@radix-ui/react-use-callback-ref@1.1.1", "", { "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg=="],
|
||||||
|
|
|
||||||
|
|
@ -11,26 +11,26 @@ export default function CKANVersionBuilderSection({ config, setConfig }: any) {
|
||||||
<Cards>
|
<Cards>
|
||||||
<Card
|
<Card
|
||||||
icon={<SailboatIcon />}
|
icon={<SailboatIcon />}
|
||||||
title="2.11.3"
|
title="2.11.4"
|
||||||
className={
|
className={
|
||||||
config.ckanVersion === "2.11.3"
|
config.ckanVersion === "2.11.4"
|
||||||
? selectedCardClasses
|
? selectedCardClasses
|
||||||
: "cursor-pointer"
|
: "cursor-pointer"
|
||||||
}
|
}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setConfig({ ...config, ckanVersion: "2.11.3" });
|
setConfig({ ...config, ckanVersion: "2.11.4" });
|
||||||
}}
|
}}
|
||||||
></Card>
|
></Card>
|
||||||
<Card
|
<Card
|
||||||
icon={<SailboatIcon />}
|
icon={<SailboatIcon />}
|
||||||
title="2.10.8"
|
title="2.10.9"
|
||||||
className={
|
className={
|
||||||
config.ckanVersion === "2.10.8"
|
config.ckanVersion === "2.10.9"
|
||||||
? selectedCardClasses
|
? selectedCardClasses
|
||||||
: "cursor-pointer"
|
: "cursor-pointer"
|
||||||
}
|
}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setConfig({ ...config, ckanVersion: "2.10.8" });
|
setConfig({ ...config, ckanVersion: "2.10.9" });
|
||||||
}}
|
}}
|
||||||
></Card>
|
></Card>
|
||||||
</Cards>
|
</Cards>
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ export default function PresetsBuilderSection({
|
||||||
setConfig({
|
setConfig({
|
||||||
...config,
|
...config,
|
||||||
preset: "dathere-default",
|
preset: "dathere-default",
|
||||||
ckanVersion: "2.11.3",
|
ckanVersion: "2.11.4",
|
||||||
extensions: ["ckanext-scheming", "DataStore", "DataPusher+"],
|
extensions: ["ckanext-scheming", "DataStore", "DataPusher+"],
|
||||||
features: ["enable-ssh"],
|
features: ["enable-ssh"],
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,13 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { CodeBlock, Pre } from "fumadocs-ui/components/codeblock";
|
import { CodeBlock, Pre } from "fumadocs-ui/components/codeblock";
|
||||||
import defaultMdxComponents from "fumadocs-ui/mdx";
|
import { Label } from "@/components/ui/label"
|
||||||
import {
|
import { Switch } from "@/components/ui/switch"
|
||||||
BarChartBigIcon,
|
|
||||||
BlocksIcon,
|
|
||||||
SailboatIcon,
|
|
||||||
TerminalSquareIcon,
|
|
||||||
} from "lucide-react";
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import PresetsBuilderSection from "./builder-sections/presets";
|
import PresetsBuilderSection from "@/components/builder-sections/presets";
|
||||||
import CKANVersionBuilderSection from "./builder-sections/ckan-version";
|
import CKANVersionBuilderSection from "@/components/builder-sections/ckan-version";
|
||||||
import CKANExtensionsBuilderSection from "./builder-sections/ckan-extensions";
|
import CKANExtensionsBuilderSection from "@/components/builder-sections/ckan-extensions";
|
||||||
import FeaturesBuilderSection from "./builder-sections/features";
|
import FeaturesBuilderSection from "@/components/builder-sections/features";
|
||||||
|
|
||||||
export type Config = {
|
export type Config = {
|
||||||
preset: string | undefined;
|
preset: string | undefined;
|
||||||
|
|
@ -25,11 +20,28 @@ export const selectedCardClasses =
|
||||||
"bg-blue-100 dark:bg-blue-950 border-blue-300 dark:border-blue-900 border-2";
|
"bg-blue-100 dark:bg-blue-950 border-blue-300 dark:border-blue-900 border-2";
|
||||||
|
|
||||||
export default function Builder() {
|
export default function Builder() {
|
||||||
const { Card, Cards } = defaultMdxComponents;
|
const [downloadScript, setDownloadScript] = useState(true);
|
||||||
|
const downloadScriptString = `#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Update/Upgrade system dependencies
|
||||||
|
sudo apt update -y
|
||||||
|
sudo apt upgrade -y
|
||||||
|
|
||||||
|
# Install curl
|
||||||
|
sudo apt install curl -y
|
||||||
|
|
||||||
|
# Change to the home directory
|
||||||
|
cd ~/
|
||||||
|
|
||||||
|
# Download the ckan-devstaller binary file
|
||||||
|
wget https://github.com/dathere/ckan-devstaller/releases/download/0.3.1/ckan-devstaller
|
||||||
|
|
||||||
|
# Add execute permission to ckan-devstaller binary file
|
||||||
|
sudo chmod +x ./ckan-devstaller\n\n# Run ckan-devstaller script\n`;
|
||||||
const [command, setCommand] = useState("./ckan-devstaller");
|
const [command, setCommand] = useState("./ckan-devstaller");
|
||||||
const [config, setConfig] = useState<Config>({
|
const [config, setConfig] = useState<Config>({
|
||||||
preset: "ckan-only",
|
preset: "ckan-only",
|
||||||
ckanVersion: "2.11.3",
|
ckanVersion: "2.11.4",
|
||||||
extensions: [],
|
extensions: [],
|
||||||
features: [],
|
features: [],
|
||||||
});
|
});
|
||||||
|
|
@ -52,12 +64,16 @@ ${ckanVersionString}${extensionsString ? extensionsString : ""}${featuresString
|
||||||
}, [config]);
|
}, [config]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-3 gap-4">
|
<div className="md:grid md:grid-cols-3 md:gap-4">
|
||||||
<div className="col-span-1 border-r-2 pr-4">
|
<div className="md:col-span-1 md:border-r-2 md:pr-4">
|
||||||
<div className="sticky top-8">
|
<div className="sticky top-8">
|
||||||
<h2>ckan-devstaller command</h2>
|
<h2>ckan-devstaller command</h2>
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<Switch defaultChecked={downloadScript} onCheckedChange={() => setDownloadScript(!downloadScript)} id="download-script" />
|
||||||
|
<Label htmlFor="download-script">Include download script?</Label>
|
||||||
|
</div>
|
||||||
<CodeBlock title="Installation command">
|
<CodeBlock title="Installation command">
|
||||||
<Pre className="text-wrap pl-4 max-w-[21rem]">{command}</Pre>
|
<Pre className="text-wrap pl-4 max-w-[21rem]">{downloadScript ? downloadScriptString : ""}{command}</Pre>
|
||||||
</CodeBlock>
|
</CodeBlock>
|
||||||
<h2>Selected configuration</h2>
|
<h2>Selected configuration</h2>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -87,7 +103,7 @@ ${ckanVersionString}${extensionsString ? extensionsString : ""}${featuresString
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-2">
|
<div className="md:col-span-2">
|
||||||
<h2>Configuration options</h2>
|
<h2>Configuration options</h2>
|
||||||
<PresetsBuilderSection config={config} setConfig={setConfig} />
|
<PresetsBuilderSection config={config} setConfig={setConfig} />
|
||||||
<CKANVersionBuilderSection config={config} setConfig={setConfig} />
|
<CKANVersionBuilderSection config={config} setConfig={setConfig} />
|
||||||
|
|
|
||||||
9
docs/components/steps.tsx
Normal file
9
docs/components/steps.tsx
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
import type { ReactNode } from 'react';
|
||||||
|
|
||||||
|
export function Steps({ children }: { children: ReactNode }) {
|
||||||
|
return <div className="fd-steps">{children}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Step({ children }: { children: ReactNode }) {
|
||||||
|
return <div className="fd-step">{children}</div>;
|
||||||
|
}
|
||||||
|
|
@ -20,6 +20,7 @@ const buttonVariants = cva(
|
||||||
sm: "h-9 px-3",
|
sm: "h-9 px-3",
|
||||||
lg: "h-11 px-6",
|
lg: "h-11 px-6",
|
||||||
xs: "px-2 py-1.5 text-xs",
|
xs: "px-2 py-1.5 text-xs",
|
||||||
|
"icon-xs": "p-1 [&_svg]:size-4"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
defaultVariants: {
|
defaultVariants: {
|
||||||
|
|
|
||||||
26
docs/components/ui/label.tsx
Normal file
26
docs/components/ui/label.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as LabelPrimitive from "@radix-ui/react-label"
|
||||||
|
import { cva, type VariantProps } from "class-variance-authority"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const labelVariants = cva(
|
||||||
|
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Label = React.forwardRef<
|
||||||
|
React.ElementRef<typeof LabelPrimitive.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root> &
|
||||||
|
VariantProps<typeof labelVariants>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<LabelPrimitive.Root
|
||||||
|
ref={ref}
|
||||||
|
className={cn(labelVariants(), className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
Label.displayName = LabelPrimitive.Root.displayName
|
||||||
|
|
||||||
|
export { Label }
|
||||||
29
docs/components/ui/switch.tsx
Normal file
29
docs/components/ui/switch.tsx
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as SwitchPrimitives from "@radix-ui/react-switch"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
const Switch = React.forwardRef<
|
||||||
|
React.ElementRef<typeof SwitchPrimitives.Root>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
|
||||||
|
>(({ className, ...props }, ref) => (
|
||||||
|
<SwitchPrimitives.Root
|
||||||
|
className={cn(
|
||||||
|
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-green-500 data-[state=unchecked]:bg-gray-500 dark:data-[state=checked]:bg-blue-500 dark:data-[state=unchecked]:bg-gray-600",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
ref={ref}
|
||||||
|
>
|
||||||
|
<SwitchPrimitives.Thumb
|
||||||
|
className={cn(
|
||||||
|
"pointer-events-none block h-5 w-5 rounded-full bg-white dark:bg-blue-800 shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</SwitchPrimitives.Root>
|
||||||
|
))
|
||||||
|
Switch.displayName = SwitchPrimitives.Root.displayName
|
||||||
|
|
||||||
|
export { Switch }
|
||||||
|
|
@ -4,6 +4,19 @@ description: Customize your CKAN installation before running ckan-devstaller.
|
||||||
icon: Blocks
|
icon: Blocks
|
||||||
---
|
---
|
||||||
|
|
||||||
|
ckan-devstaller attempts to install a CKAN instance from source along with [ckan-compose](https://github.com/tino097/ckan-compose/tree/ckan-devstaller) and other optional features, intended for development use in a new Ubuntu 22.04 instance.
|
||||||
|
|
||||||
|
<Callout title="Please run ckan-devstaller in a new Ubuntu 22.04 instance only" type="error">Make sure `ckan-devstaller` is run in a **new** Ubuntu 22.04 instance. Do NOT run `ckan-devstaller` in an existing instance that is important for your usage.</Callout>
|
||||||
|
|
||||||
|
import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';
|
||||||
|
|
||||||
|
<Accordions type="single">
|
||||||
|
<Accordion title="Note for VirtualBox users">If you are using Ubuntu 22.04 on VirtualBox, you may need to add your user to the sudoers file before running the ckan-devstaller install script. Open a terminal in your virtual machine (VM), run `su -` and log in as the root user with the password you used to set up the VM, then type: <br /><br />`sudo adduser <username> sudo`<br /><br /> where `<username>` is your username then restart your VM and run the ckan-devstaller installer script.</Accordion>
|
||||||
|
<Accordion title="Note for ARM64 users">Currently `ckan-devstaller` supports `x86_64` architecture. `ARM64` support is planned.</Accordion>
|
||||||
|
</Accordions>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
import Builder from "@/components/builder";
|
import Builder from "@/components/builder";
|
||||||
|
|
||||||
<Builder />
|
<Builder />
|
||||||
|
|
|
||||||
37
docs/content/docs/changelog/0.3.0.mdx
Normal file
37
docs/content/docs/changelog/0.3.0.mdx
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
---
|
||||||
|
title: Changelog for ckan-devstaller v0.3.0 (2025-10-14)
|
||||||
|
---
|
||||||
|
|
||||||
|
Since v0.2.1 of ckan-devstaller, there have been many new features and changes now available in v0.3.0.
|
||||||
|
|
||||||
|
## New web app: ckan-devstaller.dathere.com
|
||||||
|
|
||||||
|
We've released a new web app [ckan-devstaller.dathere.com](https://ckan-devstaller.dathere.com) as the primary documentation site for ckan-devstaller.
|
||||||
|
|
||||||
|
## Builder page
|
||||||
|
|
||||||
|
There is now an interactive web GUI, the [Builder](/docs/builder), for users to customize their CKAN installation before copying the (now updated) ckan-devstaller command and running it on their terminal. This helps resolve issue [#6](https://github.com/dathere/ckan-devstaller/issues/11).
|
||||||
|
|
||||||
|
## Updated Quick Start page
|
||||||
|
|
||||||
|
The [Quick Start](/docs) page now includes three options for suggested installation methods:
|
||||||
|
|
||||||
|
1. Use the interactive [Builder](/docs/builder).
|
||||||
|
2. Install the "CKAN-only" preset with a script which installs the latest stable version of CKAN and ckan-compose (with optional non-interactive script).
|
||||||
|
3. Install the "datHere default" preset with a script which installs the latest stable version of CKAN and ckan-compose (with optional non-interactive script) along with the DataStore, ckanext-scheming, and DataPusher+ extensions and also installs the `openssh-server` package.
|
||||||
|
|
||||||
|
## Installation architecture page
|
||||||
|
|
||||||
|
There is now an [Installation Architecture](/docs/reference/installation-architecture) page in the Reference section of the web app that provides a visual representation of where `ckan-devstaller` installs relevant files/folders.
|
||||||
|
|
||||||
|
## Uninstall CKAN page
|
||||||
|
|
||||||
|
There is now an [Uninstall CKAN](/docs/tutorials/uninstall-ckan) page in the Tutorials section of the web app that helps users understand how to uninstall their newly installed CKAN installation. This includes the option to either use the new `ckan-devstaller uninstall` subcommand or run the script directly.
|
||||||
|
|
||||||
|
## README update
|
||||||
|
|
||||||
|
The README on the [ckan-devstaller GitHub repository](https://github.com/dathere/ckan-devstaller) has been updated to have a more user-friendly focus for users and developers that may be new to CKAN thanks to the suggestions by [@drw](https://github.com/drw) in issues [#10](https://github.com/dathere/ckan-devstaller/issues/10) and [#11](https://github.com/dathere/ckan-devstaller/issues/11).
|
||||||
|
|
||||||
|
## Changelog section
|
||||||
|
|
||||||
|
We've added a Changelog section to the web app to denote new changes to `ckan-devstaller` for each release.
|
||||||
37
docs/content/docs/changelog/0.3.1.mdx
Normal file
37
docs/content/docs/changelog/0.3.1.mdx
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
---
|
||||||
|
title: Changelog for ckan-devstaller v0.3.1 (2025-10-30)
|
||||||
|
---
|
||||||
|
|
||||||
|
## Updated CKAN default versions to latest stable versions
|
||||||
|
|
||||||
|
We have updated ckan-devstaller to suggest the recent releases of CKAN [2.11.4](https://docs.ckan.org/en/2.11/changelog.html#v-2-11-4-2025-10-29) and [2.10.9](https://docs.ckan.org/en/2.10/changelog.html#v-2-10-9-2025-10-29).
|
||||||
|
|
||||||
|
## Added the "Developing with WSL" page in the Reference section
|
||||||
|
|
||||||
|
Developers using Windows may benefit from the new [Developing with WSL](/docs/reference/developing-with-wsl) page in the Reference section to try their builds of ckan-devstaller and verify things work on a new install of Ubuntu 22.04.
|
||||||
|
|
||||||
|
Alternatively if not trying to reset an entire WSL environment, developers can look into [`ckan-devstaller uninstall`](/docs/tutorials/uninstall-ckan).
|
||||||
|
|
||||||
|
## Added install script switch to Builder page
|
||||||
|
|
||||||
|
There is now a switch on the Builder page that is enabled by default for including the installation script for ckan-devstaller before running it. This is necessary for users that don't have ckan-devstaller installed yet and are using the Builder over the Quick Start scripts.
|
||||||
|
|
||||||
|
## Default start with the Builder page
|
||||||
|
|
||||||
|
We've changed "Get Started" links (and similar links) to the Builder page instead of the Quick Start page to users can quickly access the Builder again and get started using ckan-devstaller.
|
||||||
|
|
||||||
|
## Update ckan-compose links to use ckan-devstaller branch
|
||||||
|
|
||||||
|
We've updated ckan-compose links to use [the ckan-devstaller branch](https://github.com/tino097/ckan-compose/tree/ckan-devstaller).
|
||||||
|
|
||||||
|
## Update VirtualBox notice with better formatting
|
||||||
|
|
||||||
|
To ensure users using VirtualBox see the full command for adding a user to the sudoers file, we've improved the formatting of the note.
|
||||||
|
|
||||||
|
## GitHub Action to verify CKAN install runs
|
||||||
|
|
||||||
|
We've added a GitHub Action to run on push to the main branch to verify that a CKAN-only install runs. This doesn't include verbose testing but rather ensuring that the ckan-devstaller finishes without errors.
|
||||||
|
|
||||||
|
## New --skip-run flag
|
||||||
|
|
||||||
|
We've added a `--skip-run` flag to skip running CKAN at the end of installation.
|
||||||
|
|
@ -4,22 +4,29 @@ description: Get started with ckan-devstaller and install CKAN within minutes.
|
||||||
icon: Zap
|
icon: Zap
|
||||||
---
|
---
|
||||||
|
|
||||||
ckan-devstaller attempts to install a CKAN instance from source along with [ckan-compose](https://github.com/tino097/ckan-compose) and other optional features, intended for development use in a new Ubuntu 22.04 instance.
|
ckan-devstaller attempts to install a CKAN instance from source along with [ckan-compose](https://github.com/tino097/ckan-compose/tree/ckan-devstaller) and other optional features, intended for development use in a new Ubuntu 22.04 instance.
|
||||||
|
|
||||||
<Callout title="Please run ckan-devstaller in a new Ubuntu 22.04 instance only" type="error">Make sure `ckan-devstaller` is run in a **new** Ubuntu 22.04 instance. Do NOT run `ckan-devstaller` in an existing instance that is important for your usage.</Callout>
|
<Callout title="Please run ckan-devstaller in a new Ubuntu 22.04 instance only" type="error">Make sure `ckan-devstaller` is run in a **new** Ubuntu 22.04 instance. Do NOT run `ckan-devstaller` in an existing instance that is important for your usage.</Callout>
|
||||||
|
|
||||||
import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';
|
import { Accordion, Accordions } from 'fumadocs-ui/components/accordion';
|
||||||
|
|
||||||
<Accordions type="single">
|
<Accordions type="single">
|
||||||
<Accordion title="Note for VirtualBox users">If you are using Ubuntu 22.04 on VirtualBox, you may need to add your user to the sudoers file before running the ckan-devstaller install script. Open a terminal in your virtual machine (VM), run `su -` and log in as the root user with the password you used to set up the VM, then type `sudo adduser <username> sudo` where `<username>` is your username then restart your VM and run the ckan-devstaller installer script.</Accordion>
|
<Accordion title="Note for VirtualBox users">If you are using Ubuntu 22.04 on VirtualBox, you may need to add your user to the sudoers file before running the ckan-devstaller install script. Open a terminal in your virtual machine (VM), run `su -` and log in as the root user with the password you used to set up the VM, then type: <br /><br />`sudo adduser <username> sudo`<br /><br /> where `<username>` is your username then restart your VM and run the ckan-devstaller installer script.</Accordion>
|
||||||
<Accordion title="Note for ARM64 users">Currently `ckan-devstaller` supports `x86_64` architecture. `ARM64` support is planned.</Accordion>
|
<Accordion title="Note for ARM64 users">Currently `ckan-devstaller` supports `x86_64` architecture. `ARM64` support is planned.</Accordion>
|
||||||
</Accordions>
|
</Accordions>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
You have several options to choose from for installation. Here are a few:
|
## Install CKAN using ckan-devstaller
|
||||||
|
|
||||||
## [1/3] Customize your CKAN installation with the Builder (Recommended)
|
You have several options to choose from for installation. Here are a few you may choose one from:
|
||||||
|
|
||||||
|
import { Step, Steps } from 'fumadocs-ui/components/steps';
|
||||||
|
|
||||||
|
<Steps>
|
||||||
|
<Step>
|
||||||
|
|
||||||
|
### Customize your CKAN installation with the Builder (Recommended)
|
||||||
|
|
||||||
<Card
|
<Card
|
||||||
icon={<BlocksIcon />}
|
icon={<BlocksIcon />}
|
||||||
|
|
@ -29,25 +36,33 @@ You have several options to choose from for installation. Here are a few:
|
||||||
Click here to customize your CKAN installation with an interactive web GUI
|
Click here to customize your CKAN installation with an interactive web GUI
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
## [2/3] Install the "CKAN-only" preset
|
</Step>
|
||||||
|
|
||||||
By running the following script, ckan-devstaller will be downloaded and the default configuration for installing CKAN 2.11.3 with ckan-compose will be selected. You can then customize your configuration interactively in your terminal after running this script.
|
<Step>
|
||||||
|
|
||||||
|
### Install the "CKAN-only" preset
|
||||||
|
|
||||||
|
By running the following script, ckan-devstaller will be downloaded and the default configuration for installing CKAN with ckan-compose will be selected. You can then customize your configuration interactively in your terminal after running this script.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget -O - https://github.com/dathere/ckan-devstaller/releases/download/0.3.0/install.bash | bash
|
wget -O - https://github.com/dathere/ckan-devstaller/releases/download/0.3.1/install.bash | bash
|
||||||
```
|
```
|
||||||
|
|
||||||
If you'd rather skip the interactivity and go straight to installation, then run the following script instead:
|
If you'd rather skip the interactivity and go straight to installation, then run the following script instead:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget -O - https://github.com/dathere/ckan-devstaller/releases/download/0.3.0/install.bash | bash -s skip-interactive
|
wget -O - https://github.com/dathere/ckan-devstaller/releases/download/0.3.1/install.bash | bash -s skip-interactive
|
||||||
```
|
```
|
||||||
|
|
||||||
## [3/3] Install the "datHere Default" preset
|
</Step>
|
||||||
|
|
||||||
|
<Step>
|
||||||
|
|
||||||
|
### Install the "datHere Default" preset
|
||||||
|
|
||||||
The following script will download ckan-devstaller and select the following configuration:
|
The following script will download ckan-devstaller and select the following configuration:
|
||||||
|
|
||||||
- CKAN 2.11.3
|
- CKAN latest stable version
|
||||||
- [ckan-compose](https://github.com/tino097/ckan-compose/tree/ckan-devstaller)
|
- [ckan-compose](https://github.com/tino097/ckan-compose/tree/ckan-devstaller)
|
||||||
- [DataStore extension](https://docs.ckan.org/en/2.11/maintaining/datastore.html)
|
- [DataStore extension](https://docs.ckan.org/en/2.11/maintaining/datastore.html)
|
||||||
- [ckanext-scheming extension](https://github.com/ckan/ckanext-scheming)
|
- [ckanext-scheming extension](https://github.com/ckan/ckanext-scheming)
|
||||||
|
|
@ -58,15 +73,18 @@ The following script will download ckan-devstaller and select the following conf
|
||||||
You can then customize your configuration interactively in your terminal after running this script.
|
You can then customize your configuration interactively in your terminal after running this script.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget -O - https://github.com/dathere/ckan-devstaller/releases/download/0.3.0/install.bash | bash -s dathere-default
|
wget -O - https://github.com/dathere/ckan-devstaller/releases/download/0.3.1/install.bash | bash -s dathere-default
|
||||||
```
|
```
|
||||||
|
|
||||||
If you'd rather skip the interactivity and go straight to installation, then run the following script instead:
|
If you'd rather skip the interactivity and go straight to installation, then run the following script instead:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
wget -O - https://github.com/dathere/ckan-devstaller/releases/download/0.3.0/install.bash | bash -s dathere-default skip-interactive
|
wget -O - https://github.com/dathere/ckan-devstaller/releases/download/0.3.1/install.bash | bash -s dathere-default skip-interactive
|
||||||
```
|
```
|
||||||
|
|
||||||
|
</Step>
|
||||||
|
</Steps>
|
||||||
|
|
||||||
## Learn more
|
## Learn more
|
||||||
|
|
||||||
import { BlocksIcon, HomeIcon, GitMergeIcon, Trash2Icon } from 'lucide-react';
|
import { BlocksIcon, HomeIcon, GitMergeIcon, Trash2Icon } from 'lucide-react';
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@
|
||||||
"builder",
|
"builder",
|
||||||
"---Further reading---",
|
"---Further reading---",
|
||||||
"tutorials",
|
"tutorials",
|
||||||
"reference"
|
"reference",
|
||||||
|
"changelog",
|
||||||
|
"--- ---",
|
||||||
|
"[Privacy Policy](https://dathere.com/privacy-policy/)"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
131
docs/content/docs/reference/developing-with-wsl.mdx
Normal file
131
docs/content/docs/reference/developing-with-wsl.mdx
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
---
|
||||||
|
title: Developing with WSL
|
||||||
|
description: Tips on how to develop ckan-devstaller on a Windows machine by leveraging Windows Subsystem for Linux.
|
||||||
|
---
|
||||||
|
|
||||||
|
When developing ckan-devstaller on Windows, using Windows Subsystem for Linux (WSL) can be advantageous to demo an Ubuntu 22.04 environment without having to set up a virtual machine.
|
||||||
|
|
||||||
|
import { Step, Steps } from 'fumadocs-ui/components/steps';
|
||||||
|
import { File, Folder, Files } from 'fumadocs-ui/components/files';
|
||||||
|
|
||||||
|
<Steps>
|
||||||
|
<Step>
|
||||||
|
|
||||||
|
### Install the Ubuntu-22.04 distribution
|
||||||
|
|
||||||
|
You'll need to have the Ubuntu-22.04 distribution installed by running the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wsl --install Ubuntu-22.04 --version 2
|
||||||
|
```
|
||||||
|
|
||||||
|
</Step>
|
||||||
|
|
||||||
|
<Step>
|
||||||
|
|
||||||
|
### Export a base image
|
||||||
|
|
||||||
|
</Step>
|
||||||
|
|
||||||
|
Here's the expected set up where we create a WSL folder:
|
||||||
|
|
||||||
|
```files
|
||||||
|
/c/Users/rzmk/WSL
|
||||||
|
├── images
|
||||||
|
| ├── ubuntu-22-04-snapshot.tar
|
||||||
|
├── instances
|
||||||
|
| ├── cdr.vdhx
|
||||||
|
```
|
||||||
|
|
||||||
|
First we'll generate the `images/ubuntu-22-04-snapshot.tar` file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wsl --export Ubuntu-22.04 ./images/ubuntu-22-04-snapshot.tar
|
||||||
|
```
|
||||||
|
|
||||||
|
<Step>
|
||||||
|
|
||||||
|
### Generate a VDHX file for our new instance
|
||||||
|
|
||||||
|
Next we'll generate the `instances/cdr.vdhx` file, so we can run the following:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wsl --import cdr ./instances ./images/ubuntu-22-04-snapshot.tar
|
||||||
|
```
|
||||||
|
|
||||||
|
</Step>
|
||||||
|
|
||||||
|
<Step>
|
||||||
|
|
||||||
|
### Access your new instance as root
|
||||||
|
|
||||||
|
Now try to access your new Ubuntu 22.04 instance `cdr` as the `root` user by running:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wsl -d cdr
|
||||||
|
```
|
||||||
|
|
||||||
|
</Step>
|
||||||
|
|
||||||
|
<Step>
|
||||||
|
|
||||||
|
### Set yourself as the admin user on the instance and log in as the admin user
|
||||||
|
|
||||||
|
Once logged in as `root`, you'll want to edit the `/etc/wsl.conf` file and modify it so you can login as an admin user instead of `root`. We can use the `nano` editor to modify the file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nano /etc/wsl.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Modify the file by adding a `[user]` section with the value `default=rzmk` (where `rzmk` is your username). The file should look similar to this:
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[boot]
|
||||||
|
systemd=true
|
||||||
|
|
||||||
|
[user]
|
||||||
|
default=rzmk
|
||||||
|
```
|
||||||
|
|
||||||
|
Now leave your instance:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
exit
|
||||||
|
```
|
||||||
|
|
||||||
|
Then terminate the instance:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wsl --terminate cdr
|
||||||
|
```
|
||||||
|
|
||||||
|
Run the instance again and you should be logged in as your admin user by default now:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wsl -d cdr
|
||||||
|
```
|
||||||
|
|
||||||
|
</Step>
|
||||||
|
|
||||||
|
<Step>
|
||||||
|
|
||||||
|
### Install ckan-devstaller
|
||||||
|
|
||||||
|
Great, now you can go to the home directory and run one of the [quick start](/docs) scripts:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ~/
|
||||||
|
```
|
||||||
|
|
||||||
|
</Step>
|
||||||
|
</Steps>
|
||||||
|
|
||||||
|
## Removing your instance
|
||||||
|
|
||||||
|
When you want to remove your instance (e.g. so that you can start a brand new instance) then run the following to unregister it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wsl --unregister cdr
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can follow the steps again from step 3 to generate and try out a new instance.
|
||||||
|
|
@ -27,7 +27,7 @@ The configuration file for CKAN is installed at `/etc/ckan/default/ckan.ini`:
|
||||||
|
|
||||||
## ckan-compose
|
## ckan-compose
|
||||||
|
|
||||||
We install certain first-time install files and `ckan-compose` as a directory in the user's home (`~`) directory. For example for the user `adam`:
|
We install certain first-time install files and [`ckan-compose`](https://github.com/tino097/ckan-compose/tree/ckan-devstaller) as a directory in the user's home (`~`) directory. For example for the user `adam`:
|
||||||
|
|
||||||
```files
|
```files
|
||||||
/home/adam
|
/home/adam
|
||||||
|
|
|
||||||
6
docs/content/docs/reference/meta.json
Normal file
6
docs/content/docs/reference/meta.json
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"pages": [
|
||||||
|
"installation-architecture",
|
||||||
|
"developing-with-wsl"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -13,6 +13,8 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@radix-ui/react-accordion": "^1.2.12",
|
"@radix-ui/react-accordion": "^1.2.12",
|
||||||
"@radix-ui/react-collapsible": "^1.1.12",
|
"@radix-ui/react-collapsible": "^1.1.12",
|
||||||
|
"@radix-ui/react-label": "^2.1.7",
|
||||||
|
"@radix-ui/react-switch": "^1.2.6",
|
||||||
"@radix-ui/react-tabs": "^1.1.13",
|
"@radix-ui/react-tabs": "^1.1.13",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ sudo apt install curl -y
|
||||||
cd ~/
|
cd ~/
|
||||||
|
|
||||||
# Download the ckan-devstaller binary file
|
# Download the ckan-devstaller binary file
|
||||||
curl -LO https://github.com/dathere/ckan-devstaller/releases/download/0.3.0/ckan-devstaller
|
curl -LO https://github.com/dathere/ckan-devstaller/releases/download/0.3.1/ckan-devstaller
|
||||||
|
|
||||||
# Add execute permission to ckan-devstaller binary file
|
# Add execute permission to ckan-devstaller binary file
|
||||||
sudo chmod +x ./ckan-devstaller
|
sudo chmod +x ./ckan-devstaller
|
||||||
|
|
@ -22,9 +22,9 @@ skip_interactive=$2
|
||||||
|
|
||||||
if [ $preset == "dathere-default" ]; then
|
if [ $preset == "dathere-default" ]; then
|
||||||
if [ $skip_interactive == "skip-interactive" ]; then
|
if [ $skip_interactive == "skip-interactive" ]; then
|
||||||
./ckan-devstaller --ckan-version 2.11.3 --extensions ckanext-scheming DataStore DataPusher+ --features enable-ssh --skip-interactive
|
./ckan-devstaller --ckan-version 2.11.4 --extensions ckanext-scheming DataStore DataPusher+ --features enable-ssh --skip-interactive
|
||||||
else
|
else
|
||||||
./ckan-devstaller --ckan-version 2.11.3 --extensions ckanext-scheming DataStore DataPusher+ --features enable-ssh
|
./ckan-devstaller --ckan-version 2.11.4 --extensions ckanext-scheming DataStore DataPusher+ --features enable-ssh
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if [ $preset == "skip-interactive" ]; then
|
if [ $preset == "skip-interactive" ]; then
|
||||||
|
|
|
||||||
221
src/main.rs
221
src/main.rs
|
|
@ -5,7 +5,9 @@ mod styles;
|
||||||
use crate::{
|
use crate::{
|
||||||
questions::{question_ckan_version, question_ssh, question_sysadmin},
|
questions::{question_ckan_version, question_ssh, question_sysadmin},
|
||||||
steps::{
|
steps::{
|
||||||
step_install_ahoy, step_install_and_run_ckan_compose, step_install_curl,
|
step_install_ahoy, step_install_and_run_ckan_compose,
|
||||||
|
step_install_ckanext_scheming_extension, step_install_curl,
|
||||||
|
step_install_datapusher_plus_extension, step_install_datastore_extension,
|
||||||
step_install_docker, step_install_openssh, step_package_updates,
|
step_install_docker, step_install_openssh, step_package_updates,
|
||||||
},
|
},
|
||||||
styles::{important_text, step_text, success_text},
|
styles::{important_text, step_text, success_text},
|
||||||
|
|
@ -14,7 +16,6 @@ use anyhow::Result;
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use human_panic::{metadata, setup_panic};
|
use human_panic::{metadata, setup_panic};
|
||||||
use inquire::Confirm;
|
use inquire::Confirm;
|
||||||
use serde_json::json;
|
|
||||||
use std::{path::PathBuf, str::FromStr};
|
use std::{path::PathBuf, str::FromStr};
|
||||||
use xshell::cmd;
|
use xshell::cmd;
|
||||||
use xshell_venv::{Shell, VirtualEnv};
|
use xshell_venv::{Shell, VirtualEnv};
|
||||||
|
|
@ -26,6 +27,9 @@ struct Args {
|
||||||
/// Skip interactive steps
|
/// Skip interactive steps
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
skip_interactive: bool,
|
skip_interactive: bool,
|
||||||
|
/// Skip running CKAN at the end of installation
|
||||||
|
#[arg(short, long)]
|
||||||
|
skip_run: bool,
|
||||||
#[arg(short, long)]
|
#[arg(short, long)]
|
||||||
/// CKAN version to install defined by semantic versioning from official releases from https://github.com/ckan/ckan
|
/// CKAN version to install defined by semantic versioning from official releases from https://github.com/ckan/ckan
|
||||||
ckan_version: Option<String>,
|
ckan_version: Option<String>,
|
||||||
|
|
@ -109,7 +113,7 @@ rm -rf README ckan-compose ahoy dpp_default_config.ini get-docker.sh permissions
|
||||||
ckan_version: if args.ckan_version.is_some() {
|
ckan_version: if args.ckan_version.is_some() {
|
||||||
args.ckan_version.unwrap()
|
args.ckan_version.unwrap()
|
||||||
} else {
|
} else {
|
||||||
"2.11.3".to_string()
|
"2.11.4".to_string()
|
||||||
},
|
},
|
||||||
sysadmin: default_sysadmin.clone(),
|
sysadmin: default_sysadmin.clone(),
|
||||||
extension_datastore: args
|
extension_datastore: args
|
||||||
|
|
@ -133,7 +137,7 @@ rm -rf README ckan-compose ahoy dpp_default_config.ini get-docker.sh permissions
|
||||||
if config.ssh {
|
if config.ssh {
|
||||||
default_config_text.push_str("\n- Install openssh-server to enable SSH access");
|
default_config_text.push_str("\n- Install openssh-server to enable SSH access");
|
||||||
}
|
}
|
||||||
default_config_text.push_str("\n- Install ckan-compose (https://github.com/tino097/ckan-compose) which sets up the CKAN backend (PostgreSQL, SOLR, Redis)");
|
default_config_text.push_str("\n- Install ckan-compose (https://github.com/tino097/ckan-compose/tree/ckan-devstaller) which sets up the CKAN backend (PostgreSQL, SOLR, Redis)");
|
||||||
default_config_text.push_str(format!("\n- Install CKAN v{}", config.ckan_version).as_str());
|
default_config_text.push_str(format!("\n- Install CKAN v{}", config.ckan_version).as_str());
|
||||||
if config.extension_datastore {
|
if config.extension_datastore {
|
||||||
default_config_text.push_str("\n- Install the DataStore extension");
|
default_config_text.push_str("\n- Install the DataStore extension");
|
||||||
|
|
@ -263,207 +267,26 @@ rm -rf README ckan-compose ahoy dpp_default_config.ini get-docker.sh permissions
|
||||||
success_text(format!("6. Installed CKAN {}.", config.ckan_version).as_str())
|
success_text(format!("6. Installed CKAN {}.", config.ckan_version).as_str())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Install extensions
|
||||||
|
if config.extension_datastore {
|
||||||
|
step_install_datastore_extension("7.".to_string(), &sh, username.clone())?;
|
||||||
|
}
|
||||||
|
if config.extension_ckanext_scheming {
|
||||||
|
step_install_ckanext_scheming_extension("8.".to_string(), &sh, username.clone())?;
|
||||||
|
}
|
||||||
if config.extension_datapusher_plus {
|
if config.extension_datapusher_plus {
|
||||||
println!(
|
step_install_datapusher_plus_extension(
|
||||||
"\n{} Enabling DataStore plugin, adding config URLs in /etc/ckan/default/ckan.ini and updating permissions...",
|
"9.".to_string(),
|
||||||
step_text("7."),
|
&sh,
|
||||||
);
|
sysadmin_username,
|
||||||
let mut conf = ini::Ini::load_from_file("/etc/ckan/default/ckan.ini")?;
|
username.clone(),
|
||||||
let app_main_section = conf.section_mut(Some("app:main")).unwrap();
|
|
||||||
let mut ckan_plugins = app_main_section.get("ckan.plugins").unwrap().to_string();
|
|
||||||
ckan_plugins.push_str(" datastore");
|
|
||||||
app_main_section.insert("ckan.plugins", ckan_plugins);
|
|
||||||
app_main_section.insert(
|
|
||||||
"ckan.datastore.write_url",
|
|
||||||
"postgresql://ckan_default:pass@localhost/datastore_default",
|
|
||||||
);
|
|
||||||
app_main_section.insert(
|
|
||||||
"ckan.datastore.read_url",
|
|
||||||
"postgresql://datastore_default:pass@localhost/datastore_default",
|
|
||||||
);
|
|
||||||
app_main_section.insert("ckan.datastore.sqlsearch.enabled", "true");
|
|
||||||
conf.write_to_file("/etc/ckan/default/ckan.ini")?;
|
|
||||||
let postgres_container_id = cmd!(
|
|
||||||
sh,
|
|
||||||
"sudo docker ps -aqf name=^ckan-devstaller-project-postgres$"
|
|
||||||
)
|
|
||||||
.read()?;
|
|
||||||
let set_permissions_output = cmd!(
|
|
||||||
sh,
|
|
||||||
"ckan -c /etc/ckan/default/ckan.ini datastore set-permissions"
|
|
||||||
)
|
|
||||||
.read()?;
|
|
||||||
std::fs::write("permissions.sql", set_permissions_output)?;
|
|
||||||
loop {
|
|
||||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
|
||||||
if std::fs::exists("permissions.sql")? {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sh.change_dir(format!("/home/{username}"));
|
|
||||||
cmd!(
|
|
||||||
sh,
|
|
||||||
"sudo docker cp permissions.sql {postgres_container_id}:/permissions.sql"
|
|
||||||
)
|
|
||||||
.run()?;
|
|
||||||
cmd!(sh, "sudo docker exec {postgres_container_id} psql -U ckan_default --set ON_ERROR_STOP=1 -f permissions.sql").run()?;
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
success_text(
|
|
||||||
"7. Enabled DataStore plugin, set DataStore URLs in /etc/ckan/default/ckan.ini, and updated permissions."
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
step_text("\n{} Installing ckanext-scheming and DataPusher+ extensions..."),
|
|
||||||
);
|
|
||||||
cmd!(
|
|
||||||
sh,
|
|
||||||
"pip install -e git+https://github.com/ckan/ckanext-scheming.git#egg=ckanext-scheming"
|
|
||||||
)
|
|
||||||
.run()?;
|
|
||||||
let mut conf = ini::Ini::load_from_file("/etc/ckan/default/ckan.ini")?;
|
|
||||||
let app_main_section = conf.section_mut(Some("app:main")).unwrap();
|
|
||||||
let mut ckan_plugins = app_main_section.get("ckan.plugins").unwrap().to_string();
|
|
||||||
ckan_plugins.push_str(" scheming_datasets");
|
|
||||||
cmd!(
|
|
||||||
sh,
|
|
||||||
"ckan config-tool /etc/ckan/default/ckan.ini -s app:main ckan.plugins={ckan_plugins}"
|
|
||||||
)
|
|
||||||
.run()?;
|
|
||||||
cmd!(sh, "ckan config-tool /etc/ckan/default/ckan.ini -s app:main scheming.presets=ckanext.scheming:presets.json").run()?;
|
|
||||||
cmd!(sh, "ckan config-tool /etc/ckan/default/ckan.ini -s app:main scheming.dataset_fallback=false").run()?;
|
|
||||||
// app_main_section.insert("ckan.plugins", ckan_plugins);
|
|
||||||
// app_main_section.insert("scheming.presets", "ckanext.scheming:presets.json");
|
|
||||||
// app_main_section.insert("scheming.dataset_fallback", "false");
|
|
||||||
// conf.write_to_file("/etc/ckan/default/ckan.ini")?;
|
|
||||||
// Install DataPusher+
|
|
||||||
cmd!(sh, "sudo apt install python3-virtualenv python3-dev python3-pip python3-wheel build-essential libxslt1-dev libxml2-dev zlib1g-dev git libffi-dev libpq-dev uchardet -y").run()?;
|
|
||||||
sh.change_dir("/usr/lib/ckan/default/src");
|
|
||||||
cmd!(sh, "pip install -e git+https://github.com/dathere/datapusher-plus.git@main#egg=datapusher-plus").run()?;
|
|
||||||
sh.change_dir("/usr/lib/ckan/default/src/datapusher-plus");
|
|
||||||
cmd!(sh, "pip install -r requirements.txt").run()?;
|
|
||||||
sh.change_dir(format!("/home/{username}"));
|
|
||||||
cmd!(sh, "wget https://github.com/dathere/qsv/releases/download/4.0.0/qsv-4.0.0-x86_64-unknown-linux-gnu.zip").run()?;
|
|
||||||
cmd!(sh, "sudo apt install unzip -y").run()?;
|
|
||||||
cmd!(sh, "unzip qsv-4.0.0-x86_64-unknown-linux-gnu.zip").run()?;
|
|
||||||
cmd!(sh, "sudo rm -rf qsv-4.0.0-x86_64-unknown-linux-gnu.zip").run()?;
|
|
||||||
cmd!(sh, "sudo mv ./qsvdp_glibc-2.31 /usr/local/bin/qsvdp").run()?;
|
|
||||||
let mut conf = ini::Ini::load_from_file("/etc/ckan/default/ckan.ini")?;
|
|
||||||
let app_main_section = conf.section_mut(Some("app:main")).unwrap();
|
|
||||||
let mut ckan_plugins = app_main_section.get("ckan.plugins").unwrap().to_string();
|
|
||||||
ckan_plugins.push_str(" datapusher_plus");
|
|
||||||
cmd!(
|
|
||||||
sh,
|
|
||||||
"ckan config-tool /etc/ckan/default/ckan.ini -s app:main ckan.plugins={ckan_plugins}"
|
|
||||||
)
|
|
||||||
.run()?;
|
|
||||||
cmd!(sh, "ckan config-tool /etc/ckan/default/ckan.ini -s app:main scheming.dataset_schemas=ckanext.datapusher_plus:dataset-druf.yaml").run()?;
|
|
||||||
// app_main_section.insert("ckan.plugins", ckan_plugins);
|
|
||||||
// app_main_section.insert(
|
|
||||||
// "scheming.dataset_schemas",
|
|
||||||
// "ckanext.datapusher_plus:dataset-druf.yaml",
|
|
||||||
// );
|
|
||||||
// conf.write_to_file("/etc/ckan/default/ckan.ini")?;
|
|
||||||
let dpp_default_config = r#"
|
|
||||||
ckanext.datapusher_plus.use_proxy = false
|
|
||||||
ckanext.datapusher_plus.download_proxy =
|
|
||||||
ckanext.datapusher_plus.ssl_verify = false
|
|
||||||
# supports INFO, DEBUG, TRACE - use DEBUG or TRACE when debugging scheming Formulas
|
|
||||||
ckanext.datapusher_plus.upload_log_level = INFO
|
|
||||||
ckanext.datapusher_plus.formats = csv tsv tab ssv xls xlsx xlsxb xlsm ods geojson shp qgis zip
|
|
||||||
ckanext.datapusher_plus.pii_screening = false
|
|
||||||
ckanext.datapusher_plus.pii_found_abort = false
|
|
||||||
ckanext.datapusher_plus.pii_regex_resource_id_or_alias =
|
|
||||||
ckanext.datapusher_plus.pii_show_candidates = false
|
|
||||||
ckanext.datapusher_plus.pii_quick_screen = false
|
|
||||||
ckanext.datapusher_plus.qsv_bin = /usr/local/bin/qsvdp
|
|
||||||
ckanext.datapusher_plus.preview_rows = 100
|
|
||||||
ckanext.datapusher_plus.download_timeout = 300
|
|
||||||
ckanext.datapusher_plus.max_content_length = 1256000000000
|
|
||||||
ckanext.datapusher_plus.chunk_size = 16384
|
|
||||||
ckanext.datapusher_plus.default_excel_sheet = 0
|
|
||||||
ckanext.datapusher_plus.sort_and_dupe_check = true
|
|
||||||
ckanext.datapusher_plus.dedup = false
|
|
||||||
ckanext.datapusher_plus.unsafe_prefix = unsafe_
|
|
||||||
ckanext.datapusher_plus.reserved_colnames = _id
|
|
||||||
ckanext.datapusher_plus.prefer_dmy = false
|
|
||||||
ckanext.datapusher_plus.ignore_file_hash = true
|
|
||||||
ckanext.datapusher_plus.auto_index_threshold = 3
|
|
||||||
ckanext.datapusher_plus.auto_index_dates = true
|
|
||||||
ckanext.datapusher_plus.auto_unique_index = true
|
|
||||||
ckanext.datapusher_plus.summary_stats_options =
|
|
||||||
ckanext.datapusher_plus.add_summary_stats_resource = false
|
|
||||||
ckanext.datapusher_plus.summary_stats_with_preview = false
|
|
||||||
ckanext.datapusher_plus.qsv_stats_string_max_length = 32767
|
|
||||||
ckanext.datapusher_plus.qsv_dates_whitelist = date,time,due,open,close,created
|
|
||||||
ckanext.datapusher_plus.qsv_freq_limit = 10
|
|
||||||
ckanext.datapusher_plus.auto_alias = true
|
|
||||||
ckanext.datapusher_plus.auto_alias_unique = false
|
|
||||||
ckanext.datapusher_plus.copy_readbuffer_size = 1048576
|
|
||||||
ckanext.datapusher_plus.type_mapping = {"String": "text", "Integer": "numeric","Float": "numeric","DateTime": "timestamp","Date": "date","NULL": "text"}
|
|
||||||
ckanext.datapusher_plus.auto_spatial_simplication = true
|
|
||||||
ckanext.datapusher_plus.spatial_simplication_relative_tolerance = 0.1
|
|
||||||
ckanext.datapusher_plus.latitude_fields = latitude,lat
|
|
||||||
ckanext.datapusher_plus.longitude_fields = longitude,long,lon
|
|
||||||
ckanext.datapusher_plus.jinja2_bytecode_cache_dir = /tmp/jinja2_butecode_cache
|
|
||||||
ckanext.datapusher_plus.auto_unzip_one_file = true
|
|
||||||
ckanext.datapusher_plus.api_token = <CKAN service account token for CKAN user with sysadmin privileges>
|
|
||||||
ckanext.datapusher_plus.describeGPT_api_key = <Token for OpenAI API compatible service>
|
|
||||||
ckanext.datapusher_plus.file_bin = /usr/bin/file
|
|
||||||
ckanext.datapusher_plus.enable_druf = false
|
|
||||||
ckanext.datapusher_plus.enable_form_redirect = true
|
|
||||||
"#;
|
|
||||||
std::fs::write("dpp_default_config.ini", dpp_default_config)?;
|
|
||||||
cmd!(
|
|
||||||
sh,
|
|
||||||
"ckan config-tool /etc/ckan/default/ckan.ini -f dpp_default_config.ini"
|
|
||||||
)
|
|
||||||
.run()?;
|
|
||||||
let resource_formats_str = std::fs::read_to_string(
|
|
||||||
"/usr/lib/ckan/default/src/ckan/config/resource_formats.json",
|
|
||||||
)?;
|
)?;
|
||||||
let mut resource_formats_val: serde_json::Value =
|
|
||||||
serde_json::from_str(&resource_formats_str)?;
|
|
||||||
let all_resource_formats = resource_formats_val
|
|
||||||
.get_mut(0)
|
|
||||||
.unwrap()
|
|
||||||
.as_array_mut()
|
|
||||||
.unwrap();
|
|
||||||
all_resource_formats.push(json!([
|
|
||||||
"TAB",
|
|
||||||
"Tab Separated Values File",
|
|
||||||
"text/tab-separated-values",
|
|
||||||
[]
|
|
||||||
]));
|
|
||||||
std::fs::write(
|
|
||||||
"/usr/lib/ckan/default/src/ckan/config/resource_formats.json",
|
|
||||||
serde_json::to_string(&resource_formats_val)?,
|
|
||||||
)?;
|
|
||||||
cmd!(sh, "sudo locale-gen en_US.UTF-8").run()?;
|
|
||||||
cmd!(sh, "sudo update-locale").run()?;
|
|
||||||
let token_command_output = cmd!(
|
|
||||||
sh,
|
|
||||||
"ckan -c /etc/ckan/default/ckan.ini user token add {sysadmin_username} dpplus"
|
|
||||||
)
|
|
||||||
.read()?;
|
|
||||||
let tail_output = cmd!(sh, "tail -n 1").stdin(token_command_output).read()?;
|
|
||||||
let dpp_api_token = cmd!(sh, "tr -d '\t'").stdin(tail_output).read()?;
|
|
||||||
cmd!(sh, "ckan config-tool /etc/ckan/default/ckan.ini ckanext.datapusher_plus.api_token={dpp_api_token}").env("LC_ALL", "en_US.UTF-8").run()?;
|
|
||||||
cmd!(
|
|
||||||
sh,
|
|
||||||
"ckan -c /etc/ckan/default/ckan.ini db upgrade -p datapusher_plus"
|
|
||||||
)
|
|
||||||
.run()?;
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
success_text("8. Installed ckanext-scheming and DataPusher+ extensions.")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !args.skip_run {
|
||||||
println!("\n{}", success_text("Running CKAN instance..."));
|
println!("\n{}", success_text("Running CKAN instance..."));
|
||||||
cmd!(sh, "ckan -c /etc/ckan/default/ckan.ini run").run()?;
|
cmd!(sh, "ckan -c /etc/ckan/default/ckan.ini run").run()?;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
println!("Cancelling installation.");
|
println!("Cancelling installation.");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ pub fn question_ssh() -> Result<bool> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn question_ckan_version() -> Result<String> {
|
pub fn question_ckan_version() -> Result<String> {
|
||||||
let ckan_version_options: Vec<&str> = vec!["2.11.3", "2.10.8", "Other"];
|
let ckan_version_options: Vec<&str> = vec!["2.11.4", "2.10.9", "Other"];
|
||||||
let answer_ckan_version = Select::new(
|
let answer_ckan_version = Select::new(
|
||||||
"What CKAN version would you like to install? (optional)",
|
"What CKAN version would you like to install? (optional)",
|
||||||
ckan_version_options,
|
ckan_version_options,
|
||||||
|
|
@ -26,7 +26,7 @@ pub fn question_ckan_version() -> Result<String> {
|
||||||
if answer_ckan_version == "Other" {
|
if answer_ckan_version == "Other" {
|
||||||
Ok(
|
Ok(
|
||||||
Text::new("What CKAN version would you like to install? (optional)")
|
Text::new("What CKAN version would you like to install? (optional)")
|
||||||
.with_default("2.11.3")
|
.with_default("2.11.4")
|
||||||
.prompt()?,
|
.prompt()?,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
252
src/steps.rs
252
src/steps.rs
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::styles::{highlighted_text, important_text, step_text, success_text};
|
use crate::styles::{highlighted_text, important_text, step_text, success_text};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
use serde_json::json;
|
||||||
use xshell::{Shell, cmd};
|
use xshell::{Shell, cmd};
|
||||||
|
|
||||||
pub fn step_intro() {
|
pub fn step_intro() {
|
||||||
|
|
@ -10,7 +11,7 @@ pub fn step_intro() {
|
||||||
);
|
);
|
||||||
println!(
|
println!(
|
||||||
"This installer should assist in setting up {} from a source installation along with ckan-compose. If you have any issues, please report them at https://support.dathere.com or https://github.com/dathere/ckan-devstaller/issues.",
|
"This installer should assist in setting up {} from a source installation along with ckan-compose. If you have any issues, please report them at https://support.dathere.com or https://github.com/dathere/ckan-devstaller/issues.",
|
||||||
highlighted_text("CKAN 2.11.3")
|
highlighted_text("CKAN 2.11.4")
|
||||||
);
|
);
|
||||||
println!(
|
println!(
|
||||||
"\nYou may also learn more about ckan-devstaller at https://ckan-devstaller.dathere.com."
|
"\nYou may also learn more about ckan-devstaller at https://ckan-devstaller.dathere.com."
|
||||||
|
|
@ -135,3 +136,252 @@ POSTGRES_PASSWORD=pass";
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn step_install_datastore_extension(
|
||||||
|
step_prefix: String,
|
||||||
|
sh: &Shell,
|
||||||
|
username: String,
|
||||||
|
) -> Result<()> {
|
||||||
|
println!(
|
||||||
|
"\n{} Enabling DataStore plugin, adding config URLs in /etc/ckan/default/ckan.ini and updating permissions...",
|
||||||
|
step_text(step_prefix.as_str()),
|
||||||
|
);
|
||||||
|
let mut conf = ini::Ini::load_from_file("/etc/ckan/default/ckan.ini")?;
|
||||||
|
let app_main_section = conf.section_mut(Some("app:main")).unwrap();
|
||||||
|
let mut ckan_plugins = app_main_section.get("ckan.plugins").unwrap().to_string();
|
||||||
|
ckan_plugins.push_str(" datastore");
|
||||||
|
app_main_section.insert("ckan.plugins", ckan_plugins);
|
||||||
|
app_main_section.insert(
|
||||||
|
"ckan.datastore.write_url",
|
||||||
|
"postgresql://ckan_default:pass@localhost/datastore_default",
|
||||||
|
);
|
||||||
|
app_main_section.insert(
|
||||||
|
"ckan.datastore.read_url",
|
||||||
|
"postgresql://datastore_default:pass@localhost/datastore_default",
|
||||||
|
);
|
||||||
|
app_main_section.insert("ckan.datastore.sqlsearch.enabled", "true");
|
||||||
|
conf.write_to_file("/etc/ckan/default/ckan.ini")?;
|
||||||
|
let postgres_container_id = cmd!(
|
||||||
|
sh,
|
||||||
|
"sudo docker ps -aqf name=^ckan-devstaller-project-postgres$"
|
||||||
|
)
|
||||||
|
.read()?;
|
||||||
|
let set_permissions_output = cmd!(
|
||||||
|
sh,
|
||||||
|
"ckan -c /etc/ckan/default/ckan.ini datastore set-permissions"
|
||||||
|
)
|
||||||
|
.read()?;
|
||||||
|
std::fs::write("permissions.sql", set_permissions_output)?;
|
||||||
|
loop {
|
||||||
|
std::thread::sleep(std::time::Duration::from_secs(2));
|
||||||
|
if std::fs::exists("permissions.sql")? {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sh.change_dir(format!("/home/{username}"));
|
||||||
|
cmd!(
|
||||||
|
sh,
|
||||||
|
"sudo docker cp permissions.sql {postgres_container_id}:/permissions.sql"
|
||||||
|
)
|
||||||
|
.run()?;
|
||||||
|
cmd!(sh, "sudo docker exec {postgres_container_id} psql -U ckan_default --set ON_ERROR_STOP=1 -f permissions.sql").run()?;
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
success_text(
|
||||||
|
format!("{step_prefix} Enabled DataStore plugin, set DataStore URLs in /etc/ckan/default/ckan.ini, and updated permissions.").as_str()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn step_install_ckanext_scheming_extension(
|
||||||
|
step_prefix: String,
|
||||||
|
sh: &Shell,
|
||||||
|
username: String,
|
||||||
|
) -> Result<()> {
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
step_text("\n{} Installing the ckanext-scheming extension..."),
|
||||||
|
);
|
||||||
|
cmd!(
|
||||||
|
sh,
|
||||||
|
"pip install -e git+https://github.com/ckan/ckanext-scheming.git#egg=ckanext-scheming"
|
||||||
|
)
|
||||||
|
.run()?;
|
||||||
|
let mut conf = ini::Ini::load_from_file("/etc/ckan/default/ckan.ini")?;
|
||||||
|
let app_main_section = conf.section_mut(Some("app:main")).unwrap();
|
||||||
|
let mut ckan_plugins = app_main_section.get("ckan.plugins").unwrap().to_string();
|
||||||
|
ckan_plugins.push_str(" scheming_datasets");
|
||||||
|
cmd!(
|
||||||
|
sh,
|
||||||
|
"ckan config-tool /etc/ckan/default/ckan.ini -s app:main ckan.plugins={ckan_plugins}"
|
||||||
|
)
|
||||||
|
.run()?;
|
||||||
|
cmd!(sh, "ckan config-tool /etc/ckan/default/ckan.ini -s app:main scheming.presets=ckanext.scheming:presets.json").run()?;
|
||||||
|
cmd!(
|
||||||
|
sh,
|
||||||
|
"ckan config-tool /etc/ckan/default/ckan.ini -s app:main scheming.dataset_fallback=false"
|
||||||
|
)
|
||||||
|
.run()?;
|
||||||
|
// app_main_section.insert("ckan.plugins", ckan_plugins);
|
||||||
|
// app_main_section.insert("scheming.presets", "ckanext.scheming:presets.json");
|
||||||
|
// app_main_section.insert("scheming.dataset_fallback", "false");
|
||||||
|
// conf.write_to_file("/etc/ckan/default/ckan.ini")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn step_install_datapusher_plus_extension(
|
||||||
|
step_prefix: String,
|
||||||
|
sh: &Shell,
|
||||||
|
sysadmin_username: String,
|
||||||
|
username: String,
|
||||||
|
) -> Result<()> {
|
||||||
|
// Install DataPusher+
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
step_text(format!("\n{step_prefix} Installing DataPusher+ extension...").as_str())
|
||||||
|
);
|
||||||
|
cmd!(sh, "sudo apt install python3-virtualenv python3-dev python3-pip python3-wheel build-essential libxslt1-dev libxml2-dev zlib1g-dev git libffi-dev libpq-dev uchardet -y").run()?;
|
||||||
|
sh.change_dir("/usr/lib/ckan/default/src");
|
||||||
|
cmd!(
|
||||||
|
sh,
|
||||||
|
"pip install -e git+https://github.com/dathere/datapusher-plus.git@main#egg=datapusher-plus"
|
||||||
|
)
|
||||||
|
.run()?;
|
||||||
|
sh.change_dir("/usr/lib/ckan/default/src/datapusher-plus");
|
||||||
|
cmd!(sh, "pip install -r requirements.txt").run()?;
|
||||||
|
sh.change_dir(format!("/home/{username}"));
|
||||||
|
cmd!(sh, "wget https://github.com/dathere/qsv/releases/download/4.0.0/qsv-4.0.0-x86_64-unknown-linux-gnu.zip").run()?;
|
||||||
|
cmd!(sh, "sudo apt install unzip -y").run()?;
|
||||||
|
cmd!(sh, "unzip qsv-4.0.0-x86_64-unknown-linux-gnu.zip").run()?;
|
||||||
|
cmd!(sh, "sudo rm -rf qsv-4.0.0-x86_64-unknown-linux-gnu.zip").run()?;
|
||||||
|
cmd!(sh, "sudo mv ./qsvdp_glibc-2.31 /usr/local/bin/qsvdp").run()?;
|
||||||
|
let mut conf = ini::Ini::load_from_file("/etc/ckan/default/ckan.ini")?;
|
||||||
|
let app_main_section = conf.section_mut(Some("app:main")).unwrap();
|
||||||
|
let mut ckan_plugins = app_main_section.get("ckan.plugins").unwrap().to_string();
|
||||||
|
ckan_plugins.push_str(" datapusher_plus");
|
||||||
|
app_main_section.insert("ckan.plugins", ckan_plugins);
|
||||||
|
app_main_section.insert(
|
||||||
|
"scheming.dataset_schemas",
|
||||||
|
"ckanext.datapusher_plus:dataset-druf.yaml",
|
||||||
|
);
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.use_proxy", "false");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.download_proxy", "");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.ssl_verify", "false");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.upload_log_level", "INFO");
|
||||||
|
app_main_section.insert(
|
||||||
|
"ckanext.datapusher_plus.formats",
|
||||||
|
"csv tsv tab ssv xls xlsx xlsxb xlsm ods geojson shp qgis zip",
|
||||||
|
);
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.pii_screening", "false");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.pii_found_abort", "false");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.pii_regex_resource_id_or_alias", "");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.pii_show_candidates", "false");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.pii_quick_screen", "false");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.qsv_bin", "/usr/local/bin/qsvdp");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.preview_rows", "100");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.download_timeout", "300");
|
||||||
|
app_main_section.insert(
|
||||||
|
"ckanext.datapusher_plus.max_content_length",
|
||||||
|
"1256000000000",
|
||||||
|
);
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.chunk_size", "16384");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.default_excel_sheet", "0");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.sort_and_dupe_check", "true");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.dedup", "false");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.unsafe_prefix", "unsafe_");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.reserved_colnames", "_id");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.prefer_dmy", "false");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.ignore_file_hash", "true");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.auto_index_threshold", "3");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.auto_index_dates", "true");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.auto_unique_index", "true");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.summary_stats_options", "");
|
||||||
|
app_main_section.insert(
|
||||||
|
"ckanext.datapusher_plus.add_summary_stats_resource",
|
||||||
|
"false",
|
||||||
|
);
|
||||||
|
app_main_section.insert(
|
||||||
|
"ckanext.datapusher_plus.summary_stats_with_preview",
|
||||||
|
"false",
|
||||||
|
);
|
||||||
|
app_main_section.insert(
|
||||||
|
"ckanext.datapusher_plus.qsv_stats_string_max_length",
|
||||||
|
"32767",
|
||||||
|
);
|
||||||
|
app_main_section.insert(
|
||||||
|
"ckanext.datapusher_plus.qsv_dates_whitelist",
|
||||||
|
"date,time,due,open,close,created",
|
||||||
|
);
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.qsv_freq_limit", "10");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.auto_alias", "true");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.auto_alias_unique", "false");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.copy_readbuffer_size", "1048576");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.type_mapping", r#"{"String": "text", "Integer": "numeric","Float": "numeric","DateTime": "timestamp","Date": "date","NULL": "text"}"#);
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.auto_spatial_simplication", "true");
|
||||||
|
app_main_section.insert(
|
||||||
|
"ckanext.datapusher_plus.spatial_simplication_relative_tolerance",
|
||||||
|
"0.1",
|
||||||
|
);
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.latitude_fields", "latitude,lat");
|
||||||
|
app_main_section.insert(
|
||||||
|
"ckanext.datapusher_plus.longitude_fields",
|
||||||
|
"longitude,long,lon",
|
||||||
|
);
|
||||||
|
app_main_section.insert(
|
||||||
|
"ckanext.datapusher_plus.jinja2_bytecode_cache_dir",
|
||||||
|
"/tmp/jinja2_butecode_cache",
|
||||||
|
);
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.auto_unzip_one_file", "true");
|
||||||
|
app_main_section.insert(
|
||||||
|
"ckanext.datapusher_plus.api_token",
|
||||||
|
"<CKAN service account token for CKAN user with sysadmin privileges>",
|
||||||
|
);
|
||||||
|
app_main_section.insert(
|
||||||
|
"ckanext.datapusher_plus.describeGPT_api_key",
|
||||||
|
"<Token for OpenAI API compatible service>",
|
||||||
|
);
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.file_bin", "/usr/bin/file");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.enable_druf", "false");
|
||||||
|
app_main_section.insert("ckanext.datapusher_plus.enable_form_redirect", "true");
|
||||||
|
conf.write_to_file("/etc/ckan/default/ckan.ini")?;
|
||||||
|
let resource_formats_str = std::fs::read_to_string(
|
||||||
|
"/usr/lib/ckan/default/src/ckan/ckan/config/resource_formats.json",
|
||||||
|
)?;
|
||||||
|
let mut resource_formats_val: serde_json::Value = serde_json::from_str(&resource_formats_str)?;
|
||||||
|
let all_resource_formats = resource_formats_val
|
||||||
|
.get_mut(0)
|
||||||
|
.unwrap()
|
||||||
|
.as_array_mut()
|
||||||
|
.unwrap();
|
||||||
|
all_resource_formats.push(json!([
|
||||||
|
"TAB",
|
||||||
|
"Tab Separated Values File",
|
||||||
|
"text/tab-separated-values",
|
||||||
|
[]
|
||||||
|
]));
|
||||||
|
std::fs::write(
|
||||||
|
"/usr/lib/ckan/default/src/ckan/ckan/config/resource_formats.json",
|
||||||
|
serde_json::to_string(&resource_formats_val)?,
|
||||||
|
)?;
|
||||||
|
cmd!(sh, "sudo locale-gen en_US.UTF-8").run()?;
|
||||||
|
cmd!(sh, "sudo update-locale").run()?;
|
||||||
|
let token_command_output = cmd!(
|
||||||
|
sh,
|
||||||
|
"ckan -c /etc/ckan/default/ckan.ini user token add {sysadmin_username} dpplus"
|
||||||
|
)
|
||||||
|
.read()?;
|
||||||
|
let tail_output = cmd!(sh, "tail -n 1").stdin(token_command_output).read()?;
|
||||||
|
let dpp_api_token = cmd!(sh, "tr -d '\t'").stdin(tail_output).read()?;
|
||||||
|
cmd!(sh, "ckan config-tool /etc/ckan/default/ckan.ini ckanext.datapusher_plus.api_token={dpp_api_token}").env("LC_ALL", "en_US.UTF-8").run()?;
|
||||||
|
cmd!(
|
||||||
|
sh,
|
||||||
|
"ckan -c /etc/ckan/default/ckan.ini db upgrade -p datapusher_plus"
|
||||||
|
)
|
||||||
|
.run()?;
|
||||||
|
println!(
|
||||||
|
"{}",
|
||||||
|
success_text(format!("{step_prefix} Installed DataPusher+ extension.").as_str())
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue