diff --git a/files/package_pool.go b/files/package_pool.go index 0374a1d1..385ed050 100644 --- a/files/package_pool.go +++ b/files/package_pool.go @@ -3,6 +3,7 @@ package files import ( "fmt" "github.com/smira/aptly/aptly" + "io" "io/ioutil" "os" "path/filepath" @@ -102,3 +103,52 @@ func (pool *PackagePool) Remove(path string) (size int64, err error) { err = os.Remove(path) return info.Size(), err } + +// Import copies file into package pool +func (pool *PackagePool) Import(path string, hashMD5 string) error { + source, err := os.Open(path) + if err != nil { + return err + } + defer source.Close() + + sourceInfo, err := source.Stat() + if err != nil { + return err + } + + poolPath, err := pool.Path(path, hashMD5) + if err != nil { + return err + } + + targetInfo, err := os.Stat(poolPath) + if err != nil { + if !os.IsNotExist(err) { + // unable to stat target location? + return err + } + // file doesn't exist, that's ok + } else { + if targetInfo.Size() != sourceInfo.Size() { + // trying to overwrite file? + return fmt.Errorf("unable to import into pool: file %s already exists", poolPath) + } + } + + // create subdirs as necessary + err = os.MkdirAll(filepath.Dir(poolPath), 0755) + if err != nil { + return err + } + + target, err := os.Create(poolPath) + if err != nil { + return err + } + defer target.Close() + + _, err = io.Copy(target, source) + + return err +} diff --git a/files/package_pool_test.go b/files/package_pool_test.go index 3473f6b3..2fb1affb 100644 --- a/files/package_pool_test.go +++ b/files/package_pool_test.go @@ -5,6 +5,7 @@ import ( . "launchpad.net/gocheck" "os" "path/filepath" + "runtime" ) type PackagePoolSuite struct { @@ -84,3 +85,35 @@ func (s *PackagePoolSuite) TestRemove(c *C) { c.Check(err, IsNil) c.Check(list, DeepEquals, []string{"ae/0c/1.deb", "bd/0a/3.deb", "bd/0b/4.deb"}) } + +func (s *PackagePoolSuite) TestImportOk(c *C) { + _, __file__, _, _ := runtime.Caller(0) + debFile := filepath.Join(filepath.Dir(__file__), "../system/files/libboost-program-options-dev_1.49.0.1_i386.deb") + + err := s.pool.Import(debFile, "91b1a1480b90b9e269ca44d897b12575") + c.Check(err, IsNil) + + info, err := os.Stat(filepath.Join(s.pool.rootPath, "91", "b1", "libboost-program-options-dev_1.49.0.1_i386.deb")) + c.Check(err, IsNil) + c.Check(info.Size(), Equals, int64(2738)) + + // double import, should be ok + err = s.pool.Import(debFile, "91b1a1480b90b9e269ca44d897b12575") + c.Check(err, IsNil) +} + +func (s *PackagePoolSuite) TestImportNotExist(c *C) { + err := s.pool.Import("no-such-file", "91b1a1480b90b9e269ca44d897b12575") + c.Check(err, ErrorMatches, ".*no such file or directory") +} + +func (s *PackagePoolSuite) TestImportOverwrite(c *C) { + _, __file__, _, _ := runtime.Caller(0) + debFile := filepath.Join(filepath.Dir(__file__), "../system/files/libboost-program-options-dev_1.49.0.1_i386.deb") + + os.MkdirAll(filepath.Join(s.pool.rootPath, "91", "b1"), 0755) + ioutil.WriteFile(filepath.Join(s.pool.rootPath, "91", "b1", "libboost-program-options-dev_1.49.0.1_i386.deb"), []byte("1"), 0644) + + err := s.pool.Import(debFile, "91b1a1480b90b9e269ca44d897b12575") + c.Check(err, ErrorMatches, "unable to import into pool.*") +}