Skip to content

Commit

Permalink
Merge pull request #49 from parca-dev/add_glibc_235
Browse files Browse the repository at this point in the history
glibc: Add missing 2.35 for ARM64
  • Loading branch information
kakkoyun authored Mar 11, 2024
2 parents 405e2bc + 968989b commit badeb16
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 62 deletions.
160 changes: 99 additions & 61 deletions cmd/debdownload/debdownload.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func main() {
architectures = fSet.StringList('a', "arch", "architectures to download")
versionConstraint = fSet.String('c', "constraint", "", "version constraints to download")
variant = fSet.StringList('v', "variants", "variants of the package to download")
singleTarget = fSet.String('s', "single-target", "", "single target to download")
)
if err := ff.Parse(fSet, os.Args[1:]); err != nil {
fmt.Printf("%s\n", ffhelp.Flags(fSet))
Expand All @@ -87,10 +88,6 @@ func main() {
*tempDir = os.TempDir()
}

if *url == "" {
*url = DefaultBaseURL
}

if *pkgName == "" {
logger.Error("package name is required")
os.Exit(1)
Expand Down Expand Up @@ -122,10 +119,27 @@ func main() {
}
}

packages, err := cli.list(ctx, *url, *pkgName, *architectures, *versionConstraint, variants)
if err != nil {
logger.Error("failed to list packages", "err", err)
os.Exit(1)
var (
packages []*pkg
err error
)
if *singleTarget != "" {
p, err := cli.processPackageLink(*url, *pkgName, *architectures, *versionConstraint, variants, *singleTarget)
if err != nil {
logger.Error("failed to process package link", "err", err)
os.Exit(1)
}
packages = append(packages, p)
} else {
if *url == "" {
*url = DefaultBaseURL
}

packages, err = cli.list(ctx, *url, *pkgName, *architectures, *versionConstraint, variants)
if err != nil {
logger.Error("failed to list packages", "err", err)
os.Exit(1)
}
}

interimDir := filepath.Join(*tempDir, *pkgName)
Expand Down Expand Up @@ -205,21 +219,6 @@ func (c *cli) list(
return nil, fmt.Errorf("failed to parse HTML: %w", err)
}

var matcher *regexp.Regexp
switch c.sv {
case debian:
matcher = regexp.MustCompile(
fmt.Sprintf(`(%s)(-.*)?_(.*)_(%s)\.deb`, pkgName, strings.Join(architectures, "|")),
)
case ubuntu:
matcher = regexp.MustCompile(
fmt.Sprintf(`(%s)(-.*)?_(.*)-[0-9]ubuntu.*_(%s)\.deb`, pkgName, strings.Join(architectures, "|")),
)
default:
return nil, fmt.Errorf("unsupported package source variant: %d", c.sv)
}
c.logger.Info("matcher", "pattern", matcher.String())

packages := map[string]*pkg{}
key := func(p *pkg) string {
return strings.Join([]string{p.name, p.variant, shortVersion(p.version), p.arch}, "-")
Expand All @@ -230,46 +229,20 @@ func (c *cli) list(
if n.Type == html.ElementNode && n.Data == "a" {
for _, a := range n.Attr {
if a.Key == "href" {
if matches := matcher.FindStringSubmatch(a.Val); len(matches) > 0 {
v := strings.ReplaceAll(matches[3], "~", "+")
c.logger.Info("found package", "version", v, "arch", matches[4], "variant", matches[2])
version, err := semver.NewVersion(v)
if err != nil {
c.logger.Info("failed to parse version", "version", v, "err", err)
continue
}
if versionConstraint != "" {
match, reasons := mustConstraint(semver.NewConstraint(versionConstraint)).Validate(version)
if !match {
c.logger.Info("version does not match", "version", version, "reasons", reasons)
c.logger.Info("see: https://github.com/Masterminds/semver?tab=readme-ov-file#checking-version-constraints")
continue
}
}
variant := strings.TrimPrefix(matches[2], "-")
if variant != "" {
variant = strings.TrimSpace(variant)
if _, ok := variants[variant]; !ok {
continue
}
}
p := &pkg{
link: must(url.JoinPath(pkgUrl, a.Val)),
name: matches[1],
variant: variant,
version: version,
arch: matches[4],
}
if oldPkg, ok := packages[key(p)]; ok {
if p.version.GreaterThan(oldPkg.version) {
c.logger.Info("found newer version", "old", oldPkg.version, "new", p.version)
packages[key(p)] = p
}
continue
p, err := c.processPackageLink(pkgUrl, pkgName, architectures, versionConstraint, variants, a.Val)
if err != nil {
c.logger.Info("failed to process package link", "err", err)
continue
}
if oldPkg, ok := packages[key(p)]; ok {
if p.version.GreaterThan(oldPkg.version) {
c.logger.Info("found newer version", "old", oldPkg.version, "new", p.version)
packages[key(p)] = p
}

packages[key(p)] = p
continue
}

packages[key(p)] = p
}
}
}
Expand All @@ -281,6 +254,71 @@ func (c *cli) list(
return maps.Values(packages), nil
}

func (c *cli) processPackageLink(
pkgUrl, pkgName string,
architectures []string,
versionConstraint string,
variants map[string]struct{},
link string,
) (*pkg, error) {

var matcher *regexp.Regexp
switch c.sv {
case debian:
matcher = regexp.MustCompile(
fmt.Sprintf(`(%s)(-.*)?_(.*)_(%s)\.deb`, pkgName, strings.Join(architectures, "|")),
)
case ubuntu:
matcher = regexp.MustCompile(
fmt.Sprintf(`(%s)(-.*)?_(.*)-[0-9]ubuntu.*_(%s)\.deb`, pkgName, strings.Join(architectures, "|")),
)
default:
return nil, fmt.Errorf("unsupported package source variant: %d", c.sv)
}
c.logger.Info("matcher", "pattern", matcher.String())

if matches := matcher.FindStringSubmatch(link); len(matches) > 0 {
v := strings.ReplaceAll(matches[3], "~", "+")
c.logger.Info("found package", "version", v, "arch", matches[4], "variant", matches[2])
version, err := semver.NewVersion(v)
if err != nil {
c.logger.Info("failed to parse version", "version", v, "err", err)
return nil, fmt.Errorf("failed to parse version: %w", err)
}
if versionConstraint != "" {
match, reasons := mustConstraint(semver.NewConstraint(versionConstraint)).Validate(version)
if !match {
c.logger.Info("version does not match", "version", version, "reasons", reasons)
c.logger.Info("see: https://github.com/Masterminds/semver?tab=readme-ov-file#checking-version-constraints")
return nil, fmt.Errorf("version does not match: %s", version)
}
}
variant := strings.TrimPrefix(matches[2], "-")
if variant != "" {
variant = strings.TrimSpace(variant)
if _, ok := variants[variant]; !ok {
return nil, fmt.Errorf("variant not allowed: %s", variant)
}
}
var pLink string
if pkgUrl != "" {
pLink = must(url.JoinPath(pkgUrl, link))
} else {
pLink = link
}
p := &pkg{
link: pLink,
name: matches[1],
variant: variant,
version: version,
arch: matches[4],
}
return p, nil
}

return nil, fmt.Errorf("failed to match package link: %s", link)
}

func shortVersion(v *semver.Version) string {
return fmt.Sprintf("%d.%d", v.Major(), v.Minor())
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/libc/glibc/layout/arm64/= 2.35.0.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pthread_key_data: 8
pthread_key_data_size: 16
pthread_size: 1984
pthread_specific_1stblock: 272
6 changes: 5 additions & 1 deletion scripts/download/glibc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ PACKAGE_NAME=${PACKAGE_NAME:-libc6}
./debdownload -u 'http://archive.ubuntu.com/ubuntu/pool/main/g/glibc/' -t "${PACKAGE_DIR}" -o "${BIN_DIR}" -p "${PACKAGE_NAME}"
./debdownload -u 'http://old-releases.ubuntu.com/ubuntu/pool/main/g/glibc/' -t "${PACKAGE_DIR}" -o "${BIN_DIR}" -p "${PACKAGE_NAME}"

# 2.35 for arm64 is not available the archives above, so we need to download it separately.
./debdownload -t "${PACKAGE_DIR}" -o "${BIN_DIR}" -p "${PACKAGE_NAME}" -s http://launchpadlibrarian.net/707340001/libc6_2.35-0ubuntu3.6_arm64.deb
./debdownload -t "${PACKAGE_DIR}" -o "${BIN_DIR}" -p "${PACKAGE_NAME}" -s http://launchpadlibrarian.net/707339998/libc6-dbg_2.35-0ubuntu3.6_arm64.deb

convertArch() {
case $1 in
amd64)
Expand All @@ -39,7 +43,7 @@ convertArch() {
esac
}

echo "Extracting debuginfo from $BIN_DIR/$PACKAGE_NAME"
echo "Copying debuginfo from $BIN_DIR/$PACKAGE_NAME"
for arch in $BIN_DIR/$PACKAGE_NAME/*; do
for version in $arch/*; do
for variant in $version/*; do
Expand Down

0 comments on commit badeb16

Please sign in to comment.