Skip to content

Commit

Permalink
Merge pull request #52 from utopia-php/fix-dockerapi-stream
Browse files Browse the repository at this point in the history
Fix: DockerAPI Execute stream
  • Loading branch information
christyjacob4 authored Aug 13, 2024
2 parents b41dd82 + c01e0bb commit 0d7e722
Show file tree
Hide file tree
Showing 11 changed files with 200 additions and 95 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: "CodeQL"

on: [pull_request]
jobs:
lint:
name: CodeQL
runs-on: ubuntu-latest

steps:
- name: Check out the repo
uses: actions/checkout@v2

- name: Run CodeQL
run: |
docker run --rm -v $PWD:/app composer sh -c \
"composer install --profile --ignore-platform-reqs && composer check"
10 changes: 7 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@ jobs:

- name: Validate composer.json and composer.lock
run: composer validate --strict

- name: Install dependencies
run: composer install --ignore-platform-reqs --optimize-autoloader --no-plugins --no-scripts --prefer-dist

- name: Compose install
run: composer install --ignore-platform-reqs
- name: Start container
# For local testing, also run this before retrying tests: docker rm --force $(docker ps -aq)
run: docker compose up -d && sleep 15

- name: Run tests
run: composer test
run: docker compose exec tests vendor/bin/phpunit --configuration phpunit.xml
10 changes: 8 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,22 @@ COPY composer.lock /usr/local/src/
COPY composer.json /usr/local/src/

RUN composer install --ignore-platform-reqs --optimize-autoloader --no-plugins --no-scripts --prefer-dist


RUN docker-php-ext-install sockets

FROM php:8.0-cli-alpine as final

ENV DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
ENV DOCKER_API_VERSION=1.43

LABEL maintainer="team@appwrite.io"

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN \
apk update \
&& apk add --no-cache make automake autoconf gcc g++ git brotli-dev \
&& apk add --no-cache make automake autoconf gcc g++ git brotli-dev docker-cli \
&& docker-php-ext-install sockets \
&& docker-php-ext-install opcache

WORKDIR /usr/src/code
Expand Down
28 changes: 14 additions & 14 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ services:
context: .
networks:
- orchestration
volumes:
environment:
HOST_DIR: "$PWD" # Nessessary to mount test resources to child containers
volumes:
- ./:/usr/src/code
- /var/run/docker.sock:/var/run/docker.sock

Expand Down
58 changes: 37 additions & 21 deletions src/Orchestration/Adapter/DockerAPI.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,34 +130,50 @@ protected function streamCall(string $url, int $timeout = -1): array
$stdout = '';
$stderr = '';

$callback = function (mixed $ch, string $str) use (&$stdout, &$stderr): int {
$isHeader = true;
$currentHeader = null;
$currentData = '';

$callback = function (mixed $ch, string $str) use (&$stdout, &$stderr, &$isHeader, &$currentHeader, &$currentData): int {
if (empty($str)) {
return 0;
}

$rawStream = unpack('C*', $str);
$stream = $rawStream[1]; // 1-based index, not 0-based

// Ascii encoding support
if ($stream === \ord('1')) {
$stream = 1;
} elseif ($stream === \ord('2')) {
$stream = 2;
}

switch ($stream) { // only 1 or 2, as set while creating exec
case 1:
$packed = pack('C*', ...\array_slice($rawStream, 8));
$stdout .= $packed;
break;
case 2:
$packed = pack('C*', ...\array_slice($rawStream, 8));
$stderr .= $packed;
break;
$originalSize = \mb_strlen($str);

while (! empty($str)) {
if ($isHeader) {
$header = \unpack('Ctype/Cfill1/Cfill2/Cfill3/Nsize', $str);
$str = \mb_strcut($str, 8, null);
$isHeader = false;
$currentHeader = $header;
} else {
$size = $currentHeader['size'];
$type = $currentHeader['type'];

if (\strlen($str) >= $size) {
$currentData .= \mb_substr($str, 0, $size);
$str = \mb_strcut($str, $size, null);
$isHeader = true;
$currentHeader = null;

if ($type === 1) {
$stdout .= $currentData;
} else {
$stderr .= $currentData;
}
$currentData = '';
} else {
$currentHeader['size'] -= \mb_strlen($str);
$currentData .= $str;
$str = '';
}
}
}

return strlen($str); // must return full frame from callback
return $originalSize; // must return full frame from callback
};

\curl_setopt($ch, CURLOPT_WRITEFUNCTION, $callback);

\curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
Expand Down
Loading

0 comments on commit 0d7e722

Please sign in to comment.