mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-06 15:43:02 +02:00
Compare commits
23
Commits
v25.06.0
...
upload-image
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc0edaf59c | ||
|
|
60b3a97f0e | ||
|
|
e534c0bd2d | ||
|
|
692fa166d1 | ||
|
|
c5d9a7c8b3 | ||
|
|
45c588567d | ||
|
|
2a8580edcc | ||
|
|
ffd0c05f41 | ||
|
|
9271c2439f | ||
|
|
7295077f27 | ||
|
|
b3d76de8f3 | ||
|
|
56f14ff520 | ||
|
|
9845e3b0c7 | ||
|
|
08e6833266 | ||
|
|
df54982978 | ||
|
|
efd6cce842 | ||
|
|
1dc84af095 | ||
|
|
d6c0d4bea7 | ||
|
|
85c4b579d3 | ||
|
|
1f268a7b90 | ||
|
|
562fd253c4 | ||
|
|
be547ba9a8 | ||
|
|
eabaaac7c2 |
+55
-151
@@ -1,30 +1,51 @@
|
|||||||
name: Bob the Builder
|
name: Build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
|
||||||
types: [opened, synchronize, reopened, labeled]
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
minimal:
|
flavor:
|
||||||
description: 'Build minimal defconfigs'
|
description: 'Optional build flavor (e.g. _minimal)'
|
||||||
required: false
|
required: false
|
||||||
default: true
|
default: ''
|
||||||
type: boolean
|
type: string
|
||||||
parallell:
|
parallel:
|
||||||
description: 'Massive parallel build of each image'
|
description: 'Massive parallel build of each image'
|
||||||
required: false
|
required: false
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
|
infix_repo:
|
||||||
|
description: 'Repo to checkout (for spin overrides)'
|
||||||
|
required: false
|
||||||
|
default: kernelkit/infix
|
||||||
|
type: string
|
||||||
|
|
||||||
|
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
target:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
flavor:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
infix_repo:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: kernelkit/infix
|
||||||
|
|
||||||
|
env:
|
||||||
|
FLV: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.flavor || inputs.flavor }}
|
||||||
|
INFIX_REPO: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.infix_repo || inputs.infix_repo }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build Infix ${{ matrix.target }}
|
name: Build ${{ inputs.name }} ${{ inputs.target }}
|
||||||
runs-on: [ self-hosted, latest ]
|
runs-on: [ self-hosted, latest ]
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
|
||||||
target: [aarch64, x86_64]
|
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
outputs:
|
outputs:
|
||||||
build_id: ${{ steps.vars.outputs.INFIX_BUILD_ID }}
|
build_id: ${{ steps.vars.outputs.INFIX_BUILD_ID }}
|
||||||
@@ -36,8 +57,11 @@ jobs:
|
|||||||
rm -rf ./.??* || true
|
rm -rf ./.??* || true
|
||||||
ls -la ./
|
ls -la ./
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
- name: Checkout infix repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
repository: ${{ env.INFIX_REPO }}
|
||||||
|
ref: ${{ github.ref }}
|
||||||
clean: true
|
clean: true
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
@@ -55,26 +79,13 @@ jobs:
|
|||||||
"${{ github.event.number }}" "${{ github.event.pull_request.head.sha }}" \
|
"${{ github.event.number }}" "${{ github.event.pull_request.head.sha }}" \
|
||||||
| tee -a $GITHUB_OUTPUT $GITHUB_ENV
|
| tee -a $GITHUB_OUTPUT $GITHUB_ENV
|
||||||
fi
|
fi
|
||||||
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
|
|
||||||
if [ "${{ github.event.inputs.minimal }}" == "true" ]; then
|
target=${{ inputs.target }}
|
||||||
flavor="_minimal"
|
name=${{ inputs.name }}
|
||||||
fi
|
echo "dir=${name}-${target}" >> $GITHUB_OUTPUT
|
||||||
else
|
echo "tgz=${name}-${target}.tar.gz" >> $GITHUB_OUTPUT
|
||||||
# Ensure 'release' job get the proper image when building main
|
echo "flv=$FLV" >> $GITHUB_OUTPUT
|
||||||
if [ "$GITHUB_REF_NAME" != "main" ]; then
|
echo "Building target ${target}${FLV}_defconfig"
|
||||||
flavor="_minimal"
|
|
||||||
else
|
|
||||||
flavor=""
|
|
||||||
fi
|
|
||||||
if ${{ contains(github.event.pull_request.labels.*.name, 'ci:main') }}; then
|
|
||||||
flavor=""
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
target=${{ matrix.target }}
|
|
||||||
echo "dir=infix-$target" >> $GITHUB_OUTPUT
|
|
||||||
echo "tgz=infix-$target.tar.gz" >> $GITHUB_OUTPUT
|
|
||||||
echo "flv=$flavor" >> $GITHUB_OUTPUT
|
|
||||||
echo "Building target ${target}${flavor}_defconfig"
|
|
||||||
|
|
||||||
- name: Restore Cache of dl/
|
- name: Restore Cache of dl/
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
@@ -88,16 +99,16 @@ jobs:
|
|||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: .ccache/
|
path: .ccache/
|
||||||
key: ccache-${{ matrix.target }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
|
key: ccache-${{ inputs.target }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
ccache-${{ matrix.target }}-
|
ccache-${{ inputs.target }}-
|
||||||
ccache-
|
ccache-
|
||||||
|
|
||||||
- name: Configure ${{ matrix.target }}${{ steps.vars.outputs.flv }}
|
- name: Configure ${{ inputs.target }}${{ steps.vars.outputs.flv }}
|
||||||
run: |
|
run: |
|
||||||
make ${{ matrix.target }}${{ steps.vars.outputs.flv }}_defconfig
|
make ${{ inputs.target }}${{ steps.vars.outputs.flv }}_defconfig
|
||||||
|
|
||||||
- name: Unit Test ${{ matrix.target }}
|
- name: Unit Test ${{ inputs.target }}
|
||||||
run: |
|
run: |
|
||||||
make test-unit
|
make test-unit
|
||||||
|
|
||||||
@@ -115,9 +126,9 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
echo "MAKE=$MAKE" >> $GITHUB_OUTPUT
|
echo "MAKE=$MAKE" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
- name: Build ${{ matrix.target }}${{ steps.vars.outputs.flv }}
|
- name: Build ${{ inputs.target }}${{ steps.vars.outputs.flv }}
|
||||||
run: |
|
run: |
|
||||||
echo "Building ${{ matrix.target }}${{ steps.vars.outputs.flv }}_defconfig ..."
|
echo "Building ${{ inputs.target }}${{ steps.vars.outputs.flv }}_defconfig ..."
|
||||||
eval "${{ steps.parallel.outputs.MAKE }}"
|
eval "${{ steps.parallel.outputs.MAKE }}"
|
||||||
|
|
||||||
- name: Check SBOM from Build
|
- name: Check SBOM from Build
|
||||||
@@ -139,7 +150,7 @@ jobs:
|
|||||||
printf "Size of output/images/: "
|
printf "Size of output/images/: "
|
||||||
ls -l output/images/
|
ls -l output/images/
|
||||||
|
|
||||||
- name: Prepare ${{ matrix.target }} Artifact
|
- name: Prepare ${{ inputs.target }} Artifact
|
||||||
run: |
|
run: |
|
||||||
cd output/
|
cd output/
|
||||||
mv images ${{ steps.vars.outputs.dir }}
|
mv images ${{ steps.vars.outputs.dir }}
|
||||||
@@ -149,111 +160,4 @@ jobs:
|
|||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: output/${{ steps.vars.outputs.tgz }}
|
path: output/${{ steps.vars.outputs.tgz }}
|
||||||
name: artifact-${{ matrix.target }}
|
name: artifact-${{ inputs.target }}
|
||||||
|
|
||||||
test:
|
|
||||||
name: Regression Test of Infix x86_64
|
|
||||||
needs: build
|
|
||||||
runs-on: [ self-hosted, regression ]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
clean: true
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Set Build Variables
|
|
||||||
id: vars
|
|
||||||
run: |
|
|
||||||
if [ -n "${{ needs.build.outputs.build_id }}" ]; then
|
|
||||||
echo "INFIX_BUILD_ID=${{ needs.build.outputs.build_id }}" \
|
|
||||||
>>$GITHUB_ENV
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$GITHUB_REF_NAME" != "main" ]; then
|
|
||||||
flavor="_minimal"
|
|
||||||
else
|
|
||||||
flavor=""
|
|
||||||
fi
|
|
||||||
echo "flv=$flavor" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Configure x86_64${{ steps.vars.outputs.flv }}
|
|
||||||
run: |
|
|
||||||
make x86_64${{ steps.vars.outputs.flv }}_defconfig
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
pattern: "artifact-*"
|
|
||||||
merge-multiple: true
|
|
||||||
|
|
||||||
- name: Restore x86-64${{ steps.vars.outputs.flv }} output/
|
|
||||||
run: |
|
|
||||||
ls -l
|
|
||||||
mkdir -p output
|
|
||||||
mv infix-x86_64.tar.gz output/
|
|
||||||
cd output/
|
|
||||||
tar xf infix-x86_64.tar.gz
|
|
||||||
ln -s infix-x86_64 images
|
|
||||||
|
|
||||||
- name: Regression Test x86_64${{ steps.vars.outputs.flv }}
|
|
||||||
run: |
|
|
||||||
make test
|
|
||||||
|
|
||||||
- name: Publish Test Result for x86_64${{ steps.vars.outputs.flv }}
|
|
||||||
# Ensure this runs even if Regression Test fails
|
|
||||||
if: always()
|
|
||||||
run: cat test/.log/last/result-gh.md >> $GITHUB_STEP_SUMMARY
|
|
||||||
|
|
||||||
- name: Generate Test Report for x86_64${{ steps.vars.outputs.flv }}
|
|
||||||
# Ensure this runs even if Regression Test fails
|
|
||||||
if: always()
|
|
||||||
run: |
|
|
||||||
asciidoctor-pdf \
|
|
||||||
--theme test/9pm/report/theme.yml \
|
|
||||||
-a pdf-fontsdir=test/9pm/report/fonts \
|
|
||||||
test/.log/last/report.adoc \
|
|
||||||
-o test/.log/last/report.pdf
|
|
||||||
|
|
||||||
- name: Upload Test Report as Artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: test-report
|
|
||||||
path: test/.log/last/report.pdf
|
|
||||||
|
|
||||||
release:
|
|
||||||
if: ${{github.repository_owner == 'kernelkit' && github.ref_name == 'main'}}
|
|
||||||
name: Upload Latest Build
|
|
||||||
needs: test
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
steps:
|
|
||||||
- uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
pattern: "artifact-*"
|
|
||||||
merge-multiple: true
|
|
||||||
|
|
||||||
- name: Create checksums ...
|
|
||||||
run: |
|
|
||||||
for file in *.tar.gz; do
|
|
||||||
sha256sum $file > $file.sha256
|
|
||||||
done
|
|
||||||
|
|
||||||
- uses: ncipollo/release-action@v1
|
|
||||||
with:
|
|
||||||
allowUpdates: true
|
|
||||||
omitName: true
|
|
||||||
omitBody: true
|
|
||||||
omitBodyDuringUpdate: true
|
|
||||||
prerelease: true
|
|
||||||
tag: "latest"
|
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
artifacts: "*.tar.gz*"
|
|
||||||
|
|
||||||
- name: Summary
|
|
||||||
run: |
|
|
||||||
cat <<EOF >> $GITHUB_STEP_SUMMARY
|
|
||||||
# Latest Build Complete! :rocket:
|
|
||||||
|
|
||||||
For the public download links of these build artifacts, please see:
|
|
||||||
<https://github.com/kernelkit/infix/releases/tag/latest>
|
|
||||||
EOF
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
name: Publish latest Infix
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
workflow_call:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
name: Upload Latest Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: "artifact-*"
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Create checksums ...
|
||||||
|
run: |
|
||||||
|
for file in *.tar.gz; do
|
||||||
|
sha256sum $file > $file.sha256
|
||||||
|
done
|
||||||
|
|
||||||
|
- uses: ncipollo/release-action@v1
|
||||||
|
with:
|
||||||
|
allowUpdates: true
|
||||||
|
omitName: true
|
||||||
|
omitBody: true
|
||||||
|
omitBodyDuringUpdate: true
|
||||||
|
prerelease: true
|
||||||
|
tag: "latest"
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
artifacts: "*.tar.gz*"
|
||||||
|
|
||||||
|
- name: Summary
|
||||||
|
run: |
|
||||||
|
cat <<EOF >> $GITHUB_STEP_SUMMARY
|
||||||
|
# Latest Build Complete! :rocket:
|
||||||
|
|
||||||
|
For the public download links of these build artifacts, please see:
|
||||||
|
<https://github.com/kernelkit/infix/releases/tag/latest>
|
||||||
|
EOF
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
name: Test Infix
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
infix_repo:
|
||||||
|
description: 'Repo to checkout (for spin overrides)'
|
||||||
|
required: false
|
||||||
|
default: kernelkit/infix
|
||||||
|
type: string
|
||||||
|
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
target:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
flavor:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
infix_repo:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: kernelkit/infix
|
||||||
|
ninepm-conf:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
test-path:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: 'test'
|
||||||
|
|
||||||
|
env:
|
||||||
|
FLV: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.flavor || inputs.flavor }}
|
||||||
|
INFIX_REPO: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.infix_repo || inputs.infix_repo }}
|
||||||
|
NINEPM_CONF: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.ninepm-conf || inputs.ninepm-conf }}
|
||||||
|
TEST_PATH: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.test-path || inputs.test-path }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Regression Test ${{ inputs.name }} ${{ inputs.target }}
|
||||||
|
runs-on: [ self-hosted, regression ]
|
||||||
|
steps:
|
||||||
|
- name: Checkout infix repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
repository: ${{ env.INFIX_REPO }}
|
||||||
|
ref: ${{ github.ref }}
|
||||||
|
clean: true
|
||||||
|
fetch-depth: 0
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Set Build Variables
|
||||||
|
id: vars
|
||||||
|
run: |
|
||||||
|
if [ -n "${{ needs.build.outputs.build_id }}" ]; then
|
||||||
|
echo "INFIX_BUILD_ID=${{ needs.build.outputs.build_id }}" \
|
||||||
|
>>$GITHUB_ENV
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "flv=$FLV" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Configure ${{ inputs.target }}${{ steps.vars.outputs.flv }}
|
||||||
|
run: |
|
||||||
|
make ${{ inputs.target }}${{ steps.vars.outputs.flv }}_defconfig
|
||||||
|
|
||||||
|
- uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
pattern: "artifact-*"
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: Restore x86-64${{ steps.vars.outputs.flv }} output/
|
||||||
|
run: |
|
||||||
|
target=${{ inputs.target }}
|
||||||
|
name=${{ inputs.name }}
|
||||||
|
|
||||||
|
ls -l
|
||||||
|
mkdir -p output
|
||||||
|
mv ${name}-${target}.tar.gz output/
|
||||||
|
cd output/
|
||||||
|
tar xf ${name}-${target}.tar.gz
|
||||||
|
ln -s ${name}-${target} images
|
||||||
|
|
||||||
|
- name: Regression Test x86_64${{ steps.vars.outputs.flv }}
|
||||||
|
run: |
|
||||||
|
if [ -n "$NINEPM_CONF" ]; then
|
||||||
|
export NINEPM_PROJ_CONFIG="${GITHUB_WORKSPACE}/$NINEPM_CONF"
|
||||||
|
echo "DEBUG: NINEPM_PROJ_CONFIG is '$NINEPM_PROJ_CONFIG'"
|
||||||
|
fi
|
||||||
|
make test
|
||||||
|
|
||||||
|
- name: Publish Test Result for x86_64${{ steps.vars.outputs.flv }}
|
||||||
|
# Ensure this runs even if Regression Test fails
|
||||||
|
if: always()
|
||||||
|
run: cat $TEST_PATH/.log/last/result-gh.md >> $GITHUB_STEP_SUMMARY
|
||||||
|
|
||||||
|
- name: Generate Test Report for x86_64${{ steps.vars.outputs.flv }}
|
||||||
|
# Ensure this runs even if Regression Test fails
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
asciidoctor-pdf \
|
||||||
|
--theme $TEST_PATH/9pm/report/theme.yml \
|
||||||
|
-a pdf-fontsdir=$TEST_PATH/9pm/report/fonts \
|
||||||
|
$TEST_PATH/.log/last/report.adoc \
|
||||||
|
-o $TEST_PATH/.log/last/report.pdf
|
||||||
|
|
||||||
|
- name: Upload Test Report as Artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: test-report
|
||||||
|
path: ${{ env.TEST_PATH }}/.log/last/report.pdf
|
||||||
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
name: Self Trigger
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, reopened, labeled]
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- ci-workflow-redesign
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-x86_64:
|
||||||
|
uses: ./.github/workflows/build.yml
|
||||||
|
with:
|
||||||
|
target: "x86_64"
|
||||||
|
name: "infix"
|
||||||
|
flavor: "_minimal"
|
||||||
|
|
||||||
|
build-aarch64:
|
||||||
|
uses: ./.github/workflows/build.yml
|
||||||
|
with:
|
||||||
|
target: "aarch64"
|
||||||
|
name: "infix"
|
||||||
|
flavor: "_minimal"
|
||||||
|
|
||||||
|
test-run-x86_64:
|
||||||
|
needs: build-x86_64
|
||||||
|
uses: ./.github/workflows/test.yml
|
||||||
|
with:
|
||||||
|
target: "x86_64"
|
||||||
|
name: "infix"
|
||||||
|
|
||||||
|
test-publish-x86_64:
|
||||||
|
needs: test-run-x86_64
|
||||||
|
uses: ./.github/workflows/publish.yml
|
||||||
|
|
||||||
@@ -1,5 +1,11 @@
|
|||||||
# /telemetry/optics is for streaming (not used atm)
|
# /telemetry/optics is for streaming (not used atm)
|
||||||
|
# Proxy buffer settings for large files
|
||||||
|
proxy_buffering off; # Disable buffering for streaming
|
||||||
|
proxy_request_buffering off; # Stream request body immediately
|
||||||
|
proxy_max_temp_file_size 0; # No temp files
|
||||||
location ~ ^/(restconf|yang|.well-known)/ {
|
location ~ ^/(restconf|yang|.well-known)/ {
|
||||||
|
client_max_body_size 200M;
|
||||||
|
client_body_buffer_size 1M;
|
||||||
grpc_pass grpc://[::1]:10080;
|
grpc_pass grpc://[::1]:10080;
|
||||||
grpc_set_header Host $host;
|
grpc_set_header Host $host;
|
||||||
grpc_set_header X-Real-IP $remote_addr;
|
grpc_set_header X-Real-IP $remote_addr;
|
||||||
|
|||||||
+177
-16
@@ -168,36 +168,36 @@ Now you can rebuild `confd`, just as described above, and restart Infix:
|
|||||||
|
|
||||||
### `statd`
|
### `statd`
|
||||||
|
|
||||||
The Infix status daemon, `src/statd`, is responsible for populating the
|
The Infix status daemon, `src/statd`, is responsible for populating the
|
||||||
sysrepo `operational` datastore. Like `confd`, it uses XPath subscriptions,
|
sysrepo `operational` datastore. Like `confd`, it uses XPath subscriptions,
|
||||||
but unlike `confd`, it relies entirely on `yanger`, a Python script that
|
but unlike `confd`, it relies entirely on `yanger`, a Python script that
|
||||||
gathers data from local linux services and feeds it into sysrepo.
|
gathers data from local linux services and feeds it into sysrepo.
|
||||||
|
|
||||||
To apply changes, rebuild the image:
|
To apply changes, rebuild the image:
|
||||||
|
|
||||||
make python-statd-rebuild statd-rebuild all
|
make python-statd-rebuild statd-rebuild all
|
||||||
|
|
||||||
Rebuilding the image and testing on target for every change during
|
Rebuilding the image and testing on target for every change during
|
||||||
development process can be tedious. Instead, `yanger` allows remote
|
development process can be tedious. Instead, `yanger` allows remote
|
||||||
execution, running the script directly on the host system (test
|
execution, running the script directly on the host system (test
|
||||||
container):
|
container):
|
||||||
|
|
||||||
infamy0:test # ../src/statd/python/yanger/yanger -x "../utils/ixll -A ssh d3a" ieee802-dot1ab-lldp
|
infamy0:test # ../src/statd/python/yanger/yanger -x "../utils/ixll -A ssh d3a" ieee802-dot1ab-lldp
|
||||||
|
|
||||||
`ixll` is a utility script that lets you run network commands using an
|
`ixll` is a utility script that lets you run network commands using an
|
||||||
**interface name** instead of a hostname. It makes operations like
|
**interface name** instead of a hostname. It makes operations like
|
||||||
`ssh`, `scp`, and network discovery easier.
|
`ssh`, `scp`, and network discovery easier.
|
||||||
|
|
||||||
Normally, `yanger` runs commands **locally** to retrieve data
|
Normally, `yanger` runs commands **locally** to retrieve data
|
||||||
(e.g., `lldpcli` when handling `ieee802-dot1ab-lldp`). However, when
|
(e.g., `lldpcli` when handling `ieee802-dot1ab-lldp`). However, when
|
||||||
executed with `-x "../utils/ixll -A ssh d3a"` it redirects these
|
executed with `-x "../utils/ixll -A ssh d3a"` it redirects these
|
||||||
commands to a remote system connected to the local `d3a` interface via
|
commands to a remote system connected to the local `d3a` interface via
|
||||||
SSH. This setup is used for running `yanger` in an
|
SSH. This setup is used for running `yanger` in an
|
||||||
[interactive test environment](testing.md#interactive-usage). The yanger
|
[interactive test environment](testing.md#interactive-usage). The yanger
|
||||||
script runs on the `host` system, but key commands are executed on the
|
script runs on the `host` system, but key commands are executed on the
|
||||||
`target` system.
|
`target` system.
|
||||||
|
|
||||||
For debugging or testing, you can capture system command output and
|
For debugging or testing, you can capture system command output and
|
||||||
replay it later without needing a live system.
|
replay it later without needing a live system.
|
||||||
|
|
||||||
To capture:
|
To capture:
|
||||||
@@ -211,12 +211,173 @@ To replay:
|
|||||||
This is especially useful when working in isolated environments or debugging
|
This is especially useful when working in isolated environments or debugging
|
||||||
issues without direct access to the DUT.
|
issues without direct access to the DUT.
|
||||||
|
|
||||||
|
### Upgrading Packages
|
||||||
|
|
||||||
|
#### Buildroot
|
||||||
|
|
||||||
|
Kernelkit maintains an internal [fork of
|
||||||
|
Buildroot](https://github.com/kernelkit/buildroot), with branches
|
||||||
|
following the naming scheme `YYYY.MM.patch-kkit`
|
||||||
|
e.g. `2025.02.1-kkit`, which means a new branch should be created
|
||||||
|
whenever Buildroot is updated. These branches should contain **only**
|
||||||
|
changes to existing packages (but no new patches), modifications to
|
||||||
|
Buildroot itself or upstream backports.
|
||||||
|
|
||||||
|
KernelKit track the latest Buildroot LTS (Long-Term Support) release
|
||||||
|
and updates. The upgrade of LTS minor releases is expected to have low
|
||||||
|
impact and should be done as soon there is a patch release of
|
||||||
|
Buildroot LTS is available.
|
||||||
|
|
||||||
|
> **Depending on your setup, follow the appropriate steps below.**
|
||||||
|
|
||||||
|
🔁 If you **already have** the Buildroot repo locally
|
||||||
|
|
||||||
|
1. Navigate to the Buildroot directory
|
||||||
|
```bash
|
||||||
|
$ cd buildroot
|
||||||
|
```
|
||||||
|
2. Pull the latest changes from KernelKit
|
||||||
|
```bash
|
||||||
|
$ git pull
|
||||||
|
```
|
||||||
|
3. Fetch the latest tags from upstream
|
||||||
|
```bash
|
||||||
|
$ git fetch upstream --tags
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
🆕 If you don't have the repo locally
|
||||||
|
|
||||||
|
1. Clone the Kernelkit Buildroot repository
|
||||||
|
```bash
|
||||||
|
$ git clone git@github.com:kernelkit/buildroot.git
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Add the upstream remote
|
||||||
|
```bash
|
||||||
|
$ git remote add upstream https://gitlab.com/buildroot.org/buildroot.git
|
||||||
|
```
|
||||||
|
3. Checkout old KernelKit branch
|
||||||
|
```bash
|
||||||
|
$ git checkout 2025.02.1-kkit
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
🛠 Continue from here (applies to both cases):
|
||||||
|
|
||||||
|
4. Create a new branch based on the **previous** KernelKit Buildroot
|
||||||
|
release (e.g. `2025.02.1-kkit`) and name it according to the naming scheme (e.g. `2025.02.2-kkit`)
|
||||||
|
```bash
|
||||||
|
$ git checkout -b 2025.02.2-kkit
|
||||||
|
```
|
||||||
|
5. Rebase the new branch onto the corresponding upstream release
|
||||||
|
```bash
|
||||||
|
$ git rebase 2025.02.2
|
||||||
|
```
|
||||||
|
> [!NOTE] It is **not** allowed to rebase the branch when bumped in Infix.
|
||||||
|
|
||||||
|
6. Push the new branch and tags
|
||||||
|
```bash
|
||||||
|
$ git push origin 2025.02.2-kkit --tags
|
||||||
|
```
|
||||||
|
7. In Infix, checkout new branch of Buildroot
|
||||||
|
```bash
|
||||||
|
$ cd buildroot
|
||||||
|
$ git fetch
|
||||||
|
$ git checkout 2025.02.2-kkit
|
||||||
|
```
|
||||||
|
8. Push changes
|
||||||
|
Commit and push the changes. Don’t forget to update the changelog.
|
||||||
|
|
||||||
|
9. Create a pull request.
|
||||||
|
|
||||||
|
> [!NOTE] Remember to set the pull request label to `ci:main` to ensure full CI coverage.
|
||||||
|
|
||||||
|
|
||||||
|
#### Linux kernel
|
||||||
|
|
||||||
|
KernelKit maintains an internal [fork of Linux
|
||||||
|
kernel](https://github.com/kernelkit/linux), with branches following
|
||||||
|
the naming scheme `kkit-linux-[version].y`, e.g. `kkit-6.12.y`, which
|
||||||
|
means a new branch should be created whenever the major kernel version
|
||||||
|
is updated. This branch should contain *all* kernel patches used by
|
||||||
|
Infix.
|
||||||
|
|
||||||
|
KernelKit track the latest Linux kernel LTS (Long-Term Support)
|
||||||
|
release and updates. The upgrade of LTS minor releases is expected to
|
||||||
|
have low impact and should be done as soon as a patch release of the
|
||||||
|
LTS Linux kernel is available.
|
||||||
|
|
||||||
|
|
||||||
|
🔁 If you **already have** the Linux kernel repo locally
|
||||||
|
|
||||||
|
1. Navigate to the Linux kernel directory
|
||||||
|
```bash
|
||||||
|
$ cd linux
|
||||||
|
```
|
||||||
|
2. Get latest changes from KernelKit
|
||||||
|
```bash
|
||||||
|
$ git pull
|
||||||
|
```
|
||||||
|
3. Fetch the latest tags from upstream
|
||||||
|
```bash
|
||||||
|
$ git fetch upstream --tags
|
||||||
|
```
|
||||||
|
|
||||||
|
🆕 If you don't have the repo locally
|
||||||
|
|
||||||
|
1. Clone the KernelKit Linux kernel repository
|
||||||
|
```bash
|
||||||
|
$ git clone git@github.com:kernelkit/linux.git
|
||||||
|
```
|
||||||
|
2. Add the upstream remote
|
||||||
|
```bash
|
||||||
|
$ git remote add upstream git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Checkout correct kernel branch
|
||||||
|
```bash
|
||||||
|
$ git checkout kkit-linux-6.12.y
|
||||||
|
```
|
||||||
|
|
||||||
|
🛠 Continue from here (applies to both cases)
|
||||||
|
|
||||||
|
|
||||||
|
4. Rebase on the upstream release
|
||||||
|
```bash
|
||||||
|
$ git rebase v6.12.29
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Push changes and the tags
|
||||||
|
```bash
|
||||||
|
|
||||||
|
$ git push -f origin kkit-linux-6.12.y --tags
|
||||||
|
```
|
||||||
|
|
||||||
|
**Move to your infix directory**
|
||||||
|
|
||||||
|
7. Generate patches
|
||||||
|
```bash
|
||||||
|
$ make x86_64_defconfig
|
||||||
|
$ cd output
|
||||||
|
$ ../utils/kernel-refresh.sh -k /path/to/linux -o 6.12.28 -t v6.12.29
|
||||||
|
```
|
||||||
|
> [!NOTE] See help of `kernel-refresh.sh` script for more information
|
||||||
|
|
||||||
|
|
||||||
|
8. Push changes
|
||||||
|
Commit and push the changes. Don’t forget to update the s:changelog:doc/ChangeLog.md.
|
||||||
|
|
||||||
|
9. Create a pull request.
|
||||||
|
> [!NOTE] Remember to set the pull request label to `ci:main` to ensure full CI coverage.
|
||||||
|
|
||||||
|
|
||||||
### Agree on YANG Model
|
### Agree on YANG Model
|
||||||
|
|
||||||
When making changes to the `confd` and `statd` services, you will often need to update
|
When making changes to the `confd` and `statd` services, you will often need to update
|
||||||
the YANG models. If you are adding a new YANG module, it's best to follow the
|
the YANG models. If you are adding a new YANG module, it's best to follow the
|
||||||
structure of an existing one. However, before making any changes, **always discuss
|
structure of an existing one. However, before making any changes, **always discuss
|
||||||
them with the Infix core team**. This helps avoid issues later in development and
|
them with the Infix core team**. This helps avoid issues later in development and
|
||||||
makes pull request reviews smoother.
|
makes pull request reviews smoother.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ PKG_CHECK_MODULES([jansson], [jansson >= 2.0.0])
|
|||||||
PKG_CHECK_MODULES([libite], [libite >= 2.6.1])
|
PKG_CHECK_MODULES([libite], [libite >= 2.6.1])
|
||||||
PKG_CHECK_MODULES([sysrepo], [sysrepo >= 2.2.36])
|
PKG_CHECK_MODULES([sysrepo], [sysrepo >= 2.2.36])
|
||||||
PKG_CHECK_MODULES([libsrx], [libsrx >= 1.0.0])
|
PKG_CHECK_MODULES([libsrx], [libsrx >= 1.0.0])
|
||||||
|
PKG_CHECK_MODULES([libssl], [libssl >= 1.0.0])
|
||||||
|
|
||||||
# Control build with automake flags
|
# Control build with automake flags
|
||||||
AM_CONDITIONAL(CONTAINERS, [test "x$enable_containers" != "xno"])
|
AM_CONDITIONAL(CONTAINERS, [test "x$enable_containers" != "xno"])
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ confd_plugin_la_CFLAGS = \
|
|||||||
$(libite_CFLAGS) \
|
$(libite_CFLAGS) \
|
||||||
$(sysrepo_CFLAGS) \
|
$(sysrepo_CFLAGS) \
|
||||||
$(libsrx_CFLAGS) \
|
$(libsrx_CFLAGS) \
|
||||||
|
$(libssl_CFLAGS) \
|
||||||
$(CFLAGS)
|
$(CFLAGS)
|
||||||
|
|
||||||
confd_plugin_la_LIBADD = \
|
confd_plugin_la_LIBADD = \
|
||||||
@@ -20,7 +21,8 @@ confd_plugin_la_LIBADD = \
|
|||||||
$(jansson_LIBS) \
|
$(jansson_LIBS) \
|
||||||
$(libite_LIBS) \
|
$(libite_LIBS) \
|
||||||
$(sysrepo_LIBS) \
|
$(sysrepo_LIBS) \
|
||||||
$(libsrx_LIBS)
|
$(libsrx_LIBS) \
|
||||||
|
$(libssl_LIBS)
|
||||||
|
|
||||||
confd_plugin_la_SOURCES = \
|
confd_plugin_la_SOURCES = \
|
||||||
base64.c base64.h \
|
base64.c base64.h \
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||||
#include <srx/common.h>
|
#include <srx/common.h>
|
||||||
#include <srx/lyx.h>
|
#include <srx/lyx.h>
|
||||||
|
#include <openssl/bio.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "rauc-installer.h"
|
#include "rauc-installer.h"
|
||||||
@@ -21,24 +24,111 @@ static RaucInstaller *infix_system_sw_new_rauc(void)
|
|||||||
return rauc;
|
return rauc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int base64_decode_inplace(char *input, size_t input_len, size_t *output_len)
|
||||||
|
{
|
||||||
|
BIO *bio, *b64;
|
||||||
|
int decode_len;
|
||||||
|
|
||||||
|
bio = BIO_new_mem_buf(input, input_len);
|
||||||
|
if (!bio) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
b64 = BIO_new(BIO_f_base64());
|
||||||
|
if (!b64) {
|
||||||
|
BIO_free(bio);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
|
||||||
|
bio = BIO_push(b64, bio);
|
||||||
|
|
||||||
|
/* Decode directly into the same buffer */
|
||||||
|
decode_len = BIO_read(bio, input, input_len);
|
||||||
|
BIO_free_all(bio);
|
||||||
|
|
||||||
|
if (decode_len < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*output_len = decode_len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int infix_system_sw_install(sr_session_ctx_t *session, uint32_t sub_id,
|
static int infix_system_sw_install(sr_session_ctx_t *session, uint32_t sub_id,
|
||||||
const char *path, const sr_val_t *input,
|
const char *path, const sr_val_t *input,
|
||||||
const size_t input_cnt, sr_event_t event,
|
const size_t input_cnt, sr_event_t event,
|
||||||
unsigned request_id, sr_val_t **output,
|
unsigned request_id, sr_val_t **output,
|
||||||
size_t *output_cnt, void *priv)
|
size_t *output_cnt, void *priv)
|
||||||
{
|
{
|
||||||
char *url = input->data.string_val;
|
|
||||||
sr_error_t srerr = SR_ERR_OK;
|
sr_error_t srerr = SR_ERR_OK;
|
||||||
GError *raucerr = NULL;
|
GError *raucerr = NULL;
|
||||||
RaucInstaller *rauc;
|
RaucInstaller *rauc = NULL;
|
||||||
|
char *install_source = NULL;
|
||||||
|
|
||||||
DEBUG("url:%s", url);
|
const char *url = NULL;
|
||||||
|
char *binary_data = NULL;
|
||||||
|
size_t binary_len = 0;
|
||||||
|
size_t decoded_len = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < input_cnt; i++) {
|
||||||
|
if (strcmp(input[i].xpath, "/infix-system:install-bundle/url") == 0) {
|
||||||
|
if (input[i].type == SR_STRING_T) {
|
||||||
|
url = input[i].data.string_val;
|
||||||
|
}
|
||||||
|
} else if (strcmp(input[i].xpath, "/infix-system:install-bundle/image") == 0) {
|
||||||
|
if (input[i].type == SR_BINARY_T) {
|
||||||
|
binary_data = (char *)input[i].data.binary_val; // Cast away const for in-place decode
|
||||||
|
binary_len = strlen(binary_data); // Length of base64 string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url) {
|
||||||
|
DEBUG("Installing from URL: %s", url);
|
||||||
|
install_source = (char *)url;
|
||||||
|
|
||||||
|
} else if (binary_data) {
|
||||||
|
const char *temp_dir = "/tmp";
|
||||||
|
char path[256];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
DEBUG("Installing from uploaded binary data (%zu bytes base64)", binary_len);
|
||||||
|
|
||||||
|
if (base64_decode_inplace(binary_data, binary_len, &decoded_len) != 0) {
|
||||||
|
sr_session_set_netconf_error(session, "application", "invalid-value",
|
||||||
|
NULL, NULL, "Failed to decode base64 image data", 0);
|
||||||
|
srerr = SR_ERR_INVAL_ARG;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmkpath(0775, "%s/images", temp_dir);
|
||||||
|
snprintf(path, sizeof(path), "%s/images/install_bundle", temp_dir);
|
||||||
|
|
||||||
|
fp = fopen(path, "wb");
|
||||||
|
if (!fp) {
|
||||||
|
ERROR("Could not open %s", path);
|
||||||
|
return SR_ERR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite(binary_data, sizeof(char), decoded_len, fp);
|
||||||
|
fclose(fp);
|
||||||
|
install_source = path;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ERROR("Unknown source");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
rauc = infix_system_sw_new_rauc();
|
rauc = infix_system_sw_new_rauc();
|
||||||
if (!rauc)
|
if (!rauc) {
|
||||||
return SR_ERR_INTERNAL;
|
sr_session_set_netconf_error(session, "application", "operation-failed",
|
||||||
|
NULL, NULL, "Failed to initialize RAUC installer", 0);
|
||||||
|
srerr = SR_ERR_INTERNAL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
rauc_installer_call_install_sync(rauc, url, NULL, &raucerr);
|
rauc_installer_call_install_sync(rauc, install_source, NULL, &raucerr);
|
||||||
if (raucerr) {
|
if (raucerr) {
|
||||||
sr_session_set_netconf_error(session, "application", "operation-failed",
|
sr_session_set_netconf_error(session, "application", "operation-failed",
|
||||||
NULL, NULL, raucerr->message, 0);
|
NULL, NULL, raucerr->message, 0);
|
||||||
@@ -46,13 +136,18 @@ static int infix_system_sw_install(sr_session_ctx_t *session, uint32_t sub_id,
|
|||||||
srerr = SR_ERR_OPERATION_FAILED;
|
srerr = SR_ERR_OPERATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref(rauc);
|
cleanup:
|
||||||
|
if (rauc) {
|
||||||
|
g_object_unref(rauc);
|
||||||
|
}
|
||||||
|
|
||||||
return srerr;
|
return srerr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
boot order can only be: primary, secondary and net, limited by model
|
boot order can only be: primary, secondary and net, limited by model
|
||||||
*/
|
*/
|
||||||
static int infix_system_sw_set_boot_order(sr_session_ctx_t *session, uint32_t sub_id,
|
static int infix_system_sw_set_boot_order(sr_session_ctx_t *session, uint32_t sub_id,
|
||||||
const char *path, const sr_val_t *input,
|
const char *path, const sr_val_t *input,
|
||||||
const size_t input_cnt, sr_event_t event,
|
const size_t input_cnt, sr_event_t event,
|
||||||
@@ -63,24 +158,24 @@ static int infix_system_sw_set_boot_order(sr_session_ctx_t *session, uint32_t su
|
|||||||
const sr_val_t *val = &input[i];
|
const sr_val_t *val = &input[i];
|
||||||
|
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
strlcat(boot_order, " ", sizeof(boot_order));
|
strlcat(boot_order, " ", sizeof(boot_order));
|
||||||
strlcat(boot_order, val->data.string_val, sizeof(boot_order));
|
strlcat(boot_order, val->data.string_val, sizeof(boot_order));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fexist("/sys/firmware/devicetree/base/chosen/u-boot,version")) {
|
if (fexist("/sys/firmware/devicetree/base/chosen/u-boot,version")) {
|
||||||
if (systemf("fw_setenv BOOT_ORDER %s", boot_order)) {
|
if (systemf("fw_setenv BOOT_ORDER %s", boot_order)) {
|
||||||
ERROR("Set-boot-order: Failed to set boot order in U-Boot");
|
ERROR("Set-boot-order: Failed to set boot order in U-Boot");
|
||||||
return SR_ERR_INTERNAL;
|
return SR_ERR_INTERNAL;
|
||||||
}
|
}
|
||||||
} else if (fexist("/mnt/aux/grub/grubenv")) {
|
} else if (fexist("/mnt/aux/grub/grubenv")) {
|
||||||
if (systemf("grub-editenv /mnt/aux/grub/grubenv set ORDER=\"%s\"", boot_order)) {
|
if (systemf("grub-editenv /mnt/aux/grub/grubenv set ORDER=\"%s\"", boot_order)) {
|
||||||
ERROR("Set-boot-order: Failed to set boot order in Grub");
|
ERROR("Set-boot-order: Failed to set boot order in Grub");
|
||||||
return SR_ERR_INTERNAL;
|
return SR_ERR_INTERNAL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ERROR("No supported boot loader found");
|
ERROR("No supported boot loader found");
|
||||||
return SR_ERR_UNSUPPORTED;
|
return SR_ERR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SR_ERR_OK;
|
return SR_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -204,16 +204,42 @@ submodule infix-system-software {
|
|||||||
description
|
description
|
||||||
"Upgrade the system's software by installing the specified bundle.";
|
"Upgrade the system's software by installing the specified bundle.";
|
||||||
input {
|
input {
|
||||||
leaf url {
|
choice source {
|
||||||
type string;
|
|
||||||
mandatory true;
|
mandatory true;
|
||||||
description
|
description
|
||||||
"The location of the software bundle, specified as a Uniform
|
"Source of the software bundle to install.";
|
||||||
Resource Locator (URL). Currently supported protocols include
|
case url {
|
||||||
FTP, HTTP(S) and SCP.";
|
leaf url {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"The location of the software bundle, specified as a Uniform
|
||||||
|
Resource Locator (URL). Currently supported protocols include
|
||||||
|
FTP, HTTP(S) and SCP.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case upload {
|
||||||
|
leaf image {
|
||||||
|
type binary;
|
||||||
|
description
|
||||||
|
"The image data to install, provided as base64-encoded binary data.";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rpc install-upload-bundle {
|
||||||
|
nacm:default-deny-all;
|
||||||
|
description "Upgrade the system's software by installing from a supplied blob.";
|
||||||
|
input {
|
||||||
|
leaf image {
|
||||||
|
type binary;
|
||||||
|
mandatory true;
|
||||||
|
description "The image to install";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rpc set-boot-order {
|
rpc set-boot-order {
|
||||||
nacm:default-deny-all;
|
nacm:default-deny-all;
|
||||||
description
|
description
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
=== Interface Speed Duplex (Copper)
|
=== Interface Speed Duplex (Copper)
|
||||||
==== Description
|
==== Description
|
||||||
Verify that auto-negotiation results in expected speed/duplex mode.
|
Verify that the interface operates at the expected speed/duplex in two scenarios:
|
||||||
|
|
||||||
|
1. Fixed configuration – host and target are both manually set to a specific speed/duplex
|
||||||
|
2. Auto-negotiation – host advertises selectable modes and the target negotiates
|
||||||
|
to the highest common speed/duplex.
|
||||||
|
|
||||||
==== Topology
|
==== Topology
|
||||||
ifdef::topdoc[]
|
ifdef::topdoc[]
|
||||||
@@ -17,17 +21,17 @@ endif::topdoc[]
|
|||||||
==== Test sequence
|
==== Test sequence
|
||||||
. Set up topology and attach to target DUT
|
. Set up topology and attach to target DUT
|
||||||
. Enable target interface
|
. Enable target interface
|
||||||
. Set fixed 10/full
|
. Verify fixed 10/full
|
||||||
. Set fixed 10/half
|
. Verify fixed 10/half
|
||||||
. Set fixed 100/full
|
. Verify fixed 100/full
|
||||||
. Set fixed 100/half
|
. Verify fixed 100/half
|
||||||
. Switch to auto-negotiation mode for target and host
|
. Switch to auto-negotiation mode for target and host
|
||||||
. Configure host to advertise 10/Full only
|
. Verify auto-negotiation to 10/Full only
|
||||||
. Configure host to advertise 10/Half only
|
. Verify auto-negotiation to 10/Half only
|
||||||
. Configure host to advertise 100/Full only
|
. Verify auto-negotiation to 100/Full only
|
||||||
. Configure host to advertise 100/Half only
|
. Verify auto-negotiation to 100/Half only
|
||||||
. Configure host to advertise 10/half + 10/full + 100/half
|
. Verify auto-negotiation to 10/half + 10/full + 100/half
|
||||||
. Configure host to advertise 10/half + 10/full + 100/half + 100/full + 1000/full
|
. Verify auto-negotiation to 10/half + 10/full + 100/half + 100/full + 1000/full
|
||||||
|
|
||||||
|
|
||||||
<<<
|
<<<
|
||||||
|
|||||||
@@ -2,7 +2,11 @@
|
|||||||
"""
|
"""
|
||||||
Interface Speed Duplex (Copper)
|
Interface Speed Duplex (Copper)
|
||||||
|
|
||||||
Verify that auto-negotiation results in expected speed/duplex mode.
|
Verify that the interface operates at the expected speed/duplex in two scenarios:
|
||||||
|
|
||||||
|
1. Fixed configuration – host and target are both manually set to a specific speed/duplex
|
||||||
|
2. Auto-negotiation – host advertises selectable modes and the target negotiates
|
||||||
|
to the highest common speed/duplex.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import infamy
|
import infamy
|
||||||
@@ -164,22 +168,22 @@ with infamy.Test() as test:
|
|||||||
ns.addip("10.0.0.1")
|
ns.addip("10.0.0.1")
|
||||||
|
|
||||||
# Fixed mode tests
|
# Fixed mode tests
|
||||||
with test.step("Set fixed 10/full"):
|
with test.step("Verify fixed 10/full"):
|
||||||
set_host_speed_duplex(hdata, 10, "full")
|
set_host_speed_duplex(hdata, 10, "full")
|
||||||
set_target_speed_duplex(target, tdata, 10, "full")
|
set_target_speed_duplex(target, tdata, 10, "full")
|
||||||
verify_speed_duplex(target, ns, tdata, 10, "full")
|
verify_speed_duplex(target, ns, tdata, 10, "full")
|
||||||
|
|
||||||
with test.step("Set fixed 10/half"):
|
with test.step("Verify fixed 10/half"):
|
||||||
set_host_speed_duplex(hdata, 10, "half")
|
set_host_speed_duplex(hdata, 10, "half")
|
||||||
set_target_speed_duplex(target, tdata, 10, "half")
|
set_target_speed_duplex(target, tdata, 10, "half")
|
||||||
verify_speed_duplex(target, ns, tdata, 10, "half")
|
verify_speed_duplex(target, ns, tdata, 10, "half")
|
||||||
|
|
||||||
with test.step("Set fixed 100/full"):
|
with test.step("Verify fixed 100/full"):
|
||||||
set_host_speed_duplex(hdata, 100, "full")
|
set_host_speed_duplex(hdata, 100, "full")
|
||||||
set_target_speed_duplex(target, tdata, 100, "full")
|
set_target_speed_duplex(target, tdata, 100, "full")
|
||||||
verify_speed_duplex(target, ns, tdata, 100, "full")
|
verify_speed_duplex(target, ns, tdata, 100, "full")
|
||||||
|
|
||||||
with test.step("Set fixed 100/half"):
|
with test.step("Verify fixed 100/half"):
|
||||||
set_host_speed_duplex(hdata, 100, "half")
|
set_host_speed_duplex(hdata, 100, "half")
|
||||||
set_target_speed_duplex(target, tdata, 100, "half")
|
set_target_speed_duplex(target, tdata, 100, "half")
|
||||||
verify_speed_duplex(target, ns, tdata, 100, "half")
|
verify_speed_duplex(target, ns, tdata, 100, "half")
|
||||||
@@ -189,27 +193,27 @@ with infamy.Test() as test:
|
|||||||
enable_host_autoneg(hdata)
|
enable_host_autoneg(hdata)
|
||||||
enable_target_autoneg(target, tdata)
|
enable_target_autoneg(target, tdata)
|
||||||
|
|
||||||
with test.step("Configure host to advertise 10/Full only"):
|
with test.step("Verify auto-negotiation to 10/Full only"):
|
||||||
advertise_host_modes(hdata, ["10full"])
|
advertise_host_modes(hdata, ["10full"])
|
||||||
verify_speed_duplex(target, ns, tdata, 10, "full")
|
verify_speed_duplex(target, ns, tdata, 10, "full")
|
||||||
|
|
||||||
with test.step("Configure host to advertise 10/Half only"):
|
with test.step("Verify auto-negotiation to 10/Half only"):
|
||||||
advertise_host_modes(hdata, ["10half"])
|
advertise_host_modes(hdata, ["10half"])
|
||||||
verify_speed_duplex(target, ns, tdata, 10, "half")
|
verify_speed_duplex(target, ns, tdata, 10, "half")
|
||||||
|
|
||||||
with test.step("Configure host to advertise 100/Full only"):
|
with test.step("Verify auto-negotiation to 100/Full only"):
|
||||||
advertise_host_modes(hdata, ["100full"])
|
advertise_host_modes(hdata, ["100full"])
|
||||||
verify_speed_duplex(target, ns, tdata, 100, "full")
|
verify_speed_duplex(target, ns, tdata, 100, "full")
|
||||||
|
|
||||||
with test.step("Configure host to advertise 100/Half only"):
|
with test.step("Verify auto-negotiation to 100/Half only"):
|
||||||
advertise_host_modes(hdata, ["100half"])
|
advertise_host_modes(hdata, ["100half"])
|
||||||
verify_speed_duplex(target, ns, tdata, 100, "half")
|
verify_speed_duplex(target, ns, tdata, 100, "half")
|
||||||
|
|
||||||
with test.step("Configure host to advertise 10/half + 10/full + 100/half"):
|
with test.step("Verify auto-negotiation to 10/half + 10/full + 100/half"):
|
||||||
advertise_host_modes(hdata, ["10half", "10full", "100half"])
|
advertise_host_modes(hdata, ["10half", "10full", "100half"])
|
||||||
verify_speed_duplex(target, ns, tdata, 100, "half")
|
verify_speed_duplex(target, ns, tdata, 100, "half")
|
||||||
|
|
||||||
with test.step("Configure host to advertise 10/half + 10/full + 100/half + 100/full + 1000/full"):
|
with test.step("Verify auto-negotiation to 10/half + 10/full + 100/half + 100/full + 1000/full"):
|
||||||
advertise_host_modes(hdata, ["10half", "10full", "100half", "100full", "1000full"])
|
advertise_host_modes(hdata, ["10half", "10full", "100half", "100full", "1000full"])
|
||||||
verify_speed_duplex(target, ns, tdata, 1000, "full")
|
verify_speed_duplex(target, ns, tdata, 1000, "full")
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
container_host_commands.adoc
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
=== Host Command Execution from Container
|
||||||
|
==== Description
|
||||||
|
This test verifies that a container running on Infix can execute commands
|
||||||
|
that affect the host system. Specifically, it confirms that the container
|
||||||
|
can change the hostname of the host.
|
||||||
|
|
||||||
|
==== Topology
|
||||||
|
ifdef::topdoc[]
|
||||||
|
image::{topdoc}../../test/case/infix_containers/container_host_commands/topology.svg[Host Command Execution from Container topology]
|
||||||
|
endif::topdoc[]
|
||||||
|
ifndef::topdoc[]
|
||||||
|
ifdef::testgroup[]
|
||||||
|
image::container_host_commands/topology.svg[Host Command Execution from Container topology]
|
||||||
|
endif::testgroup[]
|
||||||
|
ifndef::testgroup[]
|
||||||
|
image::topology.svg[Host Command Execution from Container topology]
|
||||||
|
endif::testgroup[]
|
||||||
|
endif::topdoc[]
|
||||||
|
==== Test sequence
|
||||||
|
. Set up topology and attach to target DUT
|
||||||
|
. Set initial hostname
|
||||||
|
. Verify initial hostname in operational
|
||||||
|
. Include script in OCI image to modify host hostname
|
||||||
|
. Verify container has started
|
||||||
|
. Verify the new hostname set by the container
|
||||||
|
|
||||||
|
|
||||||
|
<<<
|
||||||
|
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||||
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
|
||||||
|
<!-- Title: 1x1 Pages: 1 -->
|
||||||
|
<svg width="424pt" height="45pt"
|
||||||
|
viewBox="0.00 0.00 424.03 45.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 41)">
|
||||||
|
<title>1x1</title>
|
||||||
|
<polygon fill="white" stroke="transparent" points="-4,4 -4,-41 420.03,-41 420.03,4 -4,4"/>
|
||||||
|
<!-- host -->
|
||||||
|
<g id="node1" class="node">
|
||||||
|
<title>host</title>
|
||||||
|
<polygon fill="none" stroke="black" points="0,-0.5 0,-36.5 100,-36.5 100,-0.5 0,-0.5"/>
|
||||||
|
<text text-anchor="middle" x="25" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">host</text>
|
||||||
|
<polyline fill="none" stroke="black" points="50,-0.5 50,-36.5 "/>
|
||||||
|
<text text-anchor="middle" x="75" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||||
|
</g>
|
||||||
|
<!-- target -->
|
||||||
|
<g id="node2" class="node">
|
||||||
|
<title>target</title>
|
||||||
|
<polygon fill="none" stroke="black" points="300.03,-0.5 300.03,-36.5 416.03,-36.5 416.03,-0.5 300.03,-0.5"/>
|
||||||
|
<text text-anchor="middle" x="325.03" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||||
|
<polyline fill="none" stroke="black" points="350.03,-0.5 350.03,-36.5 "/>
|
||||||
|
<text text-anchor="middle" x="383.03" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">target</text>
|
||||||
|
</g>
|
||||||
|
<!-- host--target -->
|
||||||
|
<g id="edge1" class="edge">
|
||||||
|
<title>host:mgmt--target:mgmt</title>
|
||||||
|
<path fill="none" stroke="lightgray" stroke-width="2" d="M100,-18.5C100,-18.5 300.03,-18.5 300.03,-18.5"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.6 KiB |
Executable
+269
@@ -0,0 +1,269 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
usage()
|
||||||
|
{
|
||||||
|
cat <<EOF
|
||||||
|
usage: $0 COMMAND [ARGS...]
|
||||||
|
|
||||||
|
Update contents of Infix images
|
||||||
|
|
||||||
|
Commands:
|
||||||
|
|
||||||
|
unpack PKG KEY-DIR DIR
|
||||||
|
|
||||||
|
Unpack the RAUC bundle PKG and the root filesystem contained in
|
||||||
|
it, using the keys stored in KEY-DIR, and store the results in
|
||||||
|
DIR.
|
||||||
|
|
||||||
|
pack DIR [KEY-DIR] PKG
|
||||||
|
|
||||||
|
Repackage the (possibly modified) root filesystem in DIR, updating
|
||||||
|
all signatures as necessary using the keys stored in KEY-DIR (or
|
||||||
|
the keys used to unpack the bundle, if not specified) and store
|
||||||
|
the resulting bundle in PKG.
|
||||||
|
|
||||||
|
exec DIR COMMAND [ARGS...]
|
||||||
|
|
||||||
|
Run COMMAND, possibly with ARGS, from the root of the filesystem
|
||||||
|
in DIR, inside of a fakeroot context that allows otherwise
|
||||||
|
privileged operations such as ownership modifications.
|
||||||
|
|
||||||
|
help
|
||||||
|
|
||||||
|
Show this message and exit.
|
||||||
|
|
||||||
|
Key directories:
|
||||||
|
|
||||||
|
KEY-DIR arguments must reference a directory that contains the
|
||||||
|
public/private keypair used to verify/sign an image. Most commonly,
|
||||||
|
board/common/signing-keys/development from the Infix source tree is
|
||||||
|
used to validate the input image.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
Include a custom file inside a prebuilt Infix image, assign it to
|
||||||
|
the UID/GID 1337; and package up the results, signing it with the
|
||||||
|
same developer key that was used to create it:
|
||||||
|
|
||||||
|
ixbin unpack infix-aarch64.pkg ~/infix/board/common/signing-keys/development tmp
|
||||||
|
cp VBRUN300.DLL tmp/rootfs/lib/
|
||||||
|
ixbin exec tmp chown 1337:1337 lib/VBRUN300.DLL
|
||||||
|
ixbin pack tmp infix-vb3-aarch64.pkg
|
||||||
|
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
msg()
|
||||||
|
{
|
||||||
|
printf "\e[37;44mixbin: %-80s\e[0m\n" "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
err()
|
||||||
|
{
|
||||||
|
printf "\e[37;41mixbin: ERROR: %-73s\e[0m\n" "$*" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
die()
|
||||||
|
{
|
||||||
|
err "$*"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
ensuredeps()
|
||||||
|
{
|
||||||
|
local DEPS="fakeroot mksquashfs unsquashfs awk env mkimage truncate dtc fdtget rauc"
|
||||||
|
local missing=
|
||||||
|
|
||||||
|
for dep in $DEPS; do
|
||||||
|
command -v $dep >/dev/null && continue
|
||||||
|
missing="$missing $dep"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -n "$missing" ]; then
|
||||||
|
die "Missing dependencies:$missing"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
squnpack()
|
||||||
|
{
|
||||||
|
local sq="$WORKDIR"/pkg/rootfs.img
|
||||||
|
|
||||||
|
# Capture the original compression algo and block size for when we
|
||||||
|
# resquash it later on.
|
||||||
|
unsquashfs -s "$sq" | awk '
|
||||||
|
/^Compression/ { printf(" -comp %s", $2); }
|
||||||
|
/^Block size/ { printf(" -b %s", $3); }
|
||||||
|
' >"$WORKDIR"/mksquash-opts
|
||||||
|
|
||||||
|
$FAKEROOT unsquashfs -d "$WORKDIR"/rootfs "$sq"
|
||||||
|
}
|
||||||
|
|
||||||
|
sqexec()
|
||||||
|
{
|
||||||
|
$FAKEROOT env -C "$WORKDIR"/rootfs "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
sqpack()
|
||||||
|
{
|
||||||
|
$FAKEROOT mksquashfs "$WORKDIR"/rootfs "$WORKDIR"/pkg/rootfs.img \
|
||||||
|
$(cat "$WORKDIR"/mksquash-opts) -noappend "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
sqsign()
|
||||||
|
{
|
||||||
|
local its="$1"
|
||||||
|
local keys="$2"
|
||||||
|
local hsize="$3"
|
||||||
|
local out="$4"
|
||||||
|
|
||||||
|
mkimage -E -p "$hsize" -B "$hsize" -k "$keys" -f "$its" "$WORKDIR"/sign.itb
|
||||||
|
truncate -s $(($hsize)) "$WORKDIR"/sign.itb
|
||||||
|
mv "$WORKDIR"/sign.itb "$out"
|
||||||
|
}
|
||||||
|
|
||||||
|
sqresign()
|
||||||
|
{
|
||||||
|
local keys="$1"
|
||||||
|
local sq="$WORKDIR"/pkg/rootfs.img
|
||||||
|
local itbh="$WORKDIR"/pkg/rootfs.itbh
|
||||||
|
|
||||||
|
signsize=$(printf '0x%x' $(fdtget "$itbh" /images/rootfs data-position))
|
||||||
|
|
||||||
|
dtc -I dtb -O dts "$itbh" | awk -v sq="$sq" '
|
||||||
|
/timestamp =/ || /data-\w+ =/ || /signer-\w+ =/ || /value =/{
|
||||||
|
/* Remove old signature */
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/compression = "none"/ {
|
||||||
|
/* Splice in reference to the squash */
|
||||||
|
print;
|
||||||
|
sub("compression", "data");
|
||||||
|
sub("\"none\"", sprintf("/incbin/(\"%s\")", sq));
|
||||||
|
print;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Keep the rest as-is */
|
||||||
|
print;
|
||||||
|
};
|
||||||
|
' >"$WORKDIR"/resign.its
|
||||||
|
|
||||||
|
sqsign "$WORKDIR"/resign.its "$keys" "$signsize" "$itbh"
|
||||||
|
}
|
||||||
|
|
||||||
|
unpack()
|
||||||
|
{
|
||||||
|
local pkg="$1"
|
||||||
|
local keys="$2"
|
||||||
|
WORKDIR=$(readlink -f "$3")
|
||||||
|
|
||||||
|
case "$#" in
|
||||||
|
3)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: ixbin unpack PKG KEYS DIR" >&2
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
|
||||||
|
local crt=$(ls "$keys"/*.crt | head -n1)
|
||||||
|
[ -r "$crt" ] || die "No public key found in $keys"
|
||||||
|
|
||||||
|
msg "Setting up working directory"
|
||||||
|
mkdir -p "$WORKDIR"
|
||||||
|
cp -a "$keys" "$WORKDIR"/in-keys
|
||||||
|
|
||||||
|
touch "$WORKDIR"/fakeroot-state
|
||||||
|
FAKEROOT="fakeroot -i $WORKDIR/fakeroot-state -s $WORKDIR/fakeroot-state"
|
||||||
|
|
||||||
|
msg "Unpacking RAUC bundle"
|
||||||
|
rauc --keyring="$crt" extract "$pkg" "$WORKDIR"/pkg
|
||||||
|
msg "Unpacking Squash filesystem"
|
||||||
|
squnpack
|
||||||
|
msg "OK, $WORKDIR/rootfs can now be modified"
|
||||||
|
}
|
||||||
|
|
||||||
|
run()
|
||||||
|
{
|
||||||
|
WORKDIR=$(readlink -f "$1")
|
||||||
|
shift
|
||||||
|
|
||||||
|
[ -r "$WORKDIR"/fakeroot-state ] || \
|
||||||
|
die "$WORKDIR does not contain an unpacked image"
|
||||||
|
FAKEROOT="fakeroot -i $WORKDIR/fakeroot-state -s $WORKDIR/fakeroot-state"
|
||||||
|
|
||||||
|
sqexec "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
pack()
|
||||||
|
{
|
||||||
|
WORKDIR=$(readlink -f "$1")
|
||||||
|
local keys="$2"
|
||||||
|
local pkg="$3"
|
||||||
|
|
||||||
|
case "$#" in
|
||||||
|
3)
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
keys="$WORKDIR"/in-keys
|
||||||
|
pkg="$2"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: ixbin pack DIR [KEYS] DIR" >&2
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
|
||||||
|
[ -r "$WORKDIR"/fakeroot-state ] || \
|
||||||
|
die "$WORKDIR does not contain an unpacked image"
|
||||||
|
|
||||||
|
local crt=$(ls "$keys"/*.crt | head -n1)
|
||||||
|
[ -r "$crt" ] || die "No public key found in $keys"
|
||||||
|
|
||||||
|
local key=$(ls "$keys"/*.key | head -n1)
|
||||||
|
[ -r "$crt" ] || die "No private key found in $keys"
|
||||||
|
|
||||||
|
FAKEROOT="fakeroot -i $WORKDIR/fakeroot-state -s $WORKDIR/fakeroot-state"
|
||||||
|
|
||||||
|
msg "Packing up Squash filesystem"
|
||||||
|
sqpack
|
||||||
|
[ -f "$WORKDIR"/pkg/rootfs.itbh ] && {
|
||||||
|
msg "Updating Squash filesystem signature"
|
||||||
|
sqresign "$keys"
|
||||||
|
}
|
||||||
|
|
||||||
|
msg "Creating RAUC bundle"
|
||||||
|
rauc --keyring="$crt" --cert="$crt" --key="$key" bundle "$WORKDIR"/pkg "$pkg"
|
||||||
|
msg "OK, updated bundle available in $pkg"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $# -lt 1 ]; then
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cmd="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
case "$cmd" in
|
||||||
|
unpack)
|
||||||
|
ensuredeps
|
||||||
|
unpack "$@"
|
||||||
|
;;
|
||||||
|
"exec")
|
||||||
|
ensuredeps
|
||||||
|
run "$@"
|
||||||
|
;;
|
||||||
|
pack)
|
||||||
|
ensuredeps
|
||||||
|
pack "$@"
|
||||||
|
;;
|
||||||
|
help)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
die "Unknown command \"$cmd\""
|
||||||
|
;;
|
||||||
|
esac
|
||||||
Reference in New Issue
Block a user