[lxc-devel] [lxd/master] shared: move idmap/acl functions to a separate package
albertodonato on Github
lxc-bot at linuxcontainers.org
Fri Sep 8 11:07:53 UTC 2017
A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 375 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170908/b5bc1055/attachment.bin>
-------------- next part --------------
From 662161d239e152f017fa27a9fd6c03a5f9e44432 Mon Sep 17 00:00:00 2001
From: Alberto Donato <alberto.donato at canonical.com>
Date: Fri, 8 Sep 2017 12:00:38 +0200
Subject: [PATCH] shared: move idmap/acl functions to a separate package
Signed-off-by: Alberto Donato <alberto.donato at canonical.com>
---
fuidshift/main.go | 12 +--
lxd/container.go | 5 +-
lxd/container_lxc.go | 33 +++---
lxd/container_lxc_utils.go | 12 +--
lxd/main_activateifneeded.go | 3 +-
lxd/main_init.go | 3 +-
lxd/migrate.go | 21 ++--
lxd/storage.go | 9 +-
lxd/storage_btrfs.go | 3 +-
lxd/storage_ceph_migration.go | 3 +-
lxd/storage_dir.go | 3 +-
lxd/storage_lvm.go | 3 +-
lxd/storage_migration.go | 3 +-
lxd/storage_mock.go | 4 +-
lxd/storage_zfs.go | 3 +-
lxd/sys/os.go | 3 +-
lxd/util/sys.go | 8 +-
shared/{ => idmap}/idmapset_linux.go | 18 ++--
shared/{ => idmap}/idmapset_linux_test.go | 2 +-
shared/idmap/shift_linux.go | 170 ++++++++++++++++++++++++++++++
shared/util_linux.go | 145 +------------------------
21 files changed, 254 insertions(+), 212 deletions(-)
rename shared/{ => idmap}/idmapset_linux.go (97%)
rename shared/{ => idmap}/idmapset_linux_test.go (99%)
create mode 100644 shared/idmap/shift_linux.go
diff --git a/fuidshift/main.go b/fuidshift/main.go
index 63eb2ffb1..a9fa1382a 100644
--- a/fuidshift/main.go
+++ b/fuidshift/main.go
@@ -4,7 +4,7 @@ import (
"fmt"
"os"
- "github.com/lxc/lxd/shared"
+ "github.com/lxc/lxd/shared/idmap"
)
func help(me string, status int) {
@@ -35,7 +35,7 @@ func run() error {
}
directory := os.Args[1]
- idmap := shared.IdmapSet{}
+ idmapSet := idmap.IdmapSet{}
testmode := false
reverse := false
@@ -48,14 +48,14 @@ func run() error {
testmode = true
default:
var err error
- idmap, err = idmap.Append(os.Args[pos])
+ idmapSet, err = idmapSet.Append(os.Args[pos])
if err != nil {
return err
}
}
}
- if idmap.Len() == 0 {
+ if idmapSet.Len() == 0 {
fmt.Printf("No idmaps given\n")
help(os.Args[0], 1)
}
@@ -66,7 +66,7 @@ func run() error {
}
if reverse {
- return idmap.UidshiftFromContainer(directory, testmode)
+ return idmapSet.UidshiftFromContainer(directory, testmode)
}
- return idmap.UidshiftIntoContainer(directory, testmode)
+ return idmapSet.UidshiftIntoContainer(directory, testmode)
}
diff --git a/lxd/container.go b/lxd/container.go
index 1be7f95a1..bde60418a 100644
--- a/lxd/container.go
+++ b/lxd/container.go
@@ -18,6 +18,7 @@ import (
"github.com/lxc/lxd/lxd/types"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/osarch"
)
@@ -494,8 +495,8 @@ type container interface {
StorageStart() (bool, error)
StorageStop() (bool, error)
Storage() storage
- IdmapSet() (*shared.IdmapSet, error)
- LastIdmapSet() (*shared.IdmapSet, error)
+ IdmapSet() (*idmap.IdmapSet, error)
+ LastIdmapSet() (*idmap.IdmapSet, error)
TemplateApply(trigger string) error
StateObject() *state.State
}
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index d2628583c..eba02ad72 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -30,6 +30,7 @@ import (
"github.com/lxc/lxd/lxd/util"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/logger"
"github.com/lxc/lxd/shared/osarch"
@@ -331,7 +332,7 @@ func containerLXCCreate(s *state.State, args db.ContainerArgs) (container, error
c.storage = cStorage
// Setup initial idmap config
- var idmap *shared.IdmapSet
+ var idmap *idmap.IdmapSet
base := int64(0)
if !c.IsPrivileged() {
idmap, base, err = findIdmap(
@@ -457,7 +458,7 @@ type containerLXC struct {
// Cache
c *lxc.Container
state *state.State
- idmapset *shared.IdmapSet
+ idmapset *idmap.IdmapSet
// Storage
storage storage
@@ -544,7 +545,7 @@ func idmapSize(state *state.State, isolatedStr string, size string) (int64, erro
var idmapLock sync.Mutex
-func parseRawIdmap(value string) ([]shared.IdmapEntry, error) {
+func parseRawIdmap(value string) ([]idmap.IdmapEntry, error) {
getRange := func(r string) (int64, int64, error) {
entries := strings.Split(r, "-")
if len(entries) > 2 {
@@ -570,7 +571,7 @@ func parseRawIdmap(value string) ([]shared.IdmapEntry, error) {
return base, size, nil
}
- ret := shared.IdmapSet{}
+ ret := idmap.IdmapSet{}
for _, line := range strings.Split(value, "\n") {
if line == "" {
@@ -596,7 +597,7 @@ func parseRawIdmap(value string) ([]shared.IdmapEntry, error) {
return nil, fmt.Errorf("idmap ranges of different sizes %s", line)
}
- entry := shared.IdmapEntry{
+ entry := idmap.IdmapEntry{
Hostid: outsideBase,
Nsid: insideBase,
Maprange: insideSize,
@@ -630,7 +631,7 @@ func parseRawIdmap(value string) ([]shared.IdmapEntry, error) {
return ret.Idmap, nil
}
-func findIdmap(state *state.State, cName string, isolatedStr string, configBase string, configSize string, rawIdmap string) (*shared.IdmapSet, int64, error) {
+func findIdmap(state *state.State, cName string, isolatedStr string, configBase string, configSize string, rawIdmap string) (*idmap.IdmapSet, int64, error) {
isolated := false
if shared.IsTrue(isolatedStr) {
isolated = true
@@ -642,7 +643,7 @@ func findIdmap(state *state.State, cName string, isolatedStr string, configBase
}
if !isolated {
- newIdmapset := shared.IdmapSet{Idmap: make([]shared.IdmapEntry, len(state.OS.IdmapSet.Idmap))}
+ newIdmapset := idmap.IdmapSet{Idmap: make([]idmap.IdmapEntry, len(state.OS.IdmapSet.Idmap))}
copy(newIdmapset.Idmap, state.OS.IdmapSet.Idmap)
for _, ent := range rawMaps {
@@ -657,8 +658,8 @@ func findIdmap(state *state.State, cName string, isolatedStr string, configBase
return nil, 0, err
}
- mkIdmap := func(offset int64, size int64) *shared.IdmapSet {
- set := &shared.IdmapSet{Idmap: []shared.IdmapEntry{
+ mkIdmap := func(offset int64, size int64) *idmap.IdmapSet {
+ set := &idmap.IdmapSet{Idmap: []idmap.IdmapEntry{
{Isuid: true, Nsid: 0, Hostid: offset, Maprange: size},
{Isgid: true, Nsid: 0, Hostid: offset, Maprange: size},
}}
@@ -689,7 +690,7 @@ func findIdmap(state *state.State, cName string, isolatedStr string, configBase
offset := state.OS.IdmapSet.Idmap[0].Hostid + 65536
- mapentries := shared.ByHostid{}
+ mapentries := idmap.ByHostid{}
for _, name := range cs {
/* Don't change our map Just Because. */
if name == cName {
@@ -722,7 +723,7 @@ func findIdmap(state *state.State, cName string, isolatedStr string, configBase
return nil, 0, err
}
- mapentries = append(mapentries, &shared.IdmapEntry{Hostid: int64(cBase), Maprange: cSize})
+ mapentries = append(mapentries, &idmap.IdmapEntry{Hostid: int64(cBase), Maprange: cSize})
}
sort.Sort(mapentries)
@@ -3368,7 +3369,7 @@ func (c *containerLXC) Update(args db.ContainerArgs, userRequested bool) error {
}
if shared.StringInSlice("security.idmap.isolated", changedConfig) || shared.StringInSlice("security.idmap.base", changedConfig) || shared.StringInSlice("security.idmap.size", changedConfig) || shared.StringInSlice("raw.idmap", changedConfig) || shared.StringInSlice("security.privileged", changedConfig) {
- var idmap *shared.IdmapSet
+ var idmap *idmap.IdmapSet
base := int64(0)
if !c.IsPrivileged() {
// update the idmap
@@ -6859,7 +6860,7 @@ func (c *containerLXC) Id() int {
return c.id
}
-func (c *containerLXC) IdmapSet() (*shared.IdmapSet, error) {
+func (c *containerLXC) IdmapSet() (*idmap.IdmapSet, error) {
var err error
if c.idmapset != nil {
@@ -6896,7 +6897,7 @@ func (c *containerLXC) LocalDevices() types.Devices {
return c.localDevices
}
-func (c *containerLXC) idmapsetFromConfig(k string) (*shared.IdmapSet, error) {
+func (c *containerLXC) idmapsetFromConfig(k string) (*idmap.IdmapSet, error) {
lastJsonIdmap := c.LocalConfig()[k]
if lastJsonIdmap == "" {
@@ -6906,7 +6907,7 @@ func (c *containerLXC) idmapsetFromConfig(k string) (*shared.IdmapSet, error) {
return idmapsetFromString(lastJsonIdmap)
}
-func (c *containerLXC) NextIdmapSet() (*shared.IdmapSet, error) {
+func (c *containerLXC) NextIdmapSet() (*idmap.IdmapSet, error) {
if c.localConfig["volatile.idmap.next"] != "" {
return c.idmapsetFromConfig("volatile.idmap.next")
} else if c.IsPrivileged() {
@@ -6918,7 +6919,7 @@ func (c *containerLXC) NextIdmapSet() (*shared.IdmapSet, error) {
return nil, fmt.Errorf("Unable to determine the idmap")
}
-func (c *containerLXC) LastIdmapSet() (*shared.IdmapSet, error) {
+func (c *containerLXC) LastIdmapSet() (*idmap.IdmapSet, error) {
return c.idmapsetFromConfig("volatile.last_state.idmap")
}
diff --git a/lxd/container_lxc_utils.go b/lxd/container_lxc_utils.go
index e4c288fc2..9da660f39 100644
--- a/lxd/container_lxc_utils.go
+++ b/lxd/container_lxc_utils.go
@@ -3,12 +3,12 @@ package main
import (
"encoding/json"
- "github.com/lxc/lxd/shared"
+ "github.com/lxc/lxd/shared/idmap"
)
-func idmapsetFromString(idmap string) (*shared.IdmapSet, error) {
- lastIdmap := new(shared.IdmapSet)
- err := json.Unmarshal([]byte(idmap), &lastIdmap.Idmap)
+func idmapsetFromString(idmapString string) (*idmap.IdmapSet, error) {
+ lastIdmap := new(idmap.IdmapSet)
+ err := json.Unmarshal([]byte(idmapString), &lastIdmap.Idmap)
if err != nil {
return nil, err
}
@@ -20,8 +20,8 @@ func idmapsetFromString(idmap string) (*shared.IdmapSet, error) {
return lastIdmap, nil
}
-func idmapsetToJSON(idmap *shared.IdmapSet) (string, error) {
- idmapBytes, err := json.Marshal(idmap.Idmap)
+func idmapsetToJSON(idmapSet *idmap.IdmapSet) (string, error) {
+ idmapBytes, err := json.Marshal(idmapSet.Idmap)
if err != nil {
return "", err
}
diff --git a/lxd/main_activateifneeded.go b/lxd/main_activateifneeded.go
index 592e04a30..0a277b07c 100644
--- a/lxd/main_activateifneeded.go
+++ b/lxd/main_activateifneeded.go
@@ -7,6 +7,7 @@ import (
"github.com/lxc/lxd/client"
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/shared"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/logger"
)
@@ -45,7 +46,7 @@ func cmdActivateIfNeeded(args *Args) error {
}
// Load the idmap for unprivileged containers
- d.os.IdmapSet, err = shared.DefaultIdmapSet()
+ d.os.IdmapSet, err = idmap.DefaultIdmapSet()
if err != nil {
return err
}
diff --git a/lxd/main_init.go b/lxd/main_init.go
index 009ea41f5..b09724fae 100644
--- a/lxd/main_init.go
+++ b/lxd/main_init.go
@@ -16,6 +16,7 @@ import (
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
"github.com/lxc/lxd/shared/cmd"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/logger"
)
@@ -810,7 +811,7 @@ func (cmd *CmdInit) askDefaultPrivileged() int {
// Detect lack of uid/gid
defaultPrivileged := -1
needPrivileged := false
- idmapset, err := shared.DefaultIdmapSet()
+ idmapset, err := idmap.DefaultIdmapSet()
if err != nil || len(idmapset.Idmap) == 0 || idmapset.Usable() != nil {
needPrivileged = true
}
diff --git a/lxd/migrate.go b/lxd/migrate.go
index 16bcc6fa3..59fa03faa 100644
--- a/lxd/migrate.go
+++ b/lxd/migrate.go
@@ -24,6 +24,7 @@ import (
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/logger"
)
@@ -854,16 +855,16 @@ func (c *migrationSink) Do(migrateOp *operation) error {
restore := make(chan error)
go func(c *migrationSink) {
imagesDir := ""
- srcIdmap := new(shared.IdmapSet)
-
- for _, idmap := range header.Idmap {
- e := shared.IdmapEntry{
- Isuid: *idmap.Isuid,
- Isgid: *idmap.Isgid,
- Nsid: int64(*idmap.Nsid),
- Hostid: int64(*idmap.Hostid),
- Maprange: int64(*idmap.Maprange)}
- srcIdmap.Idmap = shared.Extend(srcIdmap.Idmap, e)
+ srcIdmap := new(idmap.IdmapSet)
+
+ for _, idmapSet := range header.Idmap {
+ e := idmap.IdmapEntry{
+ Isuid: *idmapSet.Isuid,
+ Isgid: *idmapSet.Isgid,
+ Nsid: int64(*idmapSet.Nsid),
+ Hostid: int64(*idmapSet.Hostid),
+ Maprange: int64(*idmapSet.Maprange)}
+ srcIdmap.Idmap = idmap.Extend(srcIdmap.Idmap, e)
}
/* We do the fs receive in parallel so we don't have to reason
diff --git a/lxd/storage.go b/lxd/storage.go
index ddc680c20..355553261 100644
--- a/lxd/storage.go
+++ b/lxd/storage.go
@@ -15,6 +15,7 @@ import (
"github.com/lxc/lxd/lxd/state"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/ioprogress"
"github.com/lxc/lxd/shared/logger"
)
@@ -220,7 +221,7 @@ type storage interface {
c container,
objects []*Snapshot,
conn *websocket.Conn,
- srcIdmap *shared.IdmapSet,
+ srcIdmap *idmap.IdmapSet,
op *operation,
containerOnly bool) error
}
@@ -392,7 +393,7 @@ func storagePoolVolumeAttachInit(s *state.State, poolName string, volumeName str
poolVolumePut := st.GetStoragePoolVolumeWritable()
// get last idmapset
- var lastIdmap *shared.IdmapSet
+ var lastIdmap *idmap.IdmapSet
if poolVolumePut.Config["volatile.idmap.last"] != "" {
lastIdmap, err = idmapsetFromString(poolVolumePut.Config["volatile.idmap.last"])
if err != nil {
@@ -709,14 +710,14 @@ func deleteSnapshotMountpoint(snapshotMountpoint string, snapshotsSymlinkTarget
// ShiftIfNecessary sets the volatile.last_state.idmap key to the idmap last
// used by the container.
-func ShiftIfNecessary(container container, srcIdmap *shared.IdmapSet) error {
+func ShiftIfNecessary(container container, srcIdmap *idmap.IdmapSet) error {
dstIdmap, err := container.IdmapSet()
if err != nil {
return err
}
if dstIdmap == nil {
- dstIdmap = new(shared.IdmapSet)
+ dstIdmap = new(idmap.IdmapSet)
}
if !reflect.DeepEqual(srcIdmap, dstIdmap) {
diff --git a/lxd/storage_btrfs.go b/lxd/storage_btrfs.go
index 8c46f174d..0b58dd135 100644
--- a/lxd/storage_btrfs.go
+++ b/lxd/storage_btrfs.go
@@ -19,6 +19,7 @@ import (
"github.com/lxc/lxd/lxd/util"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/logger"
)
@@ -1938,7 +1939,7 @@ func (s *storageBtrfs) MigrationSource(c container, containerOnly bool) (Migrati
return driver, nil
}
-func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation, containerOnly bool) error {
+func (s *storageBtrfs) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool) error {
if runningInUserns {
return rsyncMigrationSink(live, container, snapshots, conn, srcIdmap, op, containerOnly)
}
diff --git a/lxd/storage_ceph_migration.go b/lxd/storage_ceph_migration.go
index f42b706a1..24179fd6e 100644
--- a/lxd/storage_ceph_migration.go
+++ b/lxd/storage_ceph_migration.go
@@ -9,6 +9,7 @@ import (
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/shared"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/logger"
)
@@ -191,7 +192,7 @@ func (s *storageCeph) MigrationSource(c container, containerOnly bool) (Migratio
return &driver, nil
}
-func (s *storageCeph) MigrationSink(live bool, c container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation, containerOnly bool) error {
+func (s *storageCeph) MigrationSink(live bool, c container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool) error {
// Check that we received a valid root disk device with a pool property
// set.
parentStoragePool := ""
diff --git a/lxd/storage_dir.go b/lxd/storage_dir.go
index 681cbfb31..acdbca417 100644
--- a/lxd/storage_dir.go
+++ b/lxd/storage_dir.go
@@ -12,6 +12,7 @@ import (
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/logger"
)
@@ -910,7 +911,7 @@ func (s *storageDir) MigrationSource(container container, containerOnly bool) (M
return rsyncMigrationSource(container, containerOnly)
}
-func (s *storageDir) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation, containerOnly bool) error {
+func (s *storageDir) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool) error {
return rsyncMigrationSink(live, container, snapshots, conn, srcIdmap, op, containerOnly)
}
diff --git a/lxd/storage_lvm.go b/lxd/storage_lvm.go
index ce0107c7b..ece80e331 100644
--- a/lxd/storage_lvm.go
+++ b/lxd/storage_lvm.go
@@ -11,6 +11,7 @@ import (
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/logger"
)
@@ -1651,7 +1652,7 @@ func (s *storageLvm) MigrationSource(container container, containerOnly bool) (M
return rsyncMigrationSource(container, containerOnly)
}
-func (s *storageLvm) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation, containerOnly bool) error {
+func (s *storageLvm) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool) error {
return rsyncMigrationSink(live, container, snapshots, conn, srcIdmap, op, containerOnly)
}
diff --git a/lxd/storage_migration.go b/lxd/storage_migration.go
index 80dfb2c14..faf7c4f02 100644
--- a/lxd/storage_migration.go
+++ b/lxd/storage_migration.go
@@ -8,6 +8,7 @@ import (
"github.com/lxc/lxd/lxd/db"
"github.com/lxc/lxd/lxd/types"
"github.com/lxc/lxd/shared"
+ "github.com/lxc/lxd/shared/idmap"
)
// MigrationStorageSourceDriver defines the functions needed to implement a
@@ -122,7 +123,7 @@ func snapshotProtobufToContainerArgs(containerName string, snap *Snapshot) db.Co
}
}
-func rsyncMigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation, containerOnly bool) error {
+func rsyncMigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool) error {
ourStart, err := container.StorageStart()
if err != nil {
return err
diff --git a/lxd/storage_mock.go b/lxd/storage_mock.go
index b8b7e9656..03b390824 100644
--- a/lxd/storage_mock.go
+++ b/lxd/storage_mock.go
@@ -5,8 +5,8 @@ import (
"github.com/gorilla/websocket"
- "github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/logger"
)
@@ -211,7 +211,7 @@ func (s *storageMock) PreservesInodes() bool {
func (s *storageMock) MigrationSource(container container, containerOnly bool) (MigrationStorageSourceDriver, error) {
return nil, fmt.Errorf("not implemented")
}
-func (s *storageMock) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation, containerOnly bool) error {
+func (s *storageMock) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool) error {
return nil
}
diff --git a/lxd/storage_zfs.go b/lxd/storage_zfs.go
index d2e85cb1e..594d0f2ad 100644
--- a/lxd/storage_zfs.go
+++ b/lxd/storage_zfs.go
@@ -17,6 +17,7 @@ import (
"github.com/lxc/lxd/lxd/util"
"github.com/lxc/lxd/shared"
"github.com/lxc/lxd/shared/api"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/logger"
"github.com/pborman/uuid"
@@ -2114,7 +2115,7 @@ func (s *storageZfs) MigrationSource(ct container, containerOnly bool) (Migratio
return &driver, nil
}
-func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *shared.IdmapSet, op *operation, containerOnly bool) error {
+func (s *storageZfs) MigrationSink(live bool, container container, snapshots []*Snapshot, conn *websocket.Conn, srcIdmap *idmap.IdmapSet, op *operation, containerOnly bool) error {
poolName := s.getOnDiskPoolName()
zfsRecv := func(zfsName string, writeWrapper func(io.WriteCloser) io.WriteCloser) error {
zfsFsName := fmt.Sprintf("%s/%s", poolName, zfsName)
diff --git a/lxd/sys/os.go b/lxd/sys/os.go
index d699ad878..420b6e277 100644
--- a/lxd/sys/os.go
+++ b/lxd/sys/os.go
@@ -5,6 +5,7 @@ import (
"github.com/lxc/lxd/lxd/util"
"github.com/lxc/lxd/shared"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/logger"
)
@@ -16,7 +17,7 @@ type OS struct {
Architectures []int // Cache of detected system architectures
LxcPath string // Path to the $LXD_DIR/containers directory
BackingFS string // Backing filesystem of $LXD_DIR/containers
- IdmapSet *shared.IdmapSet
+ IdmapSet *idmap.IdmapSet
MockMode bool // If true some APIs will be mocked (for testing)
}
diff --git a/lxd/util/sys.go b/lxd/util/sys.go
index 005a8554a..fa46a5f2b 100644
--- a/lxd/util/sys.go
+++ b/lxd/util/sys.go
@@ -5,7 +5,7 @@ import (
log "gopkg.in/inconshreveable/log15.v2"
- "github.com/lxc/lxd/shared"
+ "github.com/lxc/lxd/shared/idmap"
"github.com/lxc/lxd/shared/logger"
"github.com/lxc/lxd/shared/osarch"
)
@@ -36,14 +36,14 @@ func GetArchitectures() ([]int, error) {
}
// GetIdmapSet reads the uid/gid allocation.
-func GetIdmapSet() *shared.IdmapSet {
- idmapSet, err := shared.DefaultIdmapSet()
+func GetIdmapSet() *idmap.IdmapSet {
+ idmapSet, err := idmap.DefaultIdmapSet()
if err != nil {
logger.Warn("Error reading default uid/gid map", log.Ctx{"err": err.Error()})
logger.Warnf("Only privileged containers will be able to run")
idmapSet = nil
} else {
- kernelIdmapSet, err := shared.CurrentIdmapSet()
+ kernelIdmapSet, err := idmap.CurrentIdmapSet()
if err == nil {
logger.Infof("Kernel uid/gid map:")
for _, lxcmap := range kernelIdmapSet.ToLxcString() {
diff --git a/shared/idmapset_linux.go b/shared/idmap/idmapset_linux.go
similarity index 97%
rename from shared/idmapset_linux.go
rename to shared/idmap/idmapset_linux.go
index da1c59e7e..aa9241c1e 100644
--- a/shared/idmapset_linux.go
+++ b/shared/idmap/idmapset_linux.go
@@ -1,4 +1,4 @@
-package shared
+package idmap
import (
"bufio"
@@ -11,6 +11,8 @@ import (
"sort"
"strconv"
"strings"
+
+ "github.com/lxc/lxd/shared"
)
type IdRange struct {
@@ -307,7 +309,7 @@ func (m IdmapSet) ValidRanges() ([]*IdRange, error) {
// Sort the map
idmap := IdmapSet{}
- err := DeepCopy(&m, &idmap)
+ err := shared.DeepCopy(&m, &idmap)
if err != nil {
return nil, err
}
@@ -397,7 +399,7 @@ func (m IdmapSet) ToLxcString() []string {
var lines []string
for _, e := range m.Idmap {
for _, l := range e.ToLxcString() {
- if !StringInSlice(l+"\n", lines) {
+ if !shared.StringInSlice(l+"\n", lines) {
lines = append(lines, l+"\n")
}
}
@@ -478,7 +480,7 @@ func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how stri
return err
}
- intUid, intGid, _, _, _, _, err := GetFileStat(path)
+ intUid, intGid, _, _, _, _, err := shared.GetFileStat(path)
if err != nil {
return err
}
@@ -510,7 +512,7 @@ func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how stri
return nil
}
- if !PathExists(dir) {
+ if !shared.PathExists(dir) {
return fmt.Errorf("No such file or directory: %q", dir)
}
@@ -650,7 +652,7 @@ func DefaultIdmapSet() (*IdmapSet, error) {
// Check if shadow's uidmap tools are installed
newuidmap, _ := exec.LookPath("newuidmap")
newgidmap, _ := exec.LookPath("newgidmap")
- if newuidmap != "" && newgidmap != "" && PathExists("/etc/subuid") && PathExists("/etc/subgid") {
+ if newuidmap != "" && newgidmap != "" && shared.PathExists("/etc/subuid") && shared.PathExists("/etc/subgid") {
// Parse the shadow uidmap
entries, err := getFromShadow("/etc/subuid", "root")
if err != nil {
@@ -788,7 +790,7 @@ func DefaultIdmapSet() (*IdmapSet, error) {
func CurrentIdmapSet() (*IdmapSet, error) {
idmapset := new(IdmapSet)
- if PathExists("/proc/self/uid_map") {
+ if shared.PathExists("/proc/self/uid_map") {
// Parse the uidmap
entries, err := getFromProc("/proc/self/uid_map")
if err != nil {
@@ -805,7 +807,7 @@ func CurrentIdmapSet() (*IdmapSet, error) {
idmapset.Idmap = Extend(idmapset.Idmap, e)
}
- if PathExists("/proc/self/gid_map") {
+ if shared.PathExists("/proc/self/gid_map") {
// Parse the gidmap
entries, err := getFromProc("/proc/self/gid_map")
if err != nil {
diff --git a/shared/idmapset_linux_test.go b/shared/idmap/idmapset_linux_test.go
similarity index 99%
rename from shared/idmapset_linux_test.go
rename to shared/idmap/idmapset_linux_test.go
index d8582c8d9..9fe466caa 100644
--- a/shared/idmapset_linux_test.go
+++ b/shared/idmap/idmapset_linux_test.go
@@ -1,4 +1,4 @@
-package shared
+package idmap
import (
"fmt"
diff --git a/shared/idmap/shift_linux.go b/shared/idmap/shift_linux.go
new file mode 100644
index 000000000..b470da4fb
--- /dev/null
+++ b/shared/idmap/shift_linux.go
@@ -0,0 +1,170 @@
+// +build linux
+// +build cgo
+
+package idmap
+
+import (
+ "fmt"
+ "os"
+ "unsafe"
+)
+
+// #cgo LDFLAGS: -lacl
+/*
+#define _GNU_SOURCE
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/acl.h>
+
+int shiftowner(char *basepath, char *path, int uid, int gid) {
+ struct stat sb;
+ int fd, r;
+ char fdpath[PATH_MAX];
+ char realpath[PATH_MAX];
+
+ fd = open(path, O_PATH|O_NOFOLLOW);
+ if (fd < 0 ) {
+ perror("Failed open");
+ return 1;
+ }
+
+ r = sprintf(fdpath, "/proc/self/fd/%d", fd);
+ if (r < 0) {
+ perror("Failed sprintf");
+ close(fd);
+ return 1;
+ }
+
+ r = readlink(fdpath, realpath, PATH_MAX);
+ if (r < 0) {
+ perror("Failed readlink");
+ close(fd);
+ return 1;
+ }
+
+ if (strlen(realpath) < strlen(basepath)) {
+ printf("Invalid path, source (%s) is outside of basepath (%s).\n", realpath, basepath);
+ close(fd);
+ return 1;
+ }
+
+ if (strncmp(realpath, basepath, strlen(basepath))) {
+ printf("Invalid path, source (%s) is outside of basepath (%s).\n", realpath, basepath);
+ close(fd);
+ return 1;
+ }
+
+ r = fstat(fd, &sb);
+ if (r < 0) {
+ perror("Failed fstat");
+ close(fd);
+ return 1;
+ }
+
+ r = fchownat(fd, "", uid, gid, AT_EMPTY_PATH|AT_SYMLINK_NOFOLLOW);
+ if (r < 0) {
+ perror("Failed chown");
+ close(fd);
+ return 1;
+ }
+
+ if (!S_ISLNK(sb.st_mode)) {
+ r = chmod(fdpath, sb.st_mode);
+ if (r < 0) {
+ perror("Failed chmod");
+ close(fd);
+ return 1;
+ }
+ }
+
+ close(fd);
+ return 0;
+}
+*/
+import "C"
+
+// ShiftOwner updates uid and gid for a file when entering/exiting a namespace
+func ShiftOwner(basepath string, path string, uid int, gid int) error {
+ cbasepath := C.CString(basepath)
+ defer C.free(unsafe.Pointer(cbasepath))
+
+ cpath := C.CString(path)
+ defer C.free(unsafe.Pointer(cpath))
+
+ r := C.shiftowner(cbasepath, cpath, C.int(uid), C.int(gid))
+ if r != 0 {
+ return fmt.Errorf("Failed to change ownership of: %s", path)
+ }
+ return nil
+}
+
+// ShiftACL updates uid and gid for file ACLs when entering/exiting a namespace
+func ShiftACL(path string, shiftIds func(uid int64, gid int64) (int64, int64)) error {
+ finfo, err := os.Lstat(path)
+ if err != nil {
+ return err
+ }
+ if finfo.Mode()&os.ModeSymlink != 0 {
+ return nil
+ }
+
+ cpath := C.CString(path)
+ defer C.free(unsafe.Pointer(cpath))
+
+ acl := C.acl_get_file(cpath, C.ACL_TYPE_ACCESS)
+ if acl == nil {
+ return nil
+ }
+ defer C.acl_free(unsafe.Pointer(acl))
+
+ for entryId := C.ACL_FIRST_ENTRY; ; entryId = C.ACL_NEXT_ENTRY {
+ var ent C.acl_entry_t
+ var tag C.acl_tag_t
+ updateACL := false
+
+ ret := C.acl_get_entry(acl, C.int(entryId), &ent)
+ if ret != 1 {
+ break
+ }
+
+ ret = C.acl_get_tag_type(ent, &tag)
+ if ret == -1 {
+ return fmt.Errorf("Failed to change ACLs on %s", path)
+ }
+
+ idp := (*C.id_t)(C.acl_get_qualifier(ent))
+ if idp == nil {
+ continue
+ }
+
+ var newId int64
+ switch tag {
+ case C.ACL_USER:
+ newId, _ = shiftIds((int64)(*idp), -1)
+ updateACL = true
+
+ case C.ACL_GROUP:
+ _, newId = shiftIds(-1, (int64)(*idp))
+ updateACL = true
+ }
+
+ if updateACL {
+ ret = C.acl_set_qualifier(ent, unsafe.Pointer(&newId))
+ if ret == -1 {
+ return fmt.Errorf("Failed to change ACLs on %s", path)
+ }
+ ret = C.acl_set_file(cpath, C.ACL_TYPE_ACCESS, acl)
+ if ret == -1 {
+ return fmt.Errorf("Failed to change ACLs on %s", path)
+ }
+ }
+ }
+ return nil
+}
diff --git a/shared/util_linux.go b/shared/util_linux.go
index 26389c7ee..77daf1051 100644
--- a/shared/util_linux.go
+++ b/shared/util_linux.go
@@ -19,7 +19,7 @@ import (
"github.com/lxc/lxd/shared/logger"
)
-// #cgo LDFLAGS: -lutil -lpthread -lacl
+// #cgo LDFLAGS: -lutil -lpthread
/*
#define _GNU_SOURCE
#include <errno.h>
@@ -36,7 +36,6 @@ import (
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
-#include <sys/acl.h>
#ifndef AT_SYMLINK_FOLLOW
#define AT_SYMLINK_FOLLOW 0x400
@@ -129,71 +128,6 @@ void create_pipe(int *master, int *slave) {
*slave = pipefd[1];
}
-int shiftowner(char *basepath, char *path, int uid, int gid) {
- struct stat sb;
- int fd, r;
- char fdpath[PATH_MAX];
- char realpath[PATH_MAX];
-
- fd = open(path, O_PATH|O_NOFOLLOW);
- if (fd < 0 ) {
- perror("Failed open");
- return 1;
- }
-
- r = sprintf(fdpath, "/proc/self/fd/%d", fd);
- if (r < 0) {
- perror("Failed sprintf");
- close(fd);
- return 1;
- }
-
- r = readlink(fdpath, realpath, PATH_MAX);
- if (r < 0) {
- perror("Failed readlink");
- close(fd);
- return 1;
- }
-
- if (strlen(realpath) < strlen(basepath)) {
- printf("Invalid path, source (%s) is outside of basepath (%s).\n", realpath, basepath);
- close(fd);
- return 1;
- }
-
- if (strncmp(realpath, basepath, strlen(basepath))) {
- printf("Invalid path, source (%s) is outside of basepath (%s).\n", realpath, basepath);
- close(fd);
- return 1;
- }
-
- r = fstat(fd, &sb);
- if (r < 0) {
- perror("Failed fstat");
- close(fd);
- return 1;
- }
-
- r = fchownat(fd, "", uid, gid, AT_EMPTY_PATH|AT_SYMLINK_NOFOLLOW);
- if (r < 0) {
- perror("Failed chown");
- close(fd);
- return 1;
- }
-
- if (!S_ISLNK(sb.st_mode)) {
- r = chmod(fdpath, sb.st_mode);
- if (r < 0) {
- perror("Failed chmod");
- close(fd);
- return 1;
- }
- }
-
- close(fd);
- return 0;
-}
-
int get_poll_revents(int lfd, int timeout, int flags, int *revents, int *saved_errno)
{
int ret;
@@ -239,83 +173,6 @@ func GetPollRevents(fd int, timeout int, flags int) (int, int, error) {
return int(ret), int(revents), err
}
-func ShiftOwner(basepath string, path string, uid int, gid int) error {
- cbasepath := C.CString(basepath)
- defer C.free(unsafe.Pointer(cbasepath))
-
- cpath := C.CString(path)
- defer C.free(unsafe.Pointer(cpath))
-
- r := C.shiftowner(cbasepath, cpath, C.int(uid), C.int(gid))
- if r != 0 {
- return fmt.Errorf("Failed to change ownership of: %s", path)
- }
- return nil
-}
-
-func ShiftACL(path string, shiftIds func(uid int64, gid int64) (int64, int64)) error {
- finfo, err := os.Lstat(path)
- if err != nil {
- return err
- }
- if finfo.Mode()&os.ModeSymlink != 0 {
- return nil
- }
-
- cpath := C.CString(path)
- defer C.free(unsafe.Pointer(cpath))
-
- acl := C.acl_get_file(cpath, C.ACL_TYPE_ACCESS)
- if acl == nil {
- return nil
- }
- defer C.acl_free(unsafe.Pointer(acl))
-
- for entryId := C.ACL_FIRST_ENTRY; ; entryId = C.ACL_NEXT_ENTRY {
- var ent C.acl_entry_t
- var tag C.acl_tag_t
- updateACL := false
-
- ret := C.acl_get_entry(acl, C.int(entryId), &ent)
- if ret != 1 {
- break
- }
-
- ret = C.acl_get_tag_type(ent, &tag)
- if ret == -1 {
- return fmt.Errorf("Failed to change ACLs on %s", path)
- }
-
- idp := (*C.id_t)(C.acl_get_qualifier(ent))
- if idp == nil {
- continue
- }
-
- var newId int64
- switch tag {
- case C.ACL_USER:
- newId, _ = shiftIds((int64)(*idp), -1)
- updateACL = true
-
- case C.ACL_GROUP:
- _, newId = shiftIds(-1, (int64)(*idp))
- updateACL = true
- }
-
- if updateACL {
- ret = C.acl_set_qualifier(ent, unsafe.Pointer(&newId))
- if ret == -1 {
- return fmt.Errorf("Failed to change ACLs on %s", path)
- }
- ret = C.acl_set_file(cpath, C.ACL_TYPE_ACCESS, acl)
- if ret == -1 {
- return fmt.Errorf("Failed to change ACLs on %s", path)
- }
- }
- }
- return nil
-}
-
func OpenPty(uid, gid int64) (master *os.File, slave *os.File, err error) {
fd_master := C.int(-1)
fd_slave := C.int(-1)
More information about the lxc-devel
mailing list