Skip to content

Commit

Permalink
Add a dev env in Okteto (#128)
Browse files Browse the repository at this point in the history
* add a dev env
  • Loading branch information
sgalsaleh authored Feb 5, 2024
1 parent ccfdafc commit 7624fbf
Show file tree
Hide file tree
Showing 20 changed files with 424 additions and 24 deletions.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
[![Develop on Okteto](https://okteto.com/develop-okteto.svg)](https://replicated.okteto.dev/deploy?repository=https://github.com/replicatedhq/ttl.sh&branch=main)

# ttl.sh

## An ephemeral container registry for CI workflows.
Expand All @@ -6,3 +8,37 @@

ttl.sh is an anonymous, expiring Docker container registry using the official Docker Registry image. This is a set of tools and configurations that can be used to deploy the registry without authentication, but with self-expiring images.

# Development

Development for the services in this project is done through [Okteto](https://replicated.okteto.dev).

## Setup

1. Install the Okteto CLI (`brew install okteto`)
2. Setup Okteto CLI (`okteto context use https://replicated.okteto.dev`)
3. Setup Okteto context in kubectl (`okteto context update-kubeconfig`)
4. Deploy your current branch. (from the ttl.sh root directory: `okteto pipeline deploy`)

## Debugging

Okteto is utilized for debugging. New build targets have been added to allow building and running each service in debug mode.

1. Replace the default container in your Okteto environment with a development container.
1. From the root directory: `okteto up` or `okteto up <service name>`
2. Run the build targets for the desired service:
1. ttl-hooks: `make deps build hooks`
2. ttl-reaper: `make deps build reap`
3. Stop development and go back to the default container.
1. From the root directory: `okteto down` or `okteto down <service name>`

## Example workflows

### Switching branches or rebasing

1. `git checkout my-new-branch`
2. `okteto pipeline deploy`
3. (make code changes)
4. `okteto up`
5. (test changes, find they don't work, make more changes)...
6. `okteto down`
7. (commit code, and be happy)
2 changes: 0 additions & 2 deletions cloudflare/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { tryParsePutTagRequest, handleTagManifestRequest } from "./tag_manifest";

if (typeof addEventListener === 'function') {
addEventListener('fetch', (e: Event): void => {
// work around as strict typescript check doesn't allow e to be of type FetchEvent
Expand Down
56 changes: 56 additions & 0 deletions hooks/.stignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
.git
# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules
jspm_packages

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# parcel-bundler cache (https://parceljs.org/)
.cache

# next.js build output
.next

# nuxt.js build output
.nuxt

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless

3 changes: 2 additions & 1 deletion hooks/Dockerfile.hooks
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
FROM node:10 as deps

ADD ./package.json /src/package.json
ADD ./Makefile /src/Makefile
ADD . /src
WORKDIR /src
RUN make deps test
RUN make deps test

ENTRYPOINT ["node"]
CMD ["--no-deprecation", "build/server.js", "hooks"]
1 change: 1 addition & 0 deletions hooks/Dockerfile.reap
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
FROM node:10 as deps

ADD ./package.json /src/package.json
ADD ./Makefile /src/Makefile
ADD . /src
Expand Down
8 changes: 4 additions & 4 deletions hooks/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ deps:

.PHONY: lint
lint:
`npm bin`/tslint --project ./tsconfig.json --fix
npx tslint --project ./tsconfig.json --fix

.PHONY: test
test: build
npm test

.PHONY: build
build: prebuild
`npm bin`/tsc
npx tsc

.PHONY: run
run:
.PHONY: hooks
hooks:
node --no-deprecation ./build/server.js hooks

.PHONY: reap
Expand Down
3 changes: 1 addition & 2 deletions hooks/src/commands/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as util from "util";
import { Server } from "../server/server";
import { logger } from "../logger";
import { param } from "../util";

exports.name = "hooks";
exports.describe = "Start and run the hook api server";
Expand All @@ -17,7 +16,7 @@ exports.handler = async (argv) => {
};

async function main(argv): Promise<any> {
process.on('SIGTERM', function onSigterm () {
process.on("SIGTERM", function onSigterm() {
logger.info(`Got SIGTERM, cleaning up`);
process.exit();
});
Expand Down
19 changes: 10 additions & 9 deletions hooks/src/commands/reap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as redis from "redis";
import { promisify } from "util";
import * as rp from "request-promise";

const registryUrl = process.env["REGISTRY_URL"] || "https://ttl.sh";
const client = redis.createClient({url: process.env["REDISCLOUD_URL"]});
const smembersAsync = promisify(client.smembers).bind(client);
const sremAsync = promisify(client.srem).bind(client);
Expand All @@ -25,13 +26,13 @@ exports.handler = async (argv) => {
};

async function main(argv): Promise<any> {
process.on('SIGTERM', function onSigterm () {
process.on("SIGTERM", function onSigterm() {
logger.info(`Got SIGTERM, cleaning up`);
process.exit();
});

let jobRunning: boolean = false;

const job = new CronJob({
cronTime: "* * * * *",
onTick: async () => {
Expand All @@ -45,7 +46,7 @@ async function main(argv): Promise<any> {

try {
await reapExpiredImages();
} catch(err) {
} catch (err) {
console.log("failed to reap expired images:", err);
} finally {
jobRunning = false;
Expand Down Expand Up @@ -73,17 +74,17 @@ async function reapExpiredImages() {

const imageAndTag = image.split(":");
const headers = {
"Accept": "application/vnd.docker.distribution.manifest.v2+json",
Accept: "application/vnd.docker.distribution.manifest.v2+json",
};

// Get the manifest from the tag
const getOptions = {
method: "HEAD",
uri: `https://ttl.sh/v2/${imageAndTag[0]}/manifests/${imageAndTag[1]}`,
uri: `${registryUrl}/v2/${imageAndTag[0]}/manifests/${imageAndTag[1]}`,
headers,
resolveWithFullResponse: true,
simple: false,
}
};
const getResponse = await rp(getOptions);

if (getResponse.statusCode == 404) {
Expand All @@ -92,7 +93,7 @@ async function reapExpiredImages() {
continue;
}

const deleteURI = `https://ttl.sh/v2/${imageAndTag[0]}/manifests/${getResponse.headers.etag.replace(/"/g,"")}`;
const deleteURI = `${registryUrl}/v2/${imageAndTag[0]}/manifests/${getResponse.headers.etag.replace(/"/g, "")}`;

// Remove from the registry
const options = {
Expand All @@ -101,14 +102,14 @@ async function reapExpiredImages() {
headers,
resolveWithFullResponse: true,
simple: false,
}
};

await rp(options);

console.log(`expiring ${image}`);
await sremAsync("current.images", image);
await delAsync(image);
} catch(err) {
} catch (err) {
console.log(`failed to evaluate image ${image}:`, err);
}
}
Expand Down
4 changes: 2 additions & 2 deletions hooks/src/controllers/HookAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ export class HookAPI {
console.log(`parsing tag ${tag}`);
let expiresIn = durationfromTag(tag);
if (expiresIn <= 0) {
expiresIn = defaultDuration
expiresIn = defaultDuration;
}
if (expiresIn > maxDuration) {
expiresIn = maxDuration
expiresIn = maxDuration;
}

await saddAsync("current.images", imageWithTag);
Expand Down
2 changes: 1 addition & 1 deletion hooks/src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function initLogger(): any {
logger.level = process.env["LOG_LEVEL"] || "warn";
return logger;
} else {
const logger = pino(logOptions)
const logger = pino(logOptions);
logger.level = process.env["LOG_LEVEL"] || "warn";
return logger;
}
Expand Down
2 changes: 1 addition & 1 deletion hooks/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export const preRequest = (req: express.Request, reqId: string) => {
export const requestId = (req: express.Request, handlerName: string) => {
const id = `${handlerName}:${uuid.v4().replace("-", "").substring(0, 8)}`;

const clientID: string = <string> req.headers["x-request-uuid"];
const clientID: string = req.headers["x-request-uuid"] as string;

if (clientID) {
return `${id}.${clientID.substring(0, 8)}`;
Expand Down
2 changes: 1 addition & 1 deletion hooks/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ yargs
.env()
.help()
.demandCommand()
.argv;
.argv;
2 changes: 1 addition & 1 deletion hooks/src/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ if (port == null || port == "") {
debug: false,
logger: {
level: "warn",
}
},
})

export class Server extends ServerLoader {
Expand Down
3 changes: 3 additions & 0 deletions kustomize/base/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources: []
62 changes: 62 additions & 0 deletions kustomize/overlays/dev/hooks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: ttl-hooks
labels:
app: ttl-hooks
spec:
selector:
matchLabels:
app: ttl-hooks
template:
metadata:
labels:
app: ttl-hooks
spec:
restartPolicy: Always
initContainers:
- name: wait-for-registry
image: quay.io/curl/curl:latest
command:
- sh
- -c
- |
until curl -s -o /dev/null -w "%{http_code}" ttl-registry:5000/v2/; do
echo "Waiting for Docker Registry to be ready..."
sleep 2
done
- name: wait-for-redis
image: redis:latest
command:
- sh
- -c
- |
until redis-cli -h ttl-redis -p 6379 ping | grep "PONG"; do
echo "Waiting for Redis to be ready..."
sleep 2
done
containers:
- name: ttl-hooks
image: ttl-hooks
ports:
- containerPort: 8000
env:
- name: REDISCLOUD_URL
value: redis://ttl-redis:6379
- name: HOOK_TOKEN
value: dev-hook-token
---
apiVersion: v1
kind: Service
metadata:
name: ttl-hooks
labels:
app: ttl-hooks
spec:
type: ClusterIP
ports:
- protocol: TCP
port: 8000
targetPort: 8000
selector:
app: ttl-hooks
8 changes: 8 additions & 0 deletions kustomize/overlays/dev/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
- ./hooks.yaml
- ./reaper.yaml
- ./redis.yaml
- ./registry.yaml
Loading

0 comments on commit 7624fbf

Please sign in to comment.