You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: ubuntu.go
    path of file: ./repos/vuls/gost
    
    the code of the file until where you have to start completion: //go:build !scanner
// +build !scanner

package gost

import (
	"encoding/json"
	"fmt"
	"strconv"
	"strings"

	debver "github.com/knqyf263/go-deb-version"
	"golang.org/x/exp/maps"
	"golang.org/x/xerrors"

	"github.com/future-architect/vuls/logging"
	"github.com/future-architect/vuls/models"
	"github.com/future-architect/vuls/util"
	gostmodels "github.com/vulsio/gost/models"
)

// Ubuntu is Gost client for Ubuntu
type Ubuntu struct {
	Base
}

func (ubu Ubuntu) supported(version string) bool {
	_, ok := map[string]string{
		"606":  "dapper",
		"610":  "edgy",
		"704":  "feisty",
		"710":  "gutsy",
		"804":  "hardy",
		"810":  "intrepid",
		"904":  "jaunty",
		"910":  "karmic",
		"1004": "lucid",
		"1010": "maverick",
		"1104": "natty",
		"1110": "oneiric",
		"1204": "precise",
		"1210": "quantal",
		"1304": "raring",
		"1310": "saucy",
		"1404": "trust
    
func (ubu Ubuntu) isKernelSourcePackage(pkgname string) bool {
	switch ss := strings.Split(pkgname, "-"); len(ss) {
	case 1:
		return pkgname == "linux"
	case 2:
		if ss[0] != "linux" {
			return false
		}
		switch ss[1] {
		case "armadaxp", "mako", "manta", "flo", "goldfish", "joule", "raspi", "raspi2", "snapdragon", "aws", "azure", "bluefield", "dell300x", "gcp", "gke", "gkeop", "ibm", "lowlatency", "kvm", "oem", "oracle", "euclid", "hwe", "riscv":
			return true
		default:
			_, err := strconv.ParseFloat(ss[1], 64)
			return err == nil
		}
	case 3:
		if ss[0] != "linux" {
			return false
		}
		switch ss[1] {
		case "ti":
			return ss[2] == "omap4"
		case "raspi", "raspi2", "gke", "gkeop", "ibm", "oracle", "riscv":
			_, err := strconv.ParseFloat(ss[2], 64)
			return err == nil
		case "aws":
			switch ss[2] {
			case "hwe", "edge":
				return true
			default:
				_, err := strconv.ParseFloat(ss[2], 64)
				return err == nil
			}
		case "azure":
			switch ss[2] {
			case "fde", "edge":
				return true
			default:
				_, err := strconv.ParseFloat(ss[2], 64)
				return err == nil
			}
		case "gcp":
			switch ss[2] {
			case "edge":
				return true
			default:
				_, err := strconv.ParseFloat(ss[2], 64)
				return err == nil
			}
		case "intel":
			switch ss[2] {
			case "iotg":
				return true
			default:
				_, err := strconv.ParseFloat(ss[2], 64)
				return err == nil
			}
		case "oem":
			switch ss[2] {
			case "osp1":
				return true
			default:
				_, err := strconv.ParseFloat(ss[2], 64)
				return err == nil
			}
		case "lts":
			return ss[2] == "xenial"
		case "hwe":
			switch ss[2] {
			case "edge":
				return true
			default:
				_, err := strconv.ParseFloat(ss[2], 64)
				return err == nil
			}
		default:
			return false
		}
	case 4:
		if ss[0] != "linux" {
			return false
		}
		switch ss[1] {
		case "azure":
			if ss[2] != "fde" {
				return false
			}
			_, err := strconv.ParseFloat(ss[3], 64)
			return err == nil
		case "intel":
			if ss[2] != "iotg" {
				return false
			}
			_, err := strconv.ParseFloat(ss[3], 64)
			return err == nil
		case "lowlatency":
			if ss[2] != "hwe" {
				return false
			}
			_, err := strconv.ParseFloat(ss[3], 64)
			return err == nil
		default:
			return false
		}
	default:
		return false
	}
}