github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/fanal/analyzer/imgconf/apk/apk_test.go (about) 1 package apk 2 3 import ( 4 "context" 5 "encoding/json" 6 "net/http" 7 "net/http/httptest" 8 "os" 9 "reflect" 10 "sort" 11 "testing" 12 "time" 13 14 v1 "github.com/google/go-containerregistry/pkg/v1" 15 "github.com/kylelemons/godebug/pretty" 16 "github.com/samber/lo" 17 "github.com/stretchr/testify/assert" 18 "github.com/stretchr/testify/require" 19 20 "github.com/devseccon/trivy/pkg/fanal/analyzer" 21 "github.com/devseccon/trivy/pkg/fanal/types" 22 ) 23 24 var ( 25 oldAlpineConfig = &v1.ConfigFile{ 26 Architecture: "amd64", 27 Container: "f5b08762ace1af069127a337579acd51c415b919d736e6615b453a3c6fbf260d", 28 Created: v1.Time{ 29 Time: time.Date(2018, time.October, 15, 21, 28, 53, 798628678, time.UTC), 30 }, 31 DockerVersion: "17.06.2-ce", 32 History: []v1.History{ 33 { 34 Created: v1.Time{ 35 Time: time.Date(2018, time.September, 11, 22, 19, 38, 885299940, time.UTC), 36 }, 37 CreatedBy: "/bin/sh -c #(nop) ADD file:49f9e47e678d868d5b023482aa8dded71276a241a665c4f8b55ca77269321b34 in / ", 38 }, 39 { 40 Created: v1.Time{ 41 Time: time.Date(2018, time.September, 11, 22, 19, 39, 58628442, time.UTC), 42 }, 43 CreatedBy: "/bin/sh -c #(nop) CMD [\"/bin/sh\"]", 44 EmptyLayer: true, 45 }, 46 { 47 Created: v1.Time{ 48 Time: time.Date(2018, time.September, 12, 1, 26, 59, 951316015, time.UTC), 49 }, 50 CreatedBy: "/bin/sh -c #(nop) ENV PHPIZE_DEPS=autoconf \t\tdpkg-dev dpkg \t\tfile \t\tg++ \t\tgcc \t\tlibc-dev \t\tmake \t\tpkgconf \t\tre2c", 51 EmptyLayer: true, 52 }, 53 { 54 Created: v1.Time{ 55 Time: time.Date(2018, time.September, 12, 1, 27, 1, 470388635, time.UTC), 56 }, 57 CreatedBy: "/bin/sh -c apk add --no-cache --virtual .persistent-deps \t\tca-certificates \t\tcurl \t\ttar \t\txz \t\tlibressl", 58 }, 59 { 60 Created: v1.Time{ 61 Time: time.Date(2018, time.September, 12, 1, 27, 2, 432381785, time.UTC), 62 }, 63 CreatedBy: "/bin/sh -c set -x \t&& addgroup -g 82 -S www-data \t&& adduser -u 82 -D -S -G www-data www-data", 64 }, 65 { 66 Created: v1.Time{ 67 Time: time.Date(2018, time.September, 12, 1, 27, 2, 715120309, time.UTC), 68 }, 69 CreatedBy: "/bin/sh -c #(nop) ENV PHP_INI_DIR=/usr/local/etc/php", 70 EmptyLayer: true, 71 }, 72 { 73 Created: v1.Time{ 74 Time: time.Date(2018, time.September, 12, 1, 27, 3, 655421341, time.UTC), 75 }, 76 CreatedBy: "/bin/sh -c mkdir -p $PHP_INI_DIR/conf.d", 77 }, 78 { 79 Created: v1.Time{ 80 Time: time.Date(2018, time.September, 12, 1, 27, 3, 931799562, time.UTC), 81 }, 82 CreatedBy: "/bin/sh -c #(nop) ENV PHP_CFLAGS=-fstack-protector-strong -fpic -fpie -O2", 83 EmptyLayer: true, 84 }, 85 { 86 Created: v1.Time{ 87 Time: time.Date(2018, time.September, 12, 1, 27, 4, 210945499, time.UTC), 88 }, 89 CreatedBy: "/bin/sh -c #(nop) ENV PHP_CPPFLAGS=-fstack-protector-strong -fpic -fpie -O2", 90 EmptyLayer: true, 91 }, 92 { 93 Created: v1.Time{ 94 Time: time.Date(2018, time.September, 12, 1, 27, 4, 523116501, time.UTC), 95 }, 96 CreatedBy: "/bin/sh -c #(nop) ENV PHP_LDFLAGS=-Wl,-O1 -Wl,--hash-style=both -pie", 97 EmptyLayer: true, 98 }, 99 { 100 Created: v1.Time{ 101 Time: time.Date(2018, time.September, 12, 1, 27, 4, 795176159, time.UTC), 102 }, 103 CreatedBy: "/bin/sh -c #(nop) ENV GPG_KEYS=1729F83938DA44E27BA0F4D3DBDB397470D12172 B1B44D8F021E4E2D6021E995DC9FF8D3EE5AF27F", 104 EmptyLayer: true, 105 }, 106 { 107 Created: v1.Time{ 108 Time: time.Date(2018, time.October, 15, 19, 2, 18, 415761689, time.UTC), 109 }, 110 CreatedBy: "/bin/sh -c #(nop) ENV PHP_VERSION=7.2.11", 111 EmptyLayer: true, 112 }, 113 { 114 Created: v1.Time{ 115 Time: time.Date(2018, time.October, 15, 19, 2, 18, 599097853, time.UTC), 116 }, 117 CreatedBy: "/bin/sh -c #(nop) ENV PHP_URL=https://secure.php.net/get/php-7.2.11.tar.xz/from/this/mirror PHP_ASC_URL=https://secure.php.net/get/php-7.2.11.tar.xz.asc/from/this/mirror", 118 EmptyLayer: true, 119 }, 120 { 121 Created: v1.Time{ 122 Time: time.Date(2018, time.October, 15, 19, 2, 18, 782890412, time.UTC), 123 }, 124 CreatedBy: "/bin/sh -c #(nop) ENV PHP_SHA256=da1a705c0bc46410e330fc6baa967666c8cd2985378fb9707c01a8e33b01d985 PHP_MD5=", 125 EmptyLayer: true, 126 }, 127 { 128 Created: v1.Time{ 129 Time: time.Date(2018, time.October, 15, 19, 2, 22, 795846753, time.UTC), 130 }, 131 CreatedBy: "/bin/sh -c set -xe; \t\tapk add --no-cache --virtual .fetch-deps \t\tgnupg \t\twget \t; \t\tmkdir -p /usr/src; \tcd /usr/src; \t\twget -O php.tar.xz \"$PHP_URL\"; \t\tif [ -n \"$PHP_SHA256\" ]; then \t\techo \"$PHP_SHA256 *php.tar.xz\" | sha256sum -c -; \tfi; \tif [ -n \"$PHP_MD5\" ]; then \t\techo \"$PHP_MD5 *php.tar.xz\" | md5sum -c -; \tfi; \t\tif [ -n \"$PHP_ASC_URL\" ]; then \t\twget -O php.tar.xz.asc \"$PHP_ASC_URL\"; \t\texport GNUPGHOME=\"$(mktemp -d)\"; \t\tfor key in $GPG_KEYS; do \t\t\tgpg --keyserver ha.pool.sks-keyservers.net --recv-keys \"$key\"; \t\tdone; \t\tgpg --batch --verify php.tar.xz.asc php.tar.xz; \t\tcommand -v gpgconf > /dev/null && gpgconf --kill all; \t\trm -rf \"$GNUPGHOME\"; \tfi; \t\tapk del .fetch-deps", 132 }, 133 { 134 Created: v1.Time{ 135 Time: time.Date(2018, time.October, 15, 19, 2, 23, 71406376, time.UTC), 136 }, 137 CreatedBy: "/bin/sh -c #(nop) COPY file:207c686e3fed4f71f8a7b245d8dcae9c9048d276a326d82b553c12a90af0c0ca in /usr/local/bin/ ", 138 }, 139 { 140 Created: v1.Time{ 141 Time: time.Date(2018, time.October, 15, 19, 7, 13, 93396680, time.UTC), 142 }, 143 CreatedBy: "/bin/sh -c set -xe \t&& apk add --no-cache --virtual .build-deps \t\t$PHPIZE_DEPS \t\tcoreutils \t\tcurl-dev \t\tlibedit-dev \t\tlibressl-dev \t\tlibsodium-dev \t\tlibxml2-dev \t\tsqlite-dev \t\t&& export CFLAGS=\"$PHP_CFLAGS\" \t\tCPPFLAGS=\"$PHP_CPPFLAGS\" \t\tLDFLAGS=\"$PHP_LDFLAGS\" \t&& docker-php-source extract \t&& cd /usr/src/php \t&& gnuArch=\"$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)\" \t&& ./configure \t\t--build=\"$gnuArch\" \t\t--with-config-file-path=\"$PHP_INI_DIR\" \t\t--with-config-file-scan-dir=\"$PHP_INI_DIR/conf.d\" \t\t\t\t--enable-option-checking=fatal \t\t\t\t--with-mhash \t\t\t\t--enable-ftp \t\t--enable-mbstring \t\t--enable-mysqlnd \t\t--with-sodium=shared \t\t\t\t--with-curl \t\t--with-libedit \t\t--with-openssl \t\t--with-zlib \t\t\t\t$(test \"$gnuArch\" = 's390x-linux-gnu' && echo '--without-pcre-jit') \t\t\t\t$PHP_EXTRA_CONFIGURE_ARGS \t&& make -j \"$(nproc)\" \t&& make install \t&& { find /usr/local/bin /usr/local/sbin -type f -perm +0111 -exec strip --strip-all '{}' + || true; } \t&& make clean \t\t&& cp -v php.ini-* \"$PHP_INI_DIR/\" \t\t&& cd / \t&& docker-php-source delete \t\t&& runDeps=\"$( \t\tscanelf --needed --nobanner --format '%n#p' --recursive /usr/local \t\t\t| tr ',' '\\n' \t\t\t| sort -u \t\t\t| awk 'system(\"[ -e /usr/local/lib/\" $1 \" ]\") == 0 { next } { print \"so:\" $1 }' \t)\" \t&& apk add --no-cache --virtual .php-rundeps $runDeps \t\t&& apk del .build-deps \t\t&& pecl update-channels \t&& rm -rf /tmp/pear ~/.pearrc", 144 }, 145 { 146 Created: v1.Time{ 147 Time: time.Date(2018, time.October, 15, 19, 7, 13, 722586262, time.UTC), 148 }, 149 CreatedBy: "/bin/sh -c #(nop) COPY multi:2cdcedabcf5a3b9ae610fab7848e94bc2f64b4d85710d55fd6f79e44dacf73d8 in /usr/local/bin/ ", 150 }, 151 { 152 Created: v1.Time{ 153 Time: time.Date(2018, time.October, 15, 19, 7, 14, 618087104, time.UTC), 154 }, 155 CreatedBy: "/bin/sh -c docker-php-ext-enable sodium", 156 }, 157 { 158 Created: v1.Time{ 159 Time: time.Date(2018, time.October, 15, 19, 7, 14, 826981756, time.UTC), 160 }, 161 CreatedBy: "/bin/sh -c #(nop) ENTRYPOINT [\"docker-php-entrypoint\"]", 162 EmptyLayer: true, 163 }, 164 { 165 Created: v1.Time{ 166 Time: time.Date(2018, time.October, 15, 19, 7, 15, 10831572, time.UTC), 167 }, 168 CreatedBy: "/bin/sh -c #(nop) CMD [\"php\" \"-a\"]", 169 EmptyLayer: true, 170 }, 171 { 172 Created: v1.Time{ 173 Time: time.Date(2018, time.October, 15, 21, 28, 21, 919735971, time.UTC), 174 }, 175 CreatedBy: "/bin/sh -c apk --no-cache add git subversion openssh mercurial tini bash patch", 176 }, 177 { 178 Created: v1.Time{ 179 Time: time.Date(2018, time.October, 15, 21, 28, 22, 611763893, time.UTC), 180 }, 181 CreatedBy: "/bin/sh -c echo \"memory_limit=-1\" > \"$PHP_INI_DIR/conf.d/memory-limit.ini\" && echo \"date.timezone=${PHP_TIMEZONE:-UTC}\" > \"$PHP_INI_DIR/conf.d/date_timezone.ini\"", 182 }, 183 { 184 Created: v1.Time{ 185 Time: time.Date(2018, time.October, 15, 21, 28, 50, 224278478, time.UTC), 186 }, 187 CreatedBy: "/bin/sh -c apk add --no-cache --virtual .build-deps zlib-dev && docker-php-ext-install zip && runDeps=\"$( scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions | tr ',' '\\n' | sort -u | awk 'system(\"[ -e /usr/local/lib/\" $1 \" ]\") == 0 { next } { print \"so:\" $1 }' )\" && apk add --virtual .composer-phpext-rundeps $runDeps && apk del .build-deps", 188 }, 189 { 190 Created: v1.Time{ 191 Time: time.Date(2018, time.October, 15, 21, 28, 50, 503010161, time.UTC), 192 }, 193 CreatedBy: "/bin/sh -c #(nop) ENV COMPOSER_ALLOW_SUPERUSER=1", 194 EmptyLayer: true, 195 }, 196 { 197 Created: v1.Time{ 198 Time: time.Date(2018, time.October, 15, 21, 28, 50, 775378559, time.UTC), 199 }, 200 CreatedBy: "/bin/sh -c #(nop) ENV COMPOSER_HOME=/tmp", 201 EmptyLayer: true, 202 }, 203 { 204 Created: v1.Time{ 205 time.Date(2018, time.October, 15, 21, 28, 51, 35012363, time.UTC), 206 }, 207 CreatedBy: "/bin/sh -c #(nop) ENV COMPOSER_VERSION=1.7.2", 208 EmptyLayer: true, 209 }, 210 { 211 Created: v1.Time{ 212 Time: time.Date(2018, time.October, 15, 21, 28, 52, 491402624, time.UTC), 213 }, 214 CreatedBy: "/bin/sh -c curl --silent --fail --location --retry 3 --output /tmp/installer.php --url https://raw.githubusercontent.com/composer/getcomposer.org/b107d959a5924af895807021fcef4ffec5a76aa9/web/installer && php -r \" \\$signature = '544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061'; \\$hash = hash('SHA384', file_get_contents('/tmp/installer.php')); if (!hash_equals(\\$signature, \\$hash)) { unlink('/tmp/installer.php'); echo 'Integrity check failed, installer is either corrupt or worse.' . PHP_EOL; exit(1); }\" && php /tmp/installer.php --no-ansi --install-dir=/usr/bin --filename=composer --version=${COMPOSER_VERSION} && composer --ansi --version --no-interaction && rm -rf /tmp/* /tmp/.htaccess", 215 }, 216 { 217 Created: v1.Time{ 218 Time: time.Date(2018, time.October, 15, 21, 28, 52, 948859545, time.UTC), 219 }, 220 CreatedBy: "/bin/sh -c #(nop) COPY file:295943a303e8f27de4302b6aa3687bce4b1d1392335efaaab9ecd37bec5ab4c5 in /docker-entrypoint.sh ", 221 }, 222 { 223 Created: v1.Time{ 224 Time: time.Date(2018, time.October, 15, 21, 28, 53, 295399872, time.UTC), 225 }, 226 CreatedBy: "/bin/sh -c #(nop) WORKDIR /app", 227 }, 228 { 229 Created: v1.Time{ 230 Time: time.Date(2018, time.October, 15, 21, 28, 53, 582920705, time.UTC), 231 }, 232 CreatedBy: "/bin/sh -c #(nop) ENTRYPOINT [\"/bin/sh\" \"/docker-entrypoint.sh\"]", 233 EmptyLayer: true, 234 }, 235 { 236 Created: v1.Time{ 237 time.Date(2018, time.October, 15, 21, 28, 53, 798628678, time.UTC), 238 }, 239 CreatedBy: "/bin/sh -c #(nop) CMD [\"composer\"]", 240 EmptyLayer: true, 241 }, 242 }, 243 OS: "linux", 244 RootFS: v1.RootFS{ 245 Type: "layers", 246 DiffIDs: []v1.Hash{ 247 { 248 Algorithm: "sha256", 249 Hex: "ebf12965380b39889c99a9c02e82ba465f887b45975b6e389d42e9e6a3857888", 250 }, 251 { 252 Algorithm: "sha256", 253 Hex: "0ea33a93585cf1917ba522b2304634c3073654062d5282c1346322967790ef33", 254 }, 255 { 256 Algorithm: "sha256", 257 Hex: "9922bc15eeefe1637b803ef2106f178152ce19a391f24aec838cbe2e48e73303", 258 }, 259 { 260 Algorithm: "sha256", 261 Hex: "dc00fbef458ad3204bbb548e2d766813f593d857b845a940a0de76aed94c94d1", 262 }, 263 { 264 Algorithm: "sha256", 265 Hex: "5cb2a5009179b1e78ecfef81a19756328bb266456cf9a9dbbcf9af8b83b735f0", 266 }, 267 { 268 Algorithm: "sha256", 269 Hex: "9bdb2c849099a99c8ab35f6fd7469c623635e8f4479a0a5a3df61e22bae509f6", 270 }, 271 { 272 Algorithm: "sha256", 273 Hex: "6408527580eade39c2692dbb6b0f6a9321448d06ea1c2eef06bb7f37da9c5013", 274 }, 275 { 276 Algorithm: "sha256", 277 Hex: "83abef706f5ae199af65d1c13d737d0eb36219f0d18e36c6d8ff06159df39a63", 278 }, 279 { 280 Algorithm: "sha256", 281 Hex: "c03283c257abd289a30b4f5e9e1345da0e9bfdc6ca398ee7e8fac6d2c1456227", 282 }, 283 { 284 Algorithm: "sha256", 285 Hex: "2da3602d664dd3f71fae83cbc566d4e80b432c6ee8bb4efd94c8e85122f503d4", 286 }, 287 { 288 Algorithm: "sha256", 289 Hex: "82c59ac8ee582542648e634ca5aff9a464c68ff8a054f105a58689fb52209e34", 290 }, 291 { 292 Algorithm: "sha256", 293 Hex: "2f4a5c9187c249834ebc28783bd3c65bdcbacaa8baa6620ddaa27846dd3ef708", 294 }, 295 { 296 Algorithm: "sha256", 297 Hex: "6ca56f561e677ae06c3bc87a70792642d671a4416becb9a101577c1a6e090e36", 298 }, 299 { 300 Algorithm: "sha256", 301 Hex: "154ad0735c360b212b167f424d33a62305770a1fcfb6363882f5c436cfbd9812", 302 }, 303 { 304 Algorithm: "sha256", 305 Hex: "b2a1a2d80bf0c747a4f6b0ca6af5eef23f043fcdb1ed4f3a3e750aef2dc68079", 306 }, 307 }, 308 }, 309 Config: v1.Config{ 310 Cmd: []string{"composer"}, 311 Entrypoint: []string{ 312 "/bin/sh", 313 "/docker-entrypoint.sh", 314 }, 315 Env: []string{ 316 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 317 "PHPIZE_DEPS=autoconf \t\tdpkg-dev dpkg \t\tfile \t\tg++ \t\tgcc \t\tlibc-dev \t\tmake \t\tpkgconf \t\tre2c", 318 "PHP_INI_DIR=/usr/local/etc/php", 319 "PHP_CFLAGS=-fstack-protector-strong -fpic -fpie -O2", 320 "PHP_CPPFLAGS=-fstack-protector-strong -fpic -fpie -O2", 321 "PHP_LDFLAGS=-Wl,-O1 -Wl,--hash-style=both -pie", 322 "GPG_KEYS=1729F83938DA44E27BA0F4D3DBDB397470D12172 B1B44D8F021E4E2D6021E995DC9FF8D3EE5AF27F", 323 "PHP_VERSION=7.2.11", 324 "PHP_URL=https://secure.php.net/get/php-7.2.11.tar.xz/from/this/mirror", 325 "PHP_ASC_URL=https://secure.php.net/get/php-7.2.11.tar.xz.asc/from/this/mirror", 326 "PHP_SHA256=da1a705c0bc46410e330fc6baa967666c8cd2985378fb9707c01a8e33b01d985", 327 "PHP_MD5=", 328 "COMPOSER_ALLOW_SUPERUSER=1", 329 "COMPOSER_HOME=/tmp", 330 "COMPOSER_VERSION=1.7.2", 331 }, 332 Image: "sha256:ad8c55ed62ca1f439bd600c7251de347926ca901ab7f52a93d8fba743ef397c6", 333 WorkingDir: "/app", 334 ArgsEscaped: true, 335 }, 336 } 337 338 alpineConfig = &v1.ConfigFile{ 339 Architecture: "amd64", 340 Container: "47d9d33b3d5abb0316dba1a0bfcbc12a6fa88d98ad30170c41d30718003de82e", 341 Created: v1.Time{Time: time.Date(2019, time.May, 11, 5, 10, 20, 331457195, time.UTC)}, 342 DockerVersion: "18.06.1-ce", 343 History: []v1.History{ 344 { 345 Created: v1.Time{Time: time.Date(2019, time.May, 11, 0, 7, 3, 358250803, time.UTC)}, 346 CreatedBy: "/bin/sh -c #(nop) ADD file:a86aea1f3a7d68f6ae03397b99ea77f2e9ee901c5c59e59f76f93adbb4035913 in / ", 347 }, 348 { 349 Created: v1.Time{Time: time.Date(2019, time.May, 11, 0, 7, 3, 510395965, time.UTC)}, 350 CreatedBy: "/bin/sh -c #(nop) CMD [\"/bin/sh\"]", 351 EmptyLayer: true, 352 }, 353 { 354 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 4, 43, 80069360, time.UTC)}, 355 CreatedBy: "/bin/sh -c #(nop) ENV PHPIZE_DEPS=autoconf \t\tdpkg-dev dpkg \t\tfile \t\tg++ \t\tgcc \t\tlibc-dev \t\tmake \t\tpkgconf \t\tre2c", 356 EmptyLayer: true, 357 }, 358 { 359 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 4, 44, 655269947, time.UTC)}, 360 CreatedBy: "/bin/sh -c apk add --no-cache \t\tca-certificates \t\tcurl \t\ttar \t\txz \t\topenssl", 361 }, 362 { 363 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 4, 45, 787769041, time.UTC)}, 364 CreatedBy: "/bin/sh -c set -x \t&& addgroup -g 82 -S www-data \t&& adduser -u 82 -D -S -G www-data www-data", 365 }, 366 { 367 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 4, 46, 47800659, time.UTC)}, 368 CreatedBy: "/bin/sh -c #(nop) ENV PHP_INI_DIR=/usr/local/etc/php", 369 EmptyLayer: true, 370 }, 371 { 372 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 4, 47, 131691293, time.UTC)}, 373 CreatedBy: "/bin/sh -c set -eux; \tmkdir -p \"$PHP_INI_DIR/conf.d\"; \t[ ! -d /var/www/html ]; \tmkdir -p /var/www/html; \tchown www-data:www-data /var/www/html; \tchmod 777 /var/www/html", 374 }, 375 { 376 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 4, 47, 360137598, time.UTC)}, 377 CreatedBy: "/bin/sh -c #(nop) ENV PHP_CFLAGS=-fstack-protector-strong -fpic -fpie -O2", 378 EmptyLayer: true, 379 }, 380 { 381 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 4, 47, 624002469, time.UTC)}, 382 CreatedBy: "/bin/sh -c #(nop) ENV PHP_CPPFLAGS=-fstack-protector-strong -fpic -fpie -O2", 383 EmptyLayer: true, 384 }, 385 { 386 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 4, 47, 823552655, time.UTC)}, 387 CreatedBy: "/bin/sh -c #(nop) ENV PHP_LDFLAGS=-Wl,-O1 -Wl,--hash-style=both -pie", 388 EmptyLayer: true, 389 }, 390 { 391 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 4, 48, 90975339, time.UTC)}, 392 CreatedBy: "/bin/sh -c #(nop) ENV GPG_KEYS=CBAF69F173A0FEA4B537F470D66C9593118BCCB6 F38252826ACD957EF380D39F2F7956BC5DA04B5D", 393 EmptyLayer: true, 394 }, 395 { 396 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 4, 48, 311134986, time.UTC)}, 397 CreatedBy: "/bin/sh -c #(nop) ENV PHP_VERSION=7.3.5", 398 EmptyLayer: true, 399 }, 400 { 401 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 4, 48, 546724822, time.UTC)}, 402 CreatedBy: "/bin/sh -c #(nop) ENV PHP_URL=https://www.php.net/get/php-7.3.5.tar.xz/from/this/mirror PHP_ASC_URL=https://www.php.net/get/php-7.3.5.tar.xz.asc/from/this/mirror", 403 EmptyLayer: true, 404 }, 405 { 406 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 4, 48, 787069773, time.UTC)}, 407 CreatedBy: "/bin/sh -c #(nop) ENV PHP_SHA256=e1011838a46fd4a195c8453b333916622d7ff5bce4aca2d9d99afac142db2472 PHP_MD5=", 408 EmptyLayer: true, 409 }, 410 { 411 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 4, 54, 588915046, time.UTC)}, 412 CreatedBy: "/bin/sh -c set -xe; \t\tapk add --no-cache --virtual .fetch-deps \t\tgnupg \t\twget \t; \t\tmkdir -p /usr/src; \tcd /usr/src; \t\twget -O php.tar.xz \"$PHP_URL\"; \t\tif [ -n \"$PHP_SHA256\" ]; then \t\techo \"$PHP_SHA256 *php.tar.xz\" | sha256sum -c -; \tfi; \tif [ -n \"$PHP_MD5\" ]; then \t\techo \"$PHP_MD5 *php.tar.xz\" | md5sum -c -; \tfi; \t\tif [ -n \"$PHP_ASC_URL\" ]; then \t\twget -O php.tar.xz.asc \"$PHP_ASC_URL\"; \t\texport GNUPGHOME=\"$(mktemp -d)\"; \t\tfor key in $GPG_KEYS; do \t\t\tgpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys \"$key\"; \t\tdone; \t\tgpg --batch --verify php.tar.xz.asc php.tar.xz; \t\tcommand -v gpgconf > /dev/null && gpgconf --kill all; \t\trm -rf \"$GNUPGHOME\"; \tfi; \t\tapk del --no-network .fetch-deps", 413 }, 414 { 415 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 4, 54, 868883630, time.UTC)}, 416 CreatedBy: "/bin/sh -c #(nop) COPY file:ce57c04b70896f77cc11eb2766417d8a1240fcffe5bba92179ec78c458844110 in /usr/local/bin/ ", 417 }, 418 { 419 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 12, 28, 585346378, time.UTC)}, 420 CreatedBy: "/bin/sh -c set -xe \t&& apk add --no-cache --virtual .build-deps \t\t$PHPIZE_DEPS \t\targon2-dev \t\tcoreutils \t\tcurl-dev \t\tlibedit-dev \t\tlibsodium-dev \t\tlibxml2-dev \t\topenssl-dev \t\tsqlite-dev \t\t&& export CFLAGS=\"$PHP_CFLAGS\" \t\tCPPFLAGS=\"$PHP_CPPFLAGS\" \t\tLDFLAGS=\"$PHP_LDFLAGS\" \t&& docker-php-source extract \t&& cd /usr/src/php \t&& gnuArch=\"$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)\" \t&& ./configure \t\t--build=\"$gnuArch\" \t\t--with-config-file-path=\"$PHP_INI_DIR\" \t\t--with-config-file-scan-dir=\"$PHP_INI_DIR/conf.d\" \t\t\t\t--enable-option-checking=fatal \t\t\t\t--with-mhash \t\t\t\t--enable-ftp \t\t--enable-mbstring \t\t--enable-mysqlnd \t\t--with-password-argon2 \t\t--with-sodium=shared \t\t\t\t--with-curl \t\t--with-libedit \t\t--with-openssl \t\t--with-zlib \t\t\t\t$(test \"$gnuArch\" = 's390x-linux-gnu' && echo '--without-pcre-jit') \t\t\t\t$PHP_EXTRA_CONFIGURE_ARGS \t&& make -j \"$(nproc)\" \t&& find -type f -name '*.a' -delete \t&& make install \t&& { find /usr/local/bin /usr/local/sbin -type f -perm +0111 -exec strip --strip-all '{}' + || true; } \t&& make clean \t\t&& cp -v php.ini-* \"$PHP_INI_DIR/\" \t\t&& cd / \t&& docker-php-source delete \t\t&& runDeps=\"$( \t\tscanelf --needed --nobanner --format '%n#p' --recursive /usr/local \t\t\t| tr ',' '\\n' \t\t\t| sort -u \t\t\t| awk 'system(\"[ -e /usr/local/lib/\" $1 \" ]\") == 0 { next } { print \"so:\" $1 }' \t)\" \t&& apk add --no-cache $runDeps \t\t&& apk del --no-network .build-deps \t\t&& pecl update-channels \t&& rm -rf /tmp/pear ~/.pearrc", 421 }, 422 { 423 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 12, 29, 98563791, time.UTC)}, 424 CreatedBy: "/bin/sh -c #(nop) COPY multi:03970f7b3773444b9f7f244f89d3ceeb4253ac6599f0ba0a4c0306c5bf7d1b9b in /usr/local/bin/ ", 425 }, 426 { 427 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 12, 30, 99974579, time.UTC)}, 428 CreatedBy: "/bin/sh -c docker-php-ext-enable sodium", 429 }, 430 { 431 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 12, 30, 266754534, time.UTC)}, 432 CreatedBy: "/bin/sh -c #(nop) ENTRYPOINT [\"docker-php-entrypoint\"]", 433 EmptyLayer: true, 434 }, 435 { 436 Created: v1.Time{Time: time.Date(2019, time.May, 11, 3, 12, 30, 414982715, time.UTC)}, 437 CreatedBy: "/bin/sh -c #(nop) CMD [\"php\" \"-a\"]", 438 EmptyLayer: true, 439 }, 440 { 441 Created: v1.Time{Time: time.Date(2019, time.May, 11, 5, 10, 12, 574223281, time.UTC)}, 442 CreatedBy: "/bin/sh -c apk add --no-cache --virtual .composer-rundeps git subversion openssh mercurial tini bash patch make zip unzip coreutils && apk add --no-cache --virtual .build-deps zlib-dev libzip-dev && docker-php-ext-configure zip --with-libzip && docker-php-ext-install -j$(getconf _NPROCESSORS_ONLN) zip opcache && runDeps=\"$( scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions | tr ',' '\\n' | sort -u | awk 'system(\"[ -e /usr/local/lib/\" $1 \" ]\") == 0 { next } { print \"so:\" $1 }' )\" && apk add --no-cache --virtual .composer-phpext-rundeps $runDeps && apk del .build-deps && printf \"# composer php cli ini settings\\ndate.timezone=UTC\\nmemory_limit=-1\\nopcache.enable_cli=1\\n\" > $PHP_INI_DIR/php-cli.ini", 443 }, 444 { 445 Created: v1.Time{Time: time.Date(2019, time.May, 11, 5, 10, 12, 831274473, time.UTC)}, 446 CreatedBy: "/bin/sh -c #(nop) ENV COMPOSER_ALLOW_SUPERUSER=1", 447 EmptyLayer: true, 448 }, 449 { 450 Created: v1.Time{Time: time.Date(2019, time.May, 11, 5, 10, 13, 3330711, time.UTC)}, 451 CreatedBy: "/bin/sh -c #(nop) ENV COMPOSER_HOME=/tmp", 452 EmptyLayer: true, 453 }, 454 { 455 Created: v1.Time{Time: time.Date(2019, time.May, 11, 5, 10, 18, 503381656, time.UTC)}, 456 CreatedBy: "/bin/sh -c #(nop) ENV COMPOSER_VERSION=1.7.3", 457 EmptyLayer: true, 458 }, 459 { 460 Created: v1.Time{Time: time.Date(2019, time.May, 11, 5, 10, 19, 619504049, time.UTC)}, 461 CreatedBy: "/bin/sh -c curl --silent --fail --location --retry 3 --output /tmp/installer.php --url https://raw.githubusercontent.com/composer/getcomposer.org/cb19f2aa3aeaa2006c0cd69a7ef011eb31463067/web/installer && php -r \" \\$signature = '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5'; \\$hash = hash('sha384', file_get_contents('/tmp/installer.php')); if (!hash_equals(\\$signature, \\$hash)) { unlink('/tmp/installer.php'); echo 'Integrity check failed, installer is either corrupt or worse.' . PHP_EOL; exit(1); }\" && php /tmp/installer.php --no-ansi --install-dir=/usr/bin --filename=composer --version=${COMPOSER_VERSION} && composer --ansi --version --no-interaction && rm -f /tmp/installer.php", 462 }, 463 { 464 Created: v1.Time{Time: time.Date(2019, time.May, 11, 5, 10, 19, 803213107, time.UTC)}, 465 CreatedBy: "/bin/sh -c #(nop) COPY file:0bcb2d1c76549e38469db832f5bcfcb4c538b26748a9d4246cc64f35a23280d0 in /docker-entrypoint.sh ", 466 }, 467 { 468 Created: v1.Time{Time: time.Date(2019, time.May, 11, 5, 10, 19, 987396089, time.UTC)}, 469 CreatedBy: "/bin/sh -c #(nop) WORKDIR /app", 470 }, 471 { 472 Created: v1.Time{Time: time.Date(2019, time.May, 11, 5, 10, 20, 159217819, time.UTC)}, 473 CreatedBy: "/bin/sh -c #(nop) ENTRYPOINT [\"/bin/sh\" \"/docker-entrypoint.sh\"]", 474 EmptyLayer: true, 475 }, 476 { 477 Created: v1.Time{Time: time.Date(2019, time.May, 11, 5, 10, 20, 331457195, time.UTC)}, 478 CreatedBy: "/bin/sh -c #(nop) CMD [\"composer\"]", 479 EmptyLayer: true, 480 }, 481 }, 482 OS: "linux", 483 RootFS: v1.RootFS{ 484 Type: "layers", 485 DiffIDs: []v1.Hash{ 486 { 487 Algorithm: "sha256", 488 Hex: "f1b5933fe4b5f49bbe8258745cf396afe07e625bdab3168e364daf7c956b6b81", 489 }, 490 { 491 Algorithm: "sha256", 492 Hex: "3575e617b5f4845d72ac357ea1712be9037c1f73e8893fa4a5b887be964f8f59", 493 }, 494 { 495 Algorithm: "sha256", 496 Hex: "414e112bbb2c35bef0e76708e87a68b521a011a1941fe6d062e30da800c69d1f", 497 }, 498 { 499 Algorithm: "sha256", 500 Hex: "21f626200b4c7decb2150402d3b801a886ef9dab022d11478eb3240b2a1bb175", 501 }, 502 { 503 Algorithm: "sha256", 504 Hex: "64a9089492da43bf6f8f3b3b45aafee7d71f1dfd6464477e27b43b4dbe1da341", 505 }, 506 { 507 Algorithm: "sha256", 508 Hex: "c60e74b6df1608ee7a080978a9f5eddce48dd4d7366b65a5ec00c6e96deabfae", 509 }, 510 { 511 Algorithm: "sha256", 512 Hex: "489ab25ac6f9d77b5868493bfccc72bcbfaa85d8f393cdd21f3a6cb6e0256c15", 513 }, 514 { 515 Algorithm: "sha256", 516 Hex: "5a8c7d3402d369f0f5838b74da5c2bd3eaa64c6bbd8d8e11d7ec0affb074c276", 517 }, 518 { 519 Algorithm: "sha256", 520 Hex: "fe6bde799f85946dbed35f5f614532d68a9f8b62f3f42ae9164740c3d0a6296a", 521 }, 522 { 523 Algorithm: "sha256", 524 Hex: "40dd29f574f814717669b34efc4ae527a3af0829a2cccb9ec4f077a8cb2766cc", 525 }, 526 { 527 Algorithm: "sha256", 528 Hex: "0d5d3c0e6691d3c6d24dc782de33d64d490226c503414da0df93b8f605f93da5", 529 }, 530 { 531 Algorithm: "sha256", 532 Hex: "41467c77644ee108b8ef3e89db7f235ebb720ed4a4041bf746d7342193e6bc7d", 533 }, 534 { 535 Algorithm: "sha256", 536 Hex: "6a64ec219cdeecfe63aac5b7f43fb3cb6651c6b1a02ebbde6deeabf8a7e3b345", 537 }, 538 }, 539 }, 540 Config: v1.Config{ 541 Cmd: []string{"composer"}, 542 Entrypoint: []string{ 543 "/bin/sh", 544 "/docker-entrypoint.sh", 545 }, 546 Env: []string{ 547 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 548 "PHPIZE_DEPS=autoconf \t\tdpkg-dev dpkg \t\tfile \t\tg++ \t\tgcc \t\tlibc-dev \t\tmake \t\tpkgconf \t\tre2c", 549 "PHP_INI_DIR=/usr/local/etc/php", 550 "PHP_CFLAGS=-fstack-protector-strong -fpic -fpie -O2", 551 "PHP_CPPFLAGS=-fstack-protector-strong -fpic -fpie -O2", 552 "PHP_LDFLAGS=-Wl,-O1 -Wl,--hash-style=both -pie", 553 "GPG_KEYS=CBAF69F173A0FEA4B537F470D66C9593118BCCB6 F38252826ACD957EF380D39F2F7956BC5DA04B5D", 554 "PHP_VERSION=7.3.5", 555 "PHP_URL=https://www.php.net/get/php-7.3.5.tar.xz/from/this/mirror", 556 "PHP_ASC_URL=https://www.php.net/get/php-7.3.5.tar.xz.asc/from/this/mirror", 557 "PHP_SHA256=e1011838a46fd4a195c8453b333916622d7ff5bce4aca2d9d99afac142db2472", 558 "PHP_MD5=", 559 "COMPOSER_ALLOW_SUPERUSER=1", 560 "COMPOSER_HOME=/tmp", 561 "COMPOSER_VERSION=1.7.3", 562 }, 563 Image: "sha256:45a1f30c00e614b0d90bb2a24affba0a304ff27660ad4717987fefe067cadec8", 564 WorkingDir: "/app", 565 ArgsEscaped: true, 566 }, 567 } 568 569 wantPkgs = []types.Package{ 570 { 571 Name: "acl", 572 Version: "2.2.52-r5", 573 }, 574 { 575 Name: "apr", 576 Version: "1.6.5-r0", 577 }, 578 { 579 Name: "apr-util", 580 Version: "1.6.1-r5", 581 }, 582 { 583 Name: "argon2", 584 Version: "20171227-r1", 585 }, 586 { 587 Name: "argon2-dev", 588 Version: "20171227-r1", 589 }, 590 { 591 Name: "argon2-libs", 592 Version: "20171227-r1", 593 }, 594 { 595 Name: "attr", 596 Version: "2.4.47-r7", 597 }, 598 { 599 Name: "autoconf", 600 Version: "2.69-r2", 601 }, 602 { 603 Name: "bash", 604 Version: "4.4.19-r1", 605 }, 606 { 607 Name: "binutils", 608 Version: "2.31.1-r2", 609 }, 610 { 611 Name: "busybox", 612 Version: "1.29.3-r10", 613 }, 614 { 615 Name: "bzip2", 616 Version: "1.0.6-r6", 617 }, 618 { 619 Name: "ca-certificates", 620 Version: "20190108-r0", 621 }, 622 { 623 Name: "coreutils", 624 Version: "8.30-r0", 625 }, 626 { 627 Name: "curl", 628 Version: "7.64.0-r1", 629 }, 630 { 631 Name: "curl-dev", 632 Version: "7.64.0-r1", 633 }, 634 { 635 Name: "cyrus-sasl", 636 Version: "2.1.27-r1", 637 }, 638 { 639 Name: "db", 640 Version: "5.3.28-r1", 641 }, 642 { 643 Name: "dpkg", 644 Version: "1.19.2-r0", 645 }, 646 { 647 Name: "dpkg-dev", 648 Version: "1.19.2-r0", 649 }, 650 { 651 Name: "expat", 652 Version: "2.2.6-r0", 653 }, 654 { 655 Name: "file", 656 Version: "5.36-r0", 657 }, 658 { 659 Name: "g++", 660 Version: "8.3.0-r0", 661 }, 662 { 663 Name: "gcc", 664 Version: "8.3.0-r0", 665 }, 666 { 667 Name: "gdbm", 668 Version: "1.13-r1", 669 }, 670 { 671 Name: "git", 672 Version: "2.20.1-r0", 673 }, 674 { 675 Name: "gmp", 676 Version: "6.1.2-r1", 677 }, 678 { 679 Name: "gnupg", 680 Version: "2.2.12-r0", 681 }, 682 { 683 Name: "gnutls", 684 Version: "3.6.7-r0", 685 }, 686 { 687 Name: "isl", 688 Version: "0.18-r0", 689 }, 690 { 691 Name: "libacl", 692 Version: "2.2.52-r5", 693 }, 694 { 695 Name: "libassuan", 696 Version: "2.5.1-r0", 697 }, 698 { 699 Name: "libatomic", 700 Version: "8.3.0-r0", 701 }, 702 { 703 Name: "libattr", 704 Version: "2.4.47-r7", 705 }, 706 { 707 Name: "libbz2", 708 Version: "1.0.6-r6", 709 }, 710 { 711 Name: "libc-dev", 712 Version: "0.7.1-r0", 713 }, 714 { 715 Name: "libcap", 716 Version: "2.26-r0", 717 }, 718 { 719 Name: "libcrypto1.1", 720 Version: "1.1.1b-r1", 721 }, 722 { 723 Name: "libcurl", 724 Version: "7.64.0-r1", 725 }, 726 { 727 Name: "libedit", 728 Version: "20181209.3.1-r0", 729 }, 730 { 731 Name: "libedit-dev", 732 Version: "20181209.3.1-r0", 733 }, 734 { 735 Name: "libffi", 736 Version: "3.2.1-r6", 737 }, 738 { 739 Name: "libgcc", 740 Version: "8.3.0-r0", 741 }, 742 { 743 Name: "libgcrypt", 744 Version: "1.8.4-r0", 745 }, 746 { 747 Name: "libgomp", 748 Version: "8.3.0-r0", 749 }, 750 { 751 Name: "libgpg-error", 752 Version: "1.33-r0", 753 }, 754 { 755 Name: "libksba", 756 Version: "1.3.5-r0", 757 }, 758 { 759 Name: "libldap", 760 Version: "2.4.47-r2", 761 }, 762 { 763 Name: "libmagic", 764 Version: "5.36-r0", 765 }, 766 { 767 Name: "libsasl", 768 Version: "2.1.27-r1", 769 }, 770 { 771 Name: "libsodium", 772 Version: "1.0.16-r0", 773 }, 774 { 775 Name: "libsodium-dev", 776 Version: "1.0.16-r0", 777 }, 778 { 779 Name: "libssh2", 780 Version: "1.8.2-r0", 781 }, 782 { 783 Name: "libssh2-dev", 784 Version: "1.8.2-r0", 785 }, 786 { 787 Name: "libssl1.1", 788 Version: "1.1.1b-r1", 789 }, 790 { 791 Name: "libstdc++", 792 Version: "8.3.0-r0", 793 }, 794 { 795 Name: "libtasn1", 796 Version: "4.13-r0", 797 }, 798 { 799 Name: "libunistring", 800 Version: "0.9.10-r0", 801 }, 802 { 803 Name: "libuuid", 804 Version: "2.33-r0", 805 }, 806 { 807 Name: "libxml2", 808 Version: "2.9.9-r1", 809 }, 810 { 811 Name: "libxml2-dev", 812 Version: "2.9.9-r1", 813 }, 814 { 815 Name: "lz4", 816 Version: "1.8.3-r2", 817 }, 818 { 819 Name: "lz4-libs", 820 Version: "1.8.3-r2", 821 }, 822 { 823 Name: "m4", 824 Version: "1.4.18-r1", 825 }, 826 { 827 Name: "make", 828 Version: "4.2.1-r2", 829 }, 830 { 831 Name: "mercurial", 832 Version: "4.9.1-r0", 833 }, 834 { 835 Name: "mpc1", 836 Version: "1.0.3-r1", 837 }, 838 { 839 Name: "mpfr3", 840 Version: "3.1.5-r1", 841 }, 842 { 843 Name: "musl", 844 Version: "1.1.20-r4", 845 }, 846 { 847 Name: "musl-dev", 848 Version: "1.1.20-r4", 849 }, 850 { 851 Name: "ncurses", 852 Version: "6.1_p20190105-r0", 853 }, 854 { 855 Name: "ncurses-dev", 856 Version: "6.1_p20190105-r0", 857 }, 858 { 859 Name: "ncurses-libs", 860 Version: "6.1_p20190105-r0", 861 }, 862 { 863 Name: "ncurses-terminfo", 864 Version: "6.1_p20190105-r0", 865 }, 866 { 867 Name: "ncurses-terminfo-base", 868 Version: "6.1_p20190105-r0", 869 }, 870 { 871 Name: "nettle", 872 Version: "3.4.1-r0", 873 }, 874 { 875 Name: "nghttp2", 876 Version: "1.35.1-r0", 877 }, 878 { 879 Name: "nghttp2-dev", 880 Version: "1.35.1-r0", 881 }, 882 { 883 Name: "nghttp2-libs", 884 Version: "1.35.1-r0", 885 }, 886 { 887 Name: "npth", 888 Version: "1.6-r0", 889 }, 890 { 891 Name: "openldap", 892 Version: "2.4.47-r2", 893 }, 894 { 895 Name: "openssh", 896 Version: "7.9_p1-r5", 897 }, 898 { 899 Name: "openssh-client", 900 Version: "7.9_p1-r5", 901 }, 902 { 903 Name: "openssh-keygen", 904 Version: "7.9_p1-r5", 905 }, 906 { 907 Name: "openssh-server", 908 Version: "7.9_p1-r5", 909 }, 910 { 911 Name: "openssh-server-common", 912 Version: "7.9_p1-r5", 913 }, 914 { 915 Name: "openssh-sftp-server", 916 Version: "7.9_p1-r5", 917 }, 918 { 919 Name: "openssl", 920 Version: "1.1.1b-r1", 921 }, 922 { 923 Name: "openssl-dev", 924 Version: "1.1.1b-r1", 925 }, 926 { 927 Name: "p11-kit", 928 Version: "0.23.14-r0", 929 }, 930 { 931 Name: "patch", 932 Version: "2.7.6-r4", 933 }, 934 { 935 Name: "pcre2", 936 Version: "10.32-r1", 937 }, 938 { 939 Name: "perl", 940 Version: "5.26.3-r0", 941 }, 942 { 943 Name: "pinentry", 944 Version: "1.1.0-r0", 945 }, 946 { 947 Name: "pkgconf", 948 Version: "1.6.0-r0", 949 }, 950 { 951 Name: "python2", 952 Version: "2.7.16-r1", 953 }, 954 { 955 Name: "re2c", 956 Version: "1.1.1-r0", 957 }, 958 { 959 Name: "readline", 960 Version: "7.0.003-r1", 961 }, 962 { 963 Name: "serf", 964 Version: "1.3.9-r5", 965 }, 966 { 967 Name: "sqlite", 968 Version: "3.26.0-r3", 969 }, 970 { 971 Name: "sqlite-dev", 972 Version: "3.26.0-r3", 973 }, 974 { 975 Name: "sqlite-libs", 976 Version: "3.26.0-r3", 977 }, 978 { 979 Name: "subversion", 980 Version: "1.11.1-r0", 981 }, 982 { 983 Name: "subversion-libs", 984 Version: "1.11.1-r0", 985 }, 986 { 987 Name: "tar", 988 Version: "1.32-r0", 989 }, 990 { 991 Name: "unzip", 992 Version: "6.0-r4", 993 }, 994 { 995 Name: "util-linux", 996 Version: "2.33-r0", 997 }, 998 { 999 Name: "wget", 1000 Version: "1.20.3-r0", 1001 }, 1002 { 1003 Name: "xz", 1004 Version: "5.2.4-r0", 1005 }, 1006 { 1007 Name: "xz-libs", 1008 Version: "5.2.4-r0", 1009 }, 1010 { 1011 Name: "zip", 1012 Version: "3.0-r7", 1013 }, 1014 { 1015 Name: "zlib", 1016 Version: "1.2.11-r1", 1017 }, 1018 { 1019 Name: "zlib-dev", 1020 Version: "1.2.11-r1", 1021 }, 1022 } 1023 ) 1024 1025 func TestAnalyze(t *testing.T) { 1026 testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { 1027 content, err := os.ReadFile("testdata/history_v3.9.json") 1028 if err != nil { 1029 http.Error(res, err.Error(), http.StatusInternalServerError) 1030 return 1031 } 1032 res.WriteHeader(http.StatusOK) 1033 res.Write(content) 1034 return 1035 })) 1036 defer testServer.Close() 1037 1038 type args struct { 1039 targetOS types.OS 1040 config *v1.ConfigFile 1041 } 1042 var tests = map[string]struct { 1043 args args 1044 apkIndexArchivePath string 1045 want types.Packages 1046 }{ 1047 "old": { 1048 args: args{ 1049 targetOS: types.OS{ 1050 Family: "alpine", 1051 Name: "3.9.1", 1052 }, 1053 config: oldAlpineConfig, 1054 }, 1055 apkIndexArchivePath: "file://testdata/history_v%s.json", 1056 want: nil, 1057 }, 1058 "new": { 1059 args: args{ 1060 targetOS: types.OS{ 1061 Family: "alpine", 1062 Name: "3.9.1", 1063 }, 1064 config: alpineConfig, 1065 }, 1066 apkIndexArchivePath: "file://testdata/history_v%s.json", 1067 want: wantPkgs, 1068 }, 1069 "https": { 1070 args: args{ 1071 targetOS: types.OS{ 1072 Family: "alpine", 1073 Name: "", 1074 }, 1075 config: alpineConfig, 1076 }, 1077 apkIndexArchivePath: testServer.URL + "%v", 1078 want: wantPkgs, 1079 }, 1080 } 1081 for testName, v := range tests { 1082 t.Run(testName, func(t *testing.T) { 1083 t.Setenv(envApkIndexArchiveURL, v.apkIndexArchivePath) 1084 a, err := newAlpineCmdAnalyzer(analyzer.ConfigAnalyzerOptions{}) 1085 require.NoError(t, err) 1086 result, err := a.Analyze(context.Background(), analyzer.ConfigAnalysisInput{ 1087 OS: v.args.targetOS, 1088 Config: v.args.config, 1089 }) 1090 require.NoError(t, err) 1091 1092 got := lo.FromPtr(result) 1093 sort.Sort(got.HistoryPackages) 1094 assert.Equal(t, v.want, got.HistoryPackages) 1095 }) 1096 } 1097 } 1098 1099 func TestParseCommand(t *testing.T) { 1100 var tests = map[string]struct { 1101 command string 1102 envs map[string]string 1103 expected []string 1104 }{ 1105 "no package": { 1106 command: "/bin/sh -c #(nop) ADD file:49f9e47e678d868d5b023482aa8dded71276a241a665c4f8b55ca77269321b34 in / ", 1107 envs: nil, 1108 expected: nil, 1109 }, 1110 "no-cache": { 1111 command: "/bin/sh -c apk add --no-cache --virtual .persistent-deps \t\tca-certificates \t\tcurl \t\ttar \t\txz \t\tlibressl", 1112 envs: nil, 1113 expected: []string{ 1114 "ca-certificates", 1115 "curl", 1116 "tar", 1117 "xz", 1118 "libressl", 1119 }, 1120 }, 1121 // TODO: support $runDeps 1122 "joined by &&": { 1123 command: `/bin/sh -c apk add --no-cache --virtual .build-deps zlib-dev && docker-php-ext-install zip && runDeps=\"$( scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions | tr ',' '\\n' | sort -u | awk 'system(\"[ -e /usr/local/lib/\" $1 \" ]\") == 0 { next } { print \"so:\" $1 }' )\" && apk add --virtual .composer-phpext-rundeps $runDeps && apk del .build-deps`, 1124 envs: nil, 1125 expected: []string{"zlib-dev"}, 1126 }, 1127 "joined by ;": { 1128 command: "/bin/sh -c set -xe; \t\tapk add --no-cache --virtual .fetch-deps \t\tgnupg \t\twget \t; \t\tmkdir -p /usr/src; \tcd /usr/src; \t\twget -O php.tar.xz \"$PHP_URL\"; \t\tif [ -n \"$PHP_SHA256\" ]; then \t\techo \"$PHP_SHA256 *php.tar.xz\" | sha256sum -c -; \tfi; \tif [ -n \"$PHP_MD5\" ]; then \t\techo \"$PHP_MD5 *php.tar.xz\" | md5sum -c -; \tfi; \t\tif [ -n \"$PHP_ASC_URL\" ]; then \t\twget -O php.tar.xz.asc \"$PHP_ASC_URL\"; \t\texport GNUPGHOME=\"$(mktemp -d)\"; \t\tfor key in $GPG_KEYS; do \t\t\tgpg --keyserver ha.pool.sks-keyservers.net --recv-keys \"$key\"; \t\tdone; \t\tgpg --batch --verify php.tar.xz.asc php.tar.xz; \t\tcommand -v gpgconf > /dev/null && gpgconf --kill all; \t\trm -rf \"$GNUPGHOME\"; \tfi; \t\tapk del .fetch-deps", 1129 envs: nil, 1130 expected: []string{ 1131 "gnupg", 1132 "wget", 1133 }, 1134 }, 1135 "ENV": { 1136 command: "/bin/sh -c set -xe \t&& apk add --no-cache --virtual .build-deps \t\t$PHPIZE_DEPS \t\tcoreutils \t\tcurl-dev \t\tlibedit-dev \t\tlibressl-dev \t\tlibsodium-dev \t\tlibxml2-dev \t\tsqlite-dev", 1137 envs: map[string]string{ 1138 "$PHPIZE_DEPS": "autoconf \t\tdpkg-dev dpkg \t\tfile \t\tg++ \t\tgcc \t\tlibc-dev \t\tmake \t\tpkgconf \t\tre2c", 1139 }, 1140 expected: []string{ 1141 "autoconf", 1142 "dpkg-dev", 1143 "dpkg", 1144 "file", 1145 "g++", 1146 "gcc", 1147 "libc-dev", 1148 "make", 1149 "pkgconf", 1150 "re2c", 1151 "coreutils", 1152 "curl-dev", 1153 "libedit-dev", 1154 "libressl-dev", 1155 "libsodium-dev", 1156 "libxml2-dev", 1157 "sqlite-dev", 1158 }, 1159 }, 1160 } 1161 analyzer := alpineCmdAnalyzer{} 1162 for testName, v := range tests { 1163 actual := analyzer.parseCommand(v.command, v.envs) 1164 assert.Equal(t, v.expected, actual, "[%s]\n%s", testName, pretty.Compare(v.expected, actual)) 1165 } 1166 } 1167 1168 func TestResolveDependency(t *testing.T) { 1169 var tests = map[string]struct { 1170 pkgName string 1171 apkIndexArchivePath string 1172 expected map[string]struct{} 1173 }{ 1174 "low": { 1175 pkgName: "libblkid", 1176 apkIndexArchivePath: "testdata/history_v3.9.json", 1177 expected: map[string]struct{}{ 1178 "libblkid": {}, 1179 "libuuid": {}, 1180 "musl": {}, 1181 }, 1182 }, 1183 "medium": { 1184 pkgName: "libgcab", 1185 apkIndexArchivePath: "testdata/history_v3.9.json", 1186 expected: map[string]struct{}{ 1187 "busybox": {}, 1188 "libblkid": {}, 1189 "libuuid": {}, 1190 "musl": {}, 1191 "libmount": {}, 1192 "pcre": {}, 1193 "glib": {}, 1194 "libgcab": {}, 1195 "libintl": {}, 1196 "zlib": {}, 1197 "libffi": {}, 1198 }, 1199 }, 1200 "high": { 1201 pkgName: "postgresql", 1202 apkIndexArchivePath: "testdata/history_v3.9.json", 1203 expected: map[string]struct{}{ 1204 "busybox": {}, 1205 "ncurses-terminfo-base": {}, 1206 "ncurses-terminfo": {}, 1207 "libedit": {}, 1208 "db": {}, 1209 "libsasl": {}, 1210 "libldap": {}, 1211 "libpq": {}, 1212 "postgresql-client": {}, 1213 "tzdata": {}, 1214 "libxml2": {}, 1215 "postgresql": {}, 1216 "musl": {}, 1217 "libcrypto1.1": {}, 1218 "libssl1.1": {}, 1219 "ncurses-libs": {}, 1220 "zlib": {}, 1221 }, 1222 }, 1223 "package alias": { 1224 pkgName: "sqlite-dev", 1225 apkIndexArchivePath: "testdata/history_v3.9.json", 1226 expected: map[string]struct{}{ 1227 "sqlite-dev": {}, 1228 "sqlite-libs": {}, 1229 "pkgconf": {}, // pkgconfig => pkgconf 1230 "musl": {}, 1231 }, 1232 }, 1233 "circular dependencies": { 1234 pkgName: "nodejs", 1235 apkIndexArchivePath: "testdata/history_v3.7.json", 1236 expected: map[string]struct{}{ 1237 "busybox": {}, 1238 "c-ares": {}, 1239 "ca-certificates": {}, 1240 "http-parser": {}, 1241 "libcrypto1.0": {}, 1242 "libgcc": {}, 1243 "libressl2.6-libcrypto": {}, 1244 "libssl1.0": {}, 1245 "libstdc++": {}, 1246 "libuv": {}, 1247 "musl": {}, 1248 "nodejs": {}, 1249 "nodejs-npm": {}, 1250 "zlib": {}, 1251 }, 1252 }, 1253 } 1254 analyzer := alpineCmdAnalyzer{} 1255 for testName, v := range tests { 1256 f, err := os.Open(v.apkIndexArchivePath) 1257 if err != nil { 1258 t.Fatalf("unexpected error: %s", err) 1259 } 1260 apkIndexArchive := &apkIndex{} 1261 if err = json.NewDecoder(f).Decode(&apkIndexArchive); err != nil { 1262 t.Fatalf("unexpected error: %s", err) 1263 } 1264 circularDependencyCheck := map[string]struct{}{} 1265 pkgs := analyzer.resolveDependency(apkIndexArchive, v.pkgName, circularDependencyCheck) 1266 actual := map[string]struct{}{} 1267 for _, pkg := range pkgs { 1268 actual[pkg] = struct{}{} 1269 } 1270 if !reflect.DeepEqual(v.expected, actual) { 1271 t.Errorf("[%s]\n%s", testName, pretty.Compare(v.expected, actual)) 1272 } 1273 } 1274 } 1275 1276 func TestGuessVersion(t *testing.T) { 1277 var tests = map[string]struct { 1278 apkIndexArchive *apkIndex 1279 pkgs []string 1280 createdAt time.Time 1281 expected []types.Package 1282 }{ 1283 "normal": { 1284 apkIndexArchive: &apkIndex{ 1285 Package: map[string]archive{ 1286 "busybox": { 1287 Versions: map[string]int{ 1288 "1.24.2-r0": 100, 1289 "1.24.2-r1": 200, 1290 "1.24.2-r2": 300, 1291 }, 1292 }, 1293 }, 1294 }, 1295 pkgs: []string{"busybox"}, 1296 createdAt: time.Unix(200, 0), 1297 expected: []types.Package{ 1298 { 1299 Name: "busybox", 1300 Version: "1.24.2-r1", 1301 }, 1302 }, 1303 }, 1304 "unmatched version": { 1305 apkIndexArchive: &apkIndex{ 1306 Package: map[string]archive{ 1307 "busybox": { 1308 Versions: map[string]int{ 1309 "1.24.2-r0": 100, 1310 "1.24.2-r1": 200, 1311 "1.24.2-r2": 300, 1312 }, 1313 }, 1314 }, 1315 }, 1316 pkgs: []string{"busybox"}, 1317 createdAt: time.Unix(50, 0), 1318 expected: nil, 1319 }, 1320 "unmatched package": { 1321 apkIndexArchive: &apkIndex{ 1322 Package: map[string]archive{ 1323 "busybox": { 1324 Versions: map[string]int{ 1325 "1.24.2-r0": 100, 1326 "1.24.2-r1": 200, 1327 "1.24.2-r2": 300, 1328 }, 1329 }, 1330 }, 1331 }, 1332 pkgs: []string{ 1333 "busybox", 1334 "openssl", 1335 }, 1336 createdAt: time.Unix(200, 0), 1337 expected: []types.Package{ 1338 { 1339 Name: "busybox", 1340 Version: "1.24.2-r1", 1341 }, 1342 }, 1343 }, 1344 "origin": { 1345 apkIndexArchive: &apkIndex{ 1346 Package: map[string]archive{ 1347 "sqlite-dev": { 1348 Versions: map[string]int{ 1349 "3.26.0-r0": 100, 1350 "3.26.0-r1": 200, 1351 "3.26.0-r2": 300, 1352 "3.26.0-r3": 400, 1353 }, 1354 Origin: "sqlite", 1355 }, 1356 }, 1357 }, 1358 pkgs: []string{"sqlite-dev"}, 1359 createdAt: time.Unix(500, 0), 1360 expected: []types.Package{ 1361 { 1362 Name: "sqlite-dev", 1363 Version: "3.26.0-r3", 1364 }, 1365 { 1366 Name: "sqlite", 1367 Version: "3.26.0-r3", 1368 }, 1369 }, 1370 }, 1371 } 1372 analyzer := alpineCmdAnalyzer{} 1373 for testName, v := range tests { 1374 actual := analyzer.guessVersion(v.apkIndexArchive, v.pkgs, v.createdAt) 1375 if !reflect.DeepEqual(v.expected, actual) { 1376 t.Errorf("[%s]\n%s", testName, pretty.Compare(v.expected, actual)) 1377 } 1378 } 1379 }