Skip to content

Commit

Permalink
Add APK support to Ahab (#8)
Browse files Browse the repository at this point in the history
馃挜
  • Loading branch information
DarthHater committed Nov 25, 2019
1 parent f776247 commit fed8838
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 5 deletions.
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -16,8 +16,9 @@ To use `ahab`, assuming you have a built version of it:

* `dpkg-query --show --showformat='${Package} ${Version}\n' | ./ahab chase`
* `yum list installed | ./ahab chase --os fedora`
* `apk info -vv | sort | ./ahab chase --os alpine`

`ahab` currently works for images that use `apt` or `yum` for package management.
`ahab` currently works for images that use `apt`, `apk` or `yum` for package management.

## Why is this useful?

Expand Down
11 changes: 7 additions & 4 deletions main.go
Expand Up @@ -73,20 +73,23 @@ func tryExtractAndAudit(pkgs packages.IPackage, operating string) {
func tryParseStdInList(list []string, operating *string) {
var thing string
thing = *operating
if thing == "debian" {
switch thing {
case "debian":
var aptResult packages.Apt
//aptResult.ProjectList = parse.ParseAptListFromStdIn(list)
aptResult.ProjectList = parse.ParseDpkgList(list)
tryExtractAndAudit(aptResult, thing)
} else {
case "alpine":
var apkResult packages.Apk
apkResult.ProjectList = parse.ParseApkShow(list)
tryExtractAndAudit(apkResult, thing)
default:
var yumResult packages.Yum
yumResult.ProjectList = parse.ParseYumListFromStdIn(list)
tryExtractAndAudit(yumResult, thing)
}
}

func tryAuditPackages(purls []string, count int) {
//fmt.Print(purls)
coordinates, err := ossindex.AuditPackages(purls)
if err != nil {
fmt.Print(err)
Expand Down
32 changes: 32 additions & 0 deletions packages/apk.go
@@ -0,0 +1,32 @@
// Copyright 2019 Sonatype Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package packages

import (
"fmt"

types "github.com/sonatype-nexus-community/nancy/types"
)

type Apk struct {
ProjectList types.ProjectList
}

func (a Apk) ExtractPurlsFromProjectList(operating string) (purls []string) {
for _, s := range a.ProjectList.Projects {
var purl = fmt.Sprintf("pkg:alpine/%s@%s", s.Name, s.Version)
purls = append(purls, purl)
}
return
}
48 changes: 48 additions & 0 deletions parse/apk.go
@@ -0,0 +1,48 @@
// Copyright 2019 Sonatype Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package parse

import (
"fmt"
"regexp"
"strings"

"github.com/sonatype-nexus-community/nancy/types"
)

func ParseApkShow(packages []string) (projectList types.ProjectList) {
for _, pkg := range packages {
if !strings.Contains(pkg, "WARNING") {
projectList.Projects = append(projectList.Projects, doApkShowParse(pkg))
}
}
return
}

func doApkShowParse(pkg string) (parsedProject types.Projects) {
pkg = strings.TrimSpace(pkg)
splitPackage := strings.Split(pkg, " ")
re, err := regexp.Compile(`^((.*)-([^a-zA-Z].*)-.*)`)
if err != nil {
panic(err)
}
newSlice := re.FindStringSubmatch(splitPackage[0])
if newSlice != nil {
parsedProject.Name = newSlice[2]
parsedProject.Version = newSlice[3]
} else {
fmt.Printf("Failure parsing name, version for package")
}
return
}
64 changes: 64 additions & 0 deletions parse/apk_test.go
@@ -0,0 +1,64 @@
// Copyright 2019 Sonatype Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package parse_test

import (
"strings"
"testing"

. "github.com/sonatype-nexus-community/ahab/parse"
"github.com/sonatype-nexus-community/nancy/types"
"github.com/stretchr/testify/assert"
)

// generate CLI package list via:
// # apk info -vv | sort
var apkShowList = `WARNING: Ignoring APKINDEX.00740ba1.tar.gz: No such file or directory
WARNING: Ignoring APKINDEX.d8b2a6f4.tar.gz: No such file or directory
alpine-baselayout-3.1.2-r0 - Alpine base dir structure and init scripts
alpine-keys-2.1-r2 - Public keys for Alpine Linux packages
apk-tools-2.10.4-r2 - Alpine Package Keeper - package manager for alpine
busybox-1.30.1-r2 - Size optimized toolbox of many common UNIX utilities
ca-certificates-cacert-20190108-r0 - Mozilla bundled certificates
libc-utils-0.7.1-r0 - Meta package to pull in correct libc
libcrypto1.1-1.1.1c-r0 - Crypto library from openssl
libssl1.1-1.1.1c-r0 - SSL shared libraries
libtls-standalone-2.9.1-r0 - libtls extricated from libressl sources
musl-1.1.22-r3 - the musl c library (libc) implementation
musl-utils-1.1.22-r3 - the musl c library (libc) implementation
scanelf-1.2.3-r0 - Scan ELF binaries for stuff
ssl_client-1.30.1-r2 - EXternal ssl_client for busybox wget
zlib-1.2.11-r1 - A compression/decompression Library`

var apkShowArray = strings.Split(apkShowList, "\n")

func TestParseApkShowList(t *testing.T) {
result := ParseApkShow(apkShowArray)

if len(result.Projects) != 14 {
t.Errorf("Didn't work, expected %d projects but got %d", 14, len(result.Projects))
}

// alpine-baselayout-3.1.2-r0
assert.Equal(t, types.Projects{"alpine-baselayout", "3.1.2"}, result.Projects[0])

// alpine-keys-2.1-r2
assert.Equal(t, types.Projects{"alpine-keys", "2.1"}, result.Projects[1])

// apk-tools-2.10.4-r2
assert.Equal(t, types.Projects{"apk-tools", "2.10.4"}, result.Projects[2])

// ca-certificates-cacert-20190108-r0
assert.Equal(t, types.Projects{"ca-certificates-cacert", "20190108"}, result.Projects[4])
}
16 changes: 16 additions & 0 deletions testapk.txt
@@ -0,0 +1,16 @@
WARNING: Ignoring APKINDEX.00740ba1.tar.gz: No such file or directory
WARNING: Ignoring APKINDEX.d8b2a6f4.tar.gz: No such file or directory
alpine-baselayout-3.1.2-r0 - Alpine base dir structure and init scripts
alpine-keys-2.1-r2 - Public keys for Alpine Linux packages
apk-tools-2.10.4-r2 - Alpine Package Keeper - package manager for alpine
busybox-1.30.1-r2 - Size optimized toolbox of many common UNIX utilities
ca-certificates-cacert-20190108-r0 - Mozilla bundled certificates
libc-utils-0.7.1-r0 - Meta package to pull in correct libc
libcrypto1.1-1.1.1c-r0 - Crypto library from openssl
libssl1.1-1.1.1c-r0 - SSL shared libraries
libtls-standalone-2.9.1-r0 - libtls extricated from libressl sources
musl-1.1.22-r3 - the musl c library (libc) implementation
musl-utils-1.1.22-r3 - the musl c library (libc) implementation
scanelf-1.2.3-r0 - Scan ELF binaries for stuff
ssl_client-1.30.1-r2 - EXternal ssl_client for busybox wget
zlib-1.2.11-r1 - A compression/decompression Library

0 comments on commit fed8838

Please sign in to comment.