Skip to content

Commit

Permalink
Push to insecure registries (#40)
Browse files Browse the repository at this point in the history
* fix(test): Make Node trust self-signed certificate for test

* feat: Allow pushing without a token for registries that allow it

* chore: adding Vegard S. Hagen as contributor
  • Loading branch information
vehagn authored Jan 28, 2024
1 parent 41cbce5 commit 7dba758
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 13 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Changelog

## [3.1.0] - 2024-01-27

### Added

- Allow pushing without a token (`--allowNoPushAuth`) to registries that allow it

### Fixed

- Fixed an error with failed push (using a token) when pulling without a token

## [3.0.1] - 2024-01-18

### Fixed
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ Options:
--setTimeStamp <timestamp> Optional: Set a specific ISO 8601 timestamp on all entries (e.g. git commit hash). Default: 1970 in tar files, and current time on manifest/config
--verbose Verbose logging
--allowInsecureRegistries Allow insecure registries (with self-signed/untrusted cert)
--allowNoPushAuth Allow pushing images without authentication/token if the registry allows it
--customContent <dirs/files> Optional: Skip normal node_modules and applayer and include specified root folder files/directories instead. You can specify as
local-path:absolute-container-path if you want to place it in a specific location
--extraContent <dirs/files> Optional: Add specific content. Specify as local-path:absolute-container-path,local-path2:absolute-container-path2 etc
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "containerify",
"version": "3.0.1",
"version": "3.1.0",
"description": "Build node.js docker images without docker",
"main": "./lib/cli.js",
"scripts": {
Expand All @@ -19,6 +19,9 @@
"containerify": "./lib/cli.js"
},
"author": "Erlend Oftedal <[email protected]>",
"contributors": [
"Vegard S. Hagen <[email protected]>"
],
"license": "Apache-2.0",
"repository": {
"type": "git",
Expand Down
6 changes: 2 additions & 4 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ const possibleArgs = {
"Optional: Set a specific ISO 8601 timestamp on all entries (e.g. git commit hash). Default: 1970 in tar files, and current time on manifest/config",
"--verbose": "Verbose logging",
"--allowInsecureRegistries": "Allow insecure registries (with self-signed/untrusted cert)",
"--allowNoPushAuth": "Allow pushing images without a authentication/token to registries that allow it",
"--customContent <dirs/files>":
"Optional: Skip normal node_modules and applayer and include specified root folder files/directories instead. You can specify as local-path:absolute-container-path if you want to place it in a specific location",
"--extraContent <dirs/files>":
Expand Down Expand Up @@ -242,7 +243,7 @@ exitWithErrorIf(
!options.toRegistry && !options.toTar && !options.toDocker,
"Must specify either --toTar, --toRegistry or --toDocker",
);
exitWithErrorIf(!!options.toRegistry && !options.toToken, "A token must be given when uploading to docker hub");
exitWithErrorIf(!!options.toRegistry && !options.toToken && !options.allowNoPushAuth, "A token must be provided when uploading images");

if (options.toRegistry && !options.toRegistry.endsWith("/")) options.toRegistry += "/";
if (options.fromRegistry && !options.fromRegistry.endsWith("/")) options.fromRegistry += "/";
Expand Down Expand Up @@ -304,9 +305,6 @@ async function run(options: Options) {
await tarExporter.saveToTar(todir, tmpdir, options.toTar, [options.toImage], options);
}
if (options.toRegistry) {
if (!options.token && allowInsecure == InsecureRegistrySupport.NO) {
throw new Error("Need auth token to upload to " + options.toRegistry);
}
const toRegistry = await createRegistry(
options.toRegistry,
options.toImage,
Expand Down
9 changes: 5 additions & 4 deletions src/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,12 @@ function uploadContent(
logger.debug("Uploading: ", file);
let url = uploadUrl;
if (fileConfig.digest) url += (url.indexOf("?") == -1 ? "?" : "&") + "digest=" + fileConfig.digest;
const options = createHttpOptions("PUT", url, {
authorization: auth,
const headers: OutgoingHttpHeaders = {
"content-length": fileConfig.size,
"content-type": contentType,
});
}
if (auth) headers.authorization = auth
const options = createHttpOptions("PUT", url, headers)
logger.debug(options.method, url);
const req = request(options, allowInsecure, (res) => {
logger.debug(res.statusCode, res.statusMessage, res.headers["content-type"], res.headers["content-length"]);
Expand Down Expand Up @@ -222,7 +223,7 @@ export async function createRegistry(
const url = `${registryBaseUrl}${image.path}/blobs/uploads/${parameters.size > 0 ? "?" + parameters : ""}`;
const options: https.RequestOptions = URL.parse(url);
options.method = "POST";
options.headers = { authorization: auth };
if (auth) options.headers = { authorization: auth };
request(options, allowInsecure, (res) => {
logger.debug("POST", `${url}`, res.statusCode);
if (res.statusCode == 202) {
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export type Options = {
setTimeStamp?: string;
verbose?: boolean;
allowInsecureRegistries?: boolean;
allowNoPushAuth?: boolean;
customContent: Record<string, string>;
extraContent: Record<string, string>;
layerOwner?: string;
Expand Down
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const VERSION = "3.0.1";
export const VERSION = "3.1.0";
56 changes: 56 additions & 0 deletions tests/localtest/test-insecure.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/bin/bash

set -e

export DOCKER_CONFIG=tmp
LOCAL_REGISTRY=127.0.0.1

rm -rf tmp
mkdir tmp

printf "* Stopping any running local containerify test registry...\n"
docker stop registry-containerify-insecure-test >/dev/null 2>&1 || echo "No running container registry, so nothing to stop"

printf "* Starting local containerify test registry on port 5443...\n"
docker run -d \
--rm \
--name registry-containerify-insecure-test \
-e REGISTRY_HTTP_ADDR=0.0.0.0:5443 \
-p 5443:5443 \
registry:2 > /dev/null

printf "* Pulling node:alpine as base image...\n"
docker pull node:alpine &> /dev/null

printf "* Pushing base image to local containerify test registry...\n"
docker tag node:alpine ${LOCAL_REGISTRY}:5443/node > /dev/null
docker push ${LOCAL_REGISTRY}:5443/node > /dev/null

printf "* Running containerify to pull from and push result to the local containerify test registry...\n"
cd ../integration/app
npm ci
cd ../../localtest
../../lib/cli.js \
--fromRegistry http://${LOCAL_REGISTRY}:5443/v2/ \
--fromImage node \
--toRegistry http://${LOCAL_REGISTRY}:5443/v2/ \
--toImage containerify-integration-test:localtest \
--doCrossMount \
--allowInsecureRegistries \
--allowNoPushAuth \
--folder ../integration/app --setTimeStamp "2024-01-18T13:33:33.337Z" \

printf "\n* Pulling image from registry to local docker daemon...\n"
docker pull ${LOCAL_REGISTRY}:5443/containerify-integration-test:localtest &> /dev/null

printf "* Running image on local docker daemon...\n"
docker run --rm -it ${LOCAL_REGISTRY}:5443/containerify-integration-test:localtest

printf "\n* Deleting image from registry to local docker daemon...\n"
docker rmi ${LOCAL_REGISTRY}:5443/containerify-integration-test:localtest > /dev/null

printf "* Stopping local containerify test registry...\n"
docker stop registry-containerify-insecure-test > /dev/null
rm -rf tmp

printf "\nSUCCESS!\n"
12 changes: 9 additions & 3 deletions tests/localtest/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ mkdir -p tmp/auth
printf "* Generating key for local registry...\n"
openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout tmp/certs/domain.key \
-addext "subjectAltName = DNS:myregistry.domain.com" \
-addext "subjectAltName = IP:${LOCAL_REGISTRY}" \
-subj "/C=NO/ST=containerify/L=containerify/O=containerify Integration/OU=Test Department/CN=containerify.test" \
-x509 -days 365 -out tmp/certs/domain.crt > /dev/null 2>&1

Expand Down Expand Up @@ -54,9 +54,15 @@ docker push ${LOCAL_REGISTRY}:5443/node > /dev/null

printf "* Running containerify to pull from and push result to the local containerify test registry...\n"
cd ../integration/app
npm install
npm ci
cd ../../localtest
../../lib/cli.js --fromImage node --doCrossMount --registry https://${LOCAL_REGISTRY}:5443/v2/ --toImage containerify-integration-test:localtest --folder ../integration/app --setTimeStamp "2023-03-07T12:53:10.471Z" --allowInsecureRegistries --token "Basic $BASICAUTH"
NODE_EXTRA_CA_CERTS=tmp/certs/domain.crt ../../lib/cli.js \
--fromImage node \
--doCrossMount \
--registry https://${LOCAL_REGISTRY}:5443/v2/ \
--toImage containerify-integration-test:localtest \
--folder ../integration/app --setTimeStamp "2023-03-07T12:53:10.471Z" \
--token "Basic $BASICAUTH"


printf "\n* Pulling image from registry to local docker daemon...\n"
Expand Down

0 comments on commit 7dba758

Please sign in to comment.