Skip to content
This repository was archived by the owner on May 27, 2023. It is now read-only.

Commit 2574e4a

Browse files
add new feature that directly importing directories from skopeo.
1 parent 509fed3 commit 2574e4a

File tree

5 files changed

+253
-17
lines changed

5 files changed

+253
-17
lines changed
16.7 KB
Binary file not shown.

container/container.go

Lines changed: 159 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1751,6 +1751,157 @@ func SingularityLoad(file string, name string, tag string) *Error {
17511751
}
17521752
}
17531753

1754+
//name -> name with tag info
1755+
func SkopeoLoad(name, dir string) *Error {
1756+
currdir, err := GetConfigDir()
1757+
if err != nil {
1758+
return err
1759+
}
1760+
rootdir := fmt.Sprintf("%s/.lpmxdata", currdir)
1761+
sysdir := fmt.Sprintf("%s/.lpmxsys", currdir)
1762+
tempdir := fmt.Sprintf("%s/.temp", currdir)
1763+
//we delete temp dir if it exists at the end of the function
1764+
defer func() {
1765+
if FolderExist(tempdir) {
1766+
os.RemoveAll(tempdir)
1767+
}
1768+
}()
1769+
1770+
//check if folder exists
1771+
adir, derr := filepath.Abs(dir)
1772+
if derr!= nil {
1773+
cerr := ErrNew(derr, fmt.Sprintf("could not parse the absolute path: %s", adir))
1774+
return cerr
1775+
}
1776+
if !FolderExist(adir) {
1777+
cerr := ErrNew(ErrNExist, fmt.Sprintf("%s does exist", adir))
1778+
return cerr
1779+
}
1780+
1781+
//configure Docker related info locally
1782+
var doc Image
1783+
err = unmarshalObj(rootdir, &doc)
1784+
if err != nil && err.Err != ErrNExist {
1785+
return err
1786+
}
1787+
1788+
if err != nil && err.Err == ErrNExist {
1789+
ret, err := MakeDir(rootdir)
1790+
doc.RootDir = rootdir
1791+
doc.Images = make(map[string]interface{})
1792+
if !ret {
1793+
return err
1794+
}
1795+
}
1796+
1797+
image_dir := fmt.Sprintf("%s/.image", rootdir)
1798+
ret, layer_order, lerr := LoadSkopeoTar(adir, image_dir)
1799+
if lerr != nil {
1800+
return lerr
1801+
}
1802+
if _, ok := doc.Images[name]; ok {
1803+
cerr := ErrNew(ErrExist, fmt.Sprintf("%s already exists", name))
1804+
return cerr
1805+
} else {
1806+
tdata := strings.Split(name, ":")
1807+
tname := tdata[0]
1808+
ttag := tdata[1]
1809+
mdata := make(map[string]interface{})
1810+
mdata["rootdir"] = fmt.Sprintf("%s/%s/%s", doc.RootDir, tname, ttag)
1811+
mdata["config"] = fmt.Sprintf("%s/setting.yml", mdata["rootdir"].(string))
1812+
mdata["image"] = fmt.Sprintf("%s/.image", rootdir)
1813+
mdata["layer"] = ret
1814+
mdata["layer_order"] = strings.Join(layer_order, ":")
1815+
mdata["imagetype"] = "Docker"
1816+
1817+
//add docker info file(.info)
1818+
if !FolderExist(mdata["rootdir"].(string)) {
1819+
merr := os.MkdirAll(mdata["rootdir"].(string), os.FileMode(FOLDER_MODE))
1820+
if merr != nil {
1821+
cerr := ErrNew(merr, fmt.Sprintf("could not mkdir %s", mdata["rootdir"].(string)))
1822+
return cerr
1823+
}
1824+
}
1825+
var docinfo ImageInfo
1826+
docinfo.Name = name
1827+
docinfo.ImageType = "Docker"
1828+
// layer_order is absolute path
1829+
//docinfo layers map should remove absolute path of host
1830+
layersmap := make(map[string]int64)
1831+
for k, v := range ret {
1832+
layersmap[path.Base(k)] = v
1833+
}
1834+
docinfo.LayersMap = layersmap
1835+
1836+
var layer_sha []string
1837+
for _, layer := range layer_order {
1838+
layer_sha = append(layer_sha, path.Base(layer))
1839+
}
1840+
docinfo.Layers = strings.Join(layer_sha, ":")
1841+
1842+
LOGGER.WithFields(logrus.Fields{
1843+
"docinfo": docinfo,
1844+
}).Debug("Skopeo debug, docinfo debug")
1845+
1846+
dinfodata, _ := StructMarshal(docinfo)
1847+
err = WriteToFile(dinfodata, fmt.Sprintf("%s/.info", mdata["rootdir"].(string)))
1848+
if err != nil {
1849+
return err
1850+
}
1851+
//end
1852+
1853+
workspace := fmt.Sprintf("%s/workspace", mdata["rootdir"])
1854+
if !FolderExist(workspace) {
1855+
MakeDir(workspace)
1856+
}
1857+
mdata["workspace"] = workspace
1858+
1859+
//extract layers
1860+
base := fmt.Sprintf("%s/.base", rootdir)
1861+
if !FolderExist(base) {
1862+
MakeDir(base)
1863+
}
1864+
mdata["base"] = base
1865+
1866+
for _, k := range layer_order {
1867+
k = path.Base(k)
1868+
tar_path := fmt.Sprintf("%s/%s", image_dir, k)
1869+
layerfolder := fmt.Sprintf("%s/%s", mdata["base"], k)
1870+
if !FolderExist(layerfolder) {
1871+
MakeDir(layerfolder)
1872+
}
1873+
1874+
err := Untar(tar_path, layerfolder)
1875+
if err != nil {
1876+
return err
1877+
}
1878+
}
1879+
1880+
//download setting from github
1881+
rdir, _ := mdata["rootdir"].(string)
1882+
1883+
yaml := fmt.Sprintf("%s/distro.management.yml", sysdir)
1884+
err = DownloadFilefromGithubPlus(tname, ttag, "setting.yml", SETTING_URL, rdir, yaml)
1885+
if err != nil {
1886+
LOGGER.WithFields(logrus.Fields{
1887+
"err": err,
1888+
"toPath": rdir,
1889+
}).Error("Download setting from github failure and could not rollback to default one")
1890+
return err
1891+
}
1892+
1893+
//add map to this image
1894+
doc.Images[name] = mdata
1895+
1896+
ddata, _ := StructMarshal(doc)
1897+
err = WriteToFile(ddata, fmt.Sprintf("%s/.info", doc.RootDir))
1898+
if err != nil {
1899+
return err
1900+
}
1901+
}
1902+
return nil
1903+
}
1904+
17541905
func DockerLoad(file string) *Error {
17551906
currdir, err := GetConfigDir()
17561907
if err != nil {
@@ -1767,8 +1918,13 @@ func DockerLoad(file string) *Error {
17671918
}()
17681919

17691920
//check if file exists
1770-
if !FileExist(file) {
1771-
cerr := ErrNew(ErrNExist, fmt.Sprintf("%s does exist", file))
1921+
afile, ferr := filepath.Abs(file)
1922+
if ferr != nil {
1923+
cerr := ErrNew(ferr, fmt.Sprintf("could not parse to the absolute path: %s", file))
1924+
return cerr
1925+
}
1926+
if !FileExist(afile) {
1927+
cerr := ErrNew(ErrNExist, fmt.Sprintf("%s does exist", afile))
17721928
return cerr
17731929
}
17741930

@@ -1795,7 +1951,7 @@ func DockerLoad(file string) *Error {
17951951
}
17961952

17971953
//untar tar ball
1798-
uerr := Untar(file, tmpdir)
1954+
uerr := Untar(afile, tmpdir)
17991955
if uerr != nil {
18001956
return uerr
18011957
}

docker/docker.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,20 @@ type DockerSaveInfo struct {
3838
Layers []string //layers included inside this image, from lower to higher layers
3939
}
4040

41+
//Skopeo manifest item structure
42+
type SkopeoManifestItem struct {
43+
MediaType string `json:"mediaType"`
44+
Size uint `json:"size"`
45+
Digest string `json:"digest"`
46+
}
47+
//Skopeo manifest structure
48+
type SkopeoManifest struct {
49+
SchemaVersion int `json:"schemaVersion"`
50+
MediaType string `json:"mediaType"`
51+
Config SkopeoManifestItem `json:"config"`
52+
Layers []SkopeoManifestItem `json:"layers"`
53+
}
54+
4155
func ListRepositories(username string, pass string) ([]string, *Error) {
4256
log.SetOutput(ioutil.Discard)
4357
hub, err := registry.New(DOCKER_URL, username, pass)
@@ -342,6 +356,47 @@ func DeleteManifest(username string, pass string, name string, tag string) *Erro
342356
return nil
343357
}
344358

359+
func LoadSkopeoTar(dir, imagedir string) (map[string]int64, []string, *Error) {
360+
if !FolderExist(dir) {
361+
cerr := ErrNew(ErrNExist, fmt.Sprintf("%s does not exist", dir))
362+
return nil, nil, cerr
363+
}
364+
365+
var info SkopeoManifest
366+
manifest_file := fmt.Sprintf("%s/manifest.json", dir)
367+
b, berr := ioutil.ReadFile(manifest_file)
368+
if berr != nil {
369+
cerr := ErrNew(berr, fmt.Sprintf("could not read file: %s", manifest_file))
370+
return nil, nil, cerr
371+
}
372+
373+
jerr := json.Unmarshal(b, &info)
374+
if jerr != nil {
375+
cerr := ErrNew(jerr, "could not unmarshal json bytes to objects")
376+
return nil, nil, cerr
377+
}
378+
379+
layer_data := make(map[string]int64)
380+
var layers []string
381+
for _, item := range info.Layers {
382+
shavalue := strings.Split(item.Digest, ":")[1]
383+
layer_path := fmt.Sprintf("%s/%s", dir, shavalue)
384+
target_path := fmt.Sprintf("%s/%s.tar.gz", imagedir, shavalue)
385+
_, rerr := CopyFile(layer_path, target_path)
386+
if rerr != nil {
387+
return nil, nil, rerr
388+
}
389+
file_length, ferr := GetFileLength(target_path)
390+
if ferr != nil {
391+
return nil, nil, ferr
392+
}
393+
layer_data[target_path] = file_length
394+
layers = append(layers, target_path)
395+
}
396+
397+
return layer_data, layers, nil
398+
}
399+
345400
//dir is temp dir used for tarball extraction, image dir is used for the storage of image data
346401
func LoadDockerTar(dir, imagedir string) (string, map[string]int64, []string, *Error) {
347402
if !FolderExist(dir) {

main.go

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ var (
2020
)
2121

2222
const (
23-
VERSION = "alpha-1.7.2"
23+
VERSION = "alpha-1.8"
2424
)
2525

2626
func checkCompleteness() *Error {
@@ -672,12 +672,39 @@ func main() {
672672
},
673673
}
674674

675+
var SkopeoNameTag string
676+
var skopeoLoadCmd = &cobra.Command{
677+
Use: "skopeoload",
678+
Short: "load the skopeo directory",
679+
Long: "skopeoload sub-command is one advanced command of lpmx, which is used for importing 'skopeo copy' generated directory to system",
680+
Args: cobra.ExactArgs(1),
681+
PreRun: func(cmd *cobra.Command, args []string) {
682+
err := checkCompleteness()
683+
if err != nil {
684+
LOGGER.Fatal(err.Error())
685+
return
686+
}
687+
},
688+
Run: func(cmd *cobra.Command, args []string) {
689+
err := SkopeoLoad(SkopeoNameTag, args[0])
690+
if err != nil {
691+
LOGGER.Fatal(err.Error())
692+
return
693+
} else {
694+
LOGGER.Info("DONE")
695+
return
696+
}
697+
},
698+
}
699+
skopeoLoadCmd.Flags().StringVarP(&SkopeoNameTag, "nametag", "n", "", "required")
700+
skopeoLoadCmd.MarkFlagRequired("nametag")
701+
675702
var dockerCmd = &cobra.Command{
676703
Use: "docker",
677704
Short: "docker command",
678705
Long: "docker command is the advanced command of lpmx, which is used for executing docker related commands",
679706
}
680-
dockerCmd.AddCommand(dockerCreateCmd, dockerSearchCmd, dockerListCmd, dockerDeleteCmd, dockerDownloadCmd, dockerResetCmd, dockerPackageCmd, dockerAddCmd, dockerCommitCmd, dockerLoadCmd, dockerRunCmd, dockerMergeCmd)
707+
dockerCmd.AddCommand(dockerCreateCmd, dockerSearchCmd, dockerListCmd, dockerDeleteCmd, dockerDownloadCmd, dockerResetCmd, dockerPackageCmd, dockerAddCmd, dockerCommitCmd, dockerLoadCmd, dockerRunCmd, dockerMergeCmd, skopeoLoadCmd)
681708

682709
var SingularityLoadName string
683710
var SingularityLoadTag string

utils/utils.go

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -288,18 +288,8 @@ func RemoveFile(path string) (bool, *Error) {
288288

289289
func Rename(old_path string, new_path string) *Error {
290290
if t, terr := FileType(old_path); terr == nil {
291-
if t == TYPE_DIR {
292-
parent_dir := filepath.Dir(new_path)
293-
if !FolderExist(parent_dir) {
294-
err := os.MkdirAll(parent_dir, 0777)
295-
if err != nil {
296-
cerr := ErrNew(err, fmt.Sprintf("could not mkdir %s", parent_dir))
297-
return cerr
298-
}
299-
}
300-
}
301-
if t == TYPE_REGULAR {
302-
parent_dir := filepath.Dir(new_path)
291+
parent_dir := filepath.Dir(new_path)
292+
if t == TYPE_DIR || t == TYPE_REGULAR {
303293
if !FolderExist(parent_dir) {
304294
err := os.MkdirAll(parent_dir, 0777)
305295
if err != nil {
@@ -411,6 +401,14 @@ func CopyFile(src string, dst string) (bool, *Error) {
411401
return false, cerr
412402
}
413403
defer in.Close()
404+
parent_dir := filepath.Dir(dst)
405+
if !FolderExist(parent_dir) {
406+
err := os.MkdirAll(parent_dir, 0777)
407+
if err != nil {
408+
cerr := ErrNew(err, fmt.Sprintf("could not mkdir %s", parent_dir))
409+
return false, cerr
410+
}
411+
}
414412
out, oerr := os.Create(dst)
415413
if oerr != nil {
416414
cerr := ErrNew(oerr, fmt.Sprintf("can't open file %s", dst))

0 commit comments

Comments
 (0)